JAVA调整JMeunBar位置_面向对象的程序设计-Java

本文主要探讨了Java GUI设计中的JMenuBar位置调整,讲解了如何在面向对象的程序设计中创建和管理GUI组件,特别是如何处理事件以及响应用户输入。文章通过实例展示了如何创建基本的Swing应用程序,添加组件,设置布局管理器,以及注册事件监听器来响应用户操作。此外,还介绍了常见事件处理,如行为事件和键盘事件,并提供了响应用户输入的菜单系统设计和实现方法。
摘要由CSDN通过智能技术生成

《面向对象的程序设计-Java》由会员分享,可在线阅读,更多相关《面向对象的程序设计-Java(77页珍藏版)》请在人人文库网上搜索。

1、面向对象的程序设计Java,第六章 GUI设计和事件处理,6.1 概述 6.2 GUI设计 6.3 Java的事件处理模型 6.4 常见事件处理 6.5 响应用户输入 6.6 小结,6.1 概述,一、与用户的交互,6.1 概述,二、GUI的元素:Top-Level Containers,6.1 概述,二、GUI的元素:General-Purpose Containers,6.1 概述,二、GUI的元素:Special-Purpose Containers,6.1 概述,二、GUI的元素:Basic Controls,6.1 概述,二、GUI的元素:Uneditable Information 。

2、Displays,6.1 概述,二、GUI的元素:Editable Displays of Formatted Information,6.1 概述,事件是代表另一对象抽象状态下变化的对象。事件本身就是抽象。生成事件的过程是无法从对象外部直接观察的。,三、什么是事件?,本地事件是使用单一Java虚拟且运行于单一平台上的应用程序生成的事件。 分布事件就是由远程目标生成的事件,运行于不同的平台使用不同的JVM。,6.1 什么是事件,四、与GUI和事件处理有关的包,java.awt java.awt.event javax.swing(JFC1.1) javax.swing.event,推荐使用sw。

3、ing组件,6.2 GUI设计,一、容器与组件,6.2 GUI设计,容器是可以放置其他组件的组件,主要有 Panel、Frame和Window 容器是java.awt.Container的子类。 Swing组件都是抽象类 java.awt.Container.Jcomponent的子类。,6.2 GUI设计,二、Swing组件的类结构,6.2 GUI设计,JComponent的直接子类(JDK1.4),AbstractButton, BasicInternalFrameTitlePane, Box, Box.Filler, JColorChooser, JComboBox, JFileChoo。

4、ser, JInternalFrame, JInternalFrame.JDesktopIcon, JLabel, JLayeredPane, JList, JMenuBar, JOptionPane, JPanel, JPopupMenu, JProgressBar, JRootPane, JScrollBar, JScrollPane, JSeparator, JSlider, JSpinner, JSplitPane, JTabbedPane, JTable, JTableHeader, JTextComponent, JToolBar, JToolTip, JTree, JViewpo。

5、rt,6.2 GUI设计,三、创建主界面,要创建Swing应用程序,首先要创建一个表示图形用户界面的类,这个类的对象将被用作容器,用于放置要显示的其他组件。 大部分应用程序的主界面是一个简单窗口(Jwindow)或是一个框架窗口(JFrame)。,6.2 GUI设计,一个最简单的Swing应用程序,import javax.swing.*; public class HelloWorldSwing public static void main(String args) JFrame frame = new JFrame(HelloWorldSwing); final JLabel label。

6、 = new JLabel(Hello World); frame.getContentPane().add(label); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); ,6.2 GUI设计,四、创建并添加组件,创建组件其实就是生成一个满足外观要求的某个某个组件对象。 JLabel label = new JLabel(Hello World); JButton okButtonnew JButton(“Ok); 将组件加入到简单容器(JPanel)中,只。

7、要调用容器的add(Component)方法,参数是该组件。 对于大多数其他容器(框架、窗口、JApplet和对话框)则采用其他方法。,6.2 GUI设计,这些非简单容器实际上被划分为窗格(Pane),后者是一种容器中的容器。通常情况下组件被加入容器的内容窗格(ContentPane)中。 组件加入容器的内容窗格的步骤是: 1)创建一个面板。 2)使用面板的add(Component)方法将组件加入到面板中。 3)调用setContentPane(Container)方法,将面板作为参数,将面板加入到内容窗格中。,6.2 GUI设计,五、布局管理,Java通过布局管理器来排列组件。,6.2 G。

8、UI设计,布局管理器决定了组件被加入到容器中时被如何排列。 Java中布局管理器包括FlowLayout、GridLayout、BorderLayout、CardLayout和GridBagLayout类。 在将组件加入到容器之前,必须建立容器的布局管理器。FlowLayout flo=new FlowLayout(); 面板的缺省输出管理器是FlowLayout;框架和窗口的是BorderLayout。 创建完布局管理器后,需要用容器的setLayout()方法将它与容器关联。,6.2 GUI设计,1、FlowLayout,组件按照加入的先后顺序从从左到右排列,一行排满之后转到下一行继续从左。

9、到右排列。 要想让每一行中的组件向左、向右和居中排列,需要在构造时加参数:FlowLayout.LEFT、FlowLayout.RIGHT和 FlowLayout.CENTER。居中是其缺省排列。 构造函数FlowLayout(int, int, int)有三个参数分别表示对齐方式、组件水平间距和组件垂直间距。,6.2 GUI设计,2、GridLayout,组件按照加入的先后顺序从从左到右依次填满单元格,一行排满之后转到下一行继续。 构造函数有四个参数: GridLayout glo = new GridLayout(3,2,0,0) 分别是行单元格数、列单元格数、单元水平间距和单元垂直间距。。

10、,6.2 GUI设计,3、BorderLayout,容器分成北、南、东、西和中央五个区。 在加入组件时,需要指明加入到哪个区中。 add(West, new Button (西); add(Center,new Button(中);,6.2 GUI设计,4、GridBagLayout,GridBagLayout是功能最为强大的布局管理器。 它与GridLayout的区别在于: 组件可以占据网格中多个单元格; 不同行和列的比例不必相等; 单元格中的组件可以以不同的方式排列。,Swing界面要成为Java程序,必须能够处理用户事件。 Swing用一组称之为事件监听器(Event Listener)。

11、来处理事件。 如果没有委托(注册)监听器,事件将不被处理。,6.3 Java的事件处理模型,一、Java事件处理的委托模型,6.3 Java的事件处理模型,二、Java中,事件监听器是实现了相应接口的类。,ActionListener:行为事件 AdjustmentListener:调整事件 FocusListener:焦点事件 KeyListener:键盘事件 ItemListener:选项事件 MouseListener:鼠标事件 MouseMotionListener:鼠标移动事件 WindowListener:窗口事件,6.3 Java的事件处理模型,三、委托(注册)事件监听器,add。

12、ActionListener:JButton,JCheckBox,JCombobox,JTextfield和JRadioButton addAdjustmentListener:JScrollBar addFocusListener:所有的Swing组件 addKeyListener:所有的Swing组件 addItemListener:JCheckBox,JCombobox和JRadioButton addMouseListener:所有的Swing组件 addMouseMotionListener:所有的Swing组件 addWindowListener:所有的JWindow和JFrame。

13、组件,6.3 Java的事件处理模型,注意:将组件加入到容器之前,必须将监听器与组件关联起来,并完成相应其他配置工作,否则,程序运行时,这些设置将被忽略。,6.3 Java的事件处理模型,四、事件处理方法,实现监听器接口的类必须处理接口中所有的方法。 ActionListener:actionPerformed(ActionEvent) KeyListener:keyPressed(KeyEvent) keyReleased(KeyEvent) keyTyped(KeyEvent) MouseListener:mouseClicked(MouseEvent) mouseEntered(Mous。

14、eEvent) mouseExited(MouseEvent) mousePressed(MouseEvent) mouseReleased(MouseEvent) 为了方便,Java提供了相应接口的适配器(Adapter)。,6.3 Java的事件处理模型,五、Swing中处理各组件事件的一般步骤,1)新建一个组件(如JButton)。 2)将该组件添加到相应的面板(如JPanel)。 3)注册监听器以监听事件源产生的事件(如通过ActionListener来响应用户点击按钮)。 4)定义处理事件的方法(如在ActionListener中的actionPerformed中定义相应方法)。,6。

15、.3 Java的事件处理模型,六、例,import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Simple1 private static JFrame frame; / 定义为静态变量以便main使用 private static JPanel myPanel; / 该面板用来放置按钮组件 private JButton button1; / 这里定义按钮组件 private JButton button2; / 以便让ActionListener使用,6.3 Java的事件处理模型,pub。

16、lic Simple1() / 构造器, 建立图形界面 myPanel = new JPanel(); / 新建面板 button1 = new JButton(按钮1); / 新建按钮1 button2 = new JButton(按钮2); / 新建按钮1 SimpleListener ourListener = new SimpleListener(); / 建立一个actionlistener让两个按钮共享 button1.addActionListener(ourListener); button2.addActionListener(ourListener); myPanel.ad。

17、d(button1);/ 添加按钮到面板 myPanel.add(button2); ,6.3 Java的事件处理模型,private class SimpleListener implements ActionListener public void actionPerformed(ActionEvent e) / 利用getActionCommand获得按钮名称 / 也可以利用getSource()来实现 / if (e.getSource() =button1) String buttonName = e.getActionCommand(); if (buttonName.equals。

18、(按钮1) JOptionPane.showMessageDialog(frame, 按钮1 被点击); else if (buttonName.equals(按钮2) JOptionPane.showMessageDialog(frame, 按钮2 被点击); else JOptionPane.showMessageDialog(frame, Unknown event ); ,6.3 Java的事件处理模型,public static void main(String s) Simple1 gui = new Simple1(); / 新建Simple1组件 frame = new JFr。

19、ame(Simple1); / 新建JFrame / 处理关闭事件的通常方法 frame.addWindowListener(new WindowAdapter() public void windowClosing(WindowEvent e) System.exit(0); ); frame.getContentPane().add(myPanel); frame.pack(); frame.setVisible(true); ,6.3 Java的事件处理模型,程序运行结果:,6.4 常见事件处理,一、行为事件,接口:ActionListener 注册:addActionListener(。

20、ActionListener) 处理:actionPerformed(ActionEvent evt) 判断事件源:getSource()和getActionCommand() 判断是否同时按下其他键:getModifiers() 动作命令(action command)是与按钮、菜单等相关联的文本,如它们的标签。通过组件的setActionCommand(String)方法,可以设置不同的动作命令。多用于多个组件可激发同样事件时。,接口:KeyListener 注册:add KeyListener(KeyListener) 处理:keyPressed(KeyEvent) keyRelease。

21、d(KeyEvent) keyTyped(KeyEvent),6.4 常见事件处理,二、键盘事件,仅响应Unicode字符键,判断按下Unicode字符:键盘事件的getKeyChar()方法 判断按下虚拟键码:键盘事件的getKeyCode()方法 修改输入键码:setKeyChar(char)与setKeyCode(int),6.4 常见事件处理,import javax.swing.*; import java.awt.event.*; import java.awt.*; public class KeyEventDemo extends JApplet implements KeyL。

22、istener, ActionListener JTextArea displayArea; JTextField typingArea; static final String newline = n; public void init() JButton button = new JButton(Clear); button.addActionListener(this); typingArea = new JTextField(20); typingArea.addKeyListener(this);,6.4 常见事件处理,displayArea = new JTextArea(); d。

23、isplayArea.setEditable(false); JScrollPane scrollPane = new JScrollPane(displayArea); scrollPane.setPreferredSize(new Dimension(375, 125); JPanel contentPane = new JPanel(); contentPane.setLayout(new BorderLayout(); contentPane.add(typingArea, BorderLayout.NORTH); contentPane.add(scrollPane, BorderL。

24、ayout.CENTER); contentPane.add(button, BorderLayout.SOUTH); setContentPane(contentPane); ,6.4 常见事件处理,/* Handle the key typed event from the text field. */ public void keyTyped(KeyEvent e) displayInfo(e, KEY TYPED: ); /* Handle the key pressed event from the text field. */ public void keyPressed(KeyE。

25、vent e) displayInfo(e, KEY PRESSED: ); /* Handle the key released event from the text field. */ public void keyReleased(KeyEvent e) displayInfo(e, KEY RELEASED: ); ,6.4 常见事件处理,/* Handle the button click. */ public void actionPerformed(ActionEvent e) /Clear the text components. displayArea.setText();。

26、 typingArea.setText(); /Return the focus to the typing area. typingArea.requestFocus(); ,6.4 常见事件处理,protected void displayInfo(KeyEvent e, String s) String charString, keyCodeString, modString, tmpString; char c = e.getKeyChar(); int keyCode = e.getKeyCode(); int modifiers = e.getModifiers(); if (Ch。

27、aracter.isISOControl(c) charString = key character = + (an unprintable control character); else charString = key character = + c + ; keyCodeString = key code = + keyCode + ( + KeyEvent.getKeyText(keyCode) + );,6.4 常见事件处理,modString = modifiers = + modifiers; tmpString = KeyEvent.getKeyModifiersText(m。

28、odifiers); if (tmpString.length() 0) modString += ( + tmpString + ); else modString += (no modifiers); displayArea.append(s + newline + + charString + newline + + keyCodeString + newline + + modString + newline); ,6.4 常见事件处理,程序运行结果:,6.4 常见事件处理,三、鼠标事件,接口:MouseListener 注册:addMouseListener(MouseListene。

29、r) 处理:mouseClicked(MouseEvent) mouseEntered(MouseEvent) mouseExited(MouseEvent) mousePressed(MouseEvent) mouseReleased(MouseEvent),6.4 常见事件处理,鼠标事件的主要方法: getClickCount(),getPoint(),getX(),getY() 判断是否按下其他键: boolean isAltDown() boolean isControlDown() boolean isMetaDown() boolean isShiftDown() getModif。

30、iersEx()-jdk1.4 String getMouseModifiersText(int modifiers),6.5 响应用户输入,例1:,import javax.swing.*; import java.awt.*; import java.awt.event.*; public class PasswordDemo public static void main(String argv) final JFrame f = new JFrame(PasswordDemo); JLabel label = new JLabel(Enter the password: ); JPas。

31、swordField passwordField = new JPasswordField(10); passwordField.setEchoChar(#);,6.5 响应用户输入,passwordField.addActionListener(new ActionListener() public void actionPerformed(ActionEvent e) JPasswordField input = (JPasswordField)e.getSource(); char password = input.getPassword(); if (isPasswordCorrect。

32、(password) JOptionPane.showMessageDialog(f, Success! You typed the right password.); else JOptionPane.showMessageDialog(f, Invalid password. Try again., Error Message, JOptionPane.ERROR_MESSAGE); );,6.5 响应用户输入,JPanel contentPane = new JPanel(new BorderLayout(); contentPane.setBorder(BorderFactory.cr。

33、eateEmptyBorder(20, 20, 20, 20); contentPane.add(label, BorderLayout.WEST); contentPane.add(passwordField, BorderLayout.CENTER); f.setContentPane(contentPane); f.addWindowListener(new WindowAdapter() public void windowClosing(WindowEvent e) System.exit(0); ); f.pack(); f.setVisible(true); ,6.5 响应用户输。

34、入,private static boolean isPasswordCorrect(char input) char correctPassword = b, u, g, a, b, o, o ; if (input.length != correctPassword.length) return false; for (int i = 0; i input.length; i +) if (inputi != correctPasswordi) return false; return true; ,6.5 响应用户输入,运行结果:,6.5 响应用户输入,例2:,import java.a。

35、wt.*; import java.awt.event.*; import javax.swing.*; public class Demo extends JPanel implements ActionListener JButton myButton; JTextField myTextField; JLabel myLabel;,6.5 响应用户输入,public Demo() ImageIcon ButtonIcon = new ImageIcon(images/right.gif); ImageIcon LabelIcon = new ImageIcon(images/middle。

36、.gif); myButton = new JButton(Delete, ButtonIcon); myButton.setMnemonic(KeyEvent.VK_D); myButton.setToolTipText(delete the text.); myButton.addActionListener(this); myLabel = new JLabel(Show the text,LabelIcon,JLabel.CENTER); myTextField = new JTextField(,20); myTextField.addActionListener(this);,6.。

37、5 响应用户输入,/Add Components to this container, using GridLayout. setLayout(new GridLayout(); add(myLabel); add(myButton); add(myTextField); public void actionPerformed(ActionEvent e) if (e.getSource() = myButton) myTextField.setText(); myLabel.setText(Please input text:); else if (e.getSource() = myTex。

38、tField) myLabel.setText(myTextField.getText(); else ,6.5 响应用户输入,public static void main(String args) /Make sure we have nice window decorations. JFrame.setDefaultLookAndFeelDecorated(true); JFrame frame = new JFrame(Demo); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setContentPane(ne。

39、w Demo(); /Display the window. frame.pack(); frame.setVisible(true); ,6.5 响应用户输入,运行结果:,6.5 响应用户输入,二、菜单,一个典型的菜单系统,6.5 响应用户输入,1. 菜单系统的组成,菜单系统,一般菜单,可撕下菜单,帮助菜单,类JMenuBar,选项#1,菜单中的菜单,选项#3,选项#4,选项#1,选项#2,第三层菜单,选项#3,选项#1,选项#2,类JMenu,类JMenuItem,选项#2,菜单容器,非菜单容器,6.5 响应用户输入,2. 菜单类结构,6.5 响应用户输入,3. 菜单设计与实现,1)创建菜。

40、单条:mMenuBar = new JMeunBar() 2)创建不同的菜单并加入到菜单条中: mEditMenu = new JMenu(Edit); mMenuBar.add(mEditMenu); 3)为每个菜单创建更下一级的菜单项,并加入到菜单中: mCopyMenuItem = new JMenuItem(Copy); mEditMenu.add(mCopyMenuItem),6.5 响应用户输入,4)将菜单条加入到容器中。只有实现了MenuContainer接口的容器才能加入菜单条。 5)为各菜单项注册监听器: mCopyMenuItem.addActionListener(thi。

41、s); 6)在监听器中进行相应处理。采用getSource()和getActionCommand()方法判断用户点击的菜单和菜单项。,6.5 响应用户输入,4、其他菜单结构,使用分隔线菜单的addSeparator()方法,注意菜单项是按照加入的先后顺序排列在菜单中的。 使用快捷键。有两种方法: (1) mCopyMenu=new JMenuItem(Copy,new MenuShortcut(O); (2) mCopyMenu.setShortcut(new MenuShortcut(O); 使用二级菜单。首先创建一个包含若干菜单子项(JMenuItem)的菜单项(JMenu),再把这个菜单。

42、项像菜单子项一样加到一级菜单项中。,6.5 响应用户输入,使用检测盒菜单子项(JCheckboxMenuItem) (1)生成检测盒菜单子项 mc=new JCheckboxMenuItem(Cut) (2)加入到菜单中。 mEditMenu.add(mc); 注意:它引发的事件不是ActionEvent,而是选择事件ItemEvent,所以要注册ItemListener,并具体实现其itemStateChanged(ItemEvent e)事件。,6.5 响应用户输入,5、弹出式菜单PopupMenu,弹出式菜单附在某一个组件或容器上,一般不可见,只有鼠标在该组件或容器单击右键时显示。 (1。

43、)创建弹出式菜单。 JPopupMenu popMnew JPopupMenu(); JMenuItem pi_1=new JMenuItem(open); popM.add(pi_1); pi_1.addActionListener(this); (2)附在某个组件或容器上。 btn1.add(popM); (3)为该组件或容器注册鼠标事件监听器MouserListener:btn1.addMouseListener(this)。,6.5 响应用户输入,(4)重载MouseListener的mouseReleased(MouseEvent e)方法,同时使用弹出式菜单的show方法显示。 p。

44、ublic void mouseReleased(MouseEvent e) if(e.isPopupTrigger() popM.show(Component)e.getSource(), e.getX(),e.getY(); ,6.5 响应用户输入,例MenuDemo:,import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MenuDemo extends JFrame implements ActionListener, ItemListener JTextArea output; J。

45、ScrollPane scrollPane; String newline = n;,6.5 响应用户输入,public MenuDemo() JMenuBar menuBar; JMenu menu, submenu; JMenuItem menuItem; JRadioButtonMenuItem rbMenuItem; JCheckBoxMenuItem cbMenuItem; addWindowListener(new WindowAdapter() public void windowClosing(WindowEvent e) System.exit(0); );,6.5 响应用户。

46、输入,Container contentPane = getContentPane(); output = new JTextArea(5, 30); output.setEditable(false); scrollPane = new JScrollPane(output); contentPane.add(scrollPane, BorderLayout.CENTER); /Create the menu bar. menuBar = new JMenuBar(); setJMenuBar(menuBar); /Build the first menu. menu = new JMenu。

47、(A Menu); menu.setMnemonic(KeyEvent.VK_A); menu.getAccessibleContext().setAccessibleDescription( The only menu in this program that has menu items); menuBar.add(menu);,6.5 响应用户输入,menuItem = new JMenuItem(A text-only menu item, KeyEvent.VK_T); menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.。

48、VK_1, ActionEvent.ALT_MASK); menuItem.getAccessibleContext().setAccessibleDescription( This doesnt really do anything); menuItem.addActionListener(this); menu.add(menuItem); menuItem = new JMenuItem(Both text and icon, new ImageIcon(images/middle.gif); menuItem.setMnemonic(KeyEvent.VK_B); menuItem.a。

49、ddActionListener(this); menu.add(menuItem);,6.5 响应用户输入,/a group of radio button menu items menu.addSeparator(); ButtonGroup group = new ButtonGroup(); rbMenuItem = new JRadioButtonMenuItem(A radio button menu item); rbMenuItem.setSelected(true); rbMenuItem.setMnemonic(KeyEvent.VK_R); group.add(rbMen。

50、uItem); rbMenuItem.addActionListener(this); menu.add(rbMenuItem); rbMenuItem = new JRadioButtonMenuItem(Another one); rbMenuItem.setMnemonic(KeyEvent.VK_O); group.add(rbMenuItem); rbMenuItem.addActionListener(this); menu.add(rbMenuItem);,6.5 响应用户输入,/a group of check box menu items menu.addSeparator(。

51、); cbMenuItem = new JCheckBoxMenuItem(A check box menu item); cbMenuItem.setMnemonic(KeyEvent.VK_C); cbMenuItem.addItemListener(this); menu.add(cbMenuItem); cbMenuItem = new JCheckBoxMenuItem(Another one); cbMenuItem.setMnemonic(KeyEvent.VK_H); cbMenuItem.addItemListener(this); menu.add(cbMenuItem);。

52、 /a submenu menu.addSeparator(); submenu = new JMenu(A submenu); submenu.setMnemonic(KeyEvent.VK_S);,6.5 响应用户输入,menuItem = new JMenuItem(An item in the submenu); menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_2, ActionEvent.ALT_MASK); menuItem.addActionListener(this); submenu.add(menuIt。

53、em); menuItem = new JMenuItem(Another item); menuItem.addActionListener(this); submenu.add(menuItem); menu.add(submenu); menu = new JMenu(“Another Menu”); /另一个菜单 menu.setMnemonic(KeyEvent.VK_N); menu.getAccessibleContext().setAccessibleDescription( This menu does nothing); menuBar.add(menu); ,6.5 响应。

54、用户输入,public void actionPerformed(ActionEvent e) JMenuItem source = (JMenuItem)(e.getSource(); String s = Action event detected. + newline + Event source: + source.getText() + (an instance of + getClassName(source) + ); output.append(s + newline); public void itemStateChanged(ItemEvent e) JMenuItem s。

55、ource = (JMenuItem)(e.getSource(); String s = Item event detected. + newline + Event source: + source.getText() + (an instance of + getClassName(source) + ) + newline + New state: + (e.getStateChange() = ItemEvent.SELECTED) ? selected:unselected); output.append(s + newline); ,6.5 响应用户输入,/ Returns ju。

56、st the class name - no package info. protected String getClassName(Object o) String classString = o.getClass().getName(); int dotIndex = classString.lastIndexOf(.); return classString.substring(dotIndex+1); public static void main(String args) MenuDemo window = new MenuDemo(); window.setTitle(MenuDemo); window.setSize(450, 260); window.setVisible(true); ,6.5 响应用户输入,运行结果:,6.6 小结,重要的是,了解类及其常用方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值