【JAVA】GUI编程

  1. GUI的概念
  2. Swing概述
  3. 容器组件
  4. 布局管理器
  5. 常用组件
  6. 事件处理
  7. 对话框

GUI的概念

GUI(Graphical User Interface)即图形用户界面,它能够使应用程序使用起来更加便捷,看上去更加友好。

Swing概述

 Swing是纯Java组件,使得应用程序在不同的平台上运行时具有相同外观和相同的行为。Swing中的大部分组件类位于javax.swing包中。Swing中的组件非常丰富,支持很多功能强大的组件。

容器组件 

Java的图形用户界面的基本组成部分是组件组件是一个以图形化的方式,显示在屏幕上并能与用户进行交互的对象;

组件不能独立地显示出来,必须将组件放在一定的容器(container)中才可以显示出来。

容器可以容纳多个组件,通过调用容器的add(Component comp)方法向容器中添加组件。

窗口(Frame)和面板(Panel)是最常用的两个容器。

常用的容器组件:

JFrame

用于在Swing程序中创建窗口。

JFrame的常用方法有:

  • void setSize(int width, int height):设置窗口尺寸大小
  • void setVisible(boolean b):显式窗口,放在代码最后
  • void setTitle(String title):设置窗口标题
  • void setResizable(boolean resizable):设置是否能更改界面大小
  • void setLocation(int x,int y):设置界面位置
  • void setLocationRelativeTo(null):窗口相对位置,水平居中
  • void setDefaultCloseOperation(int operation):关闭窗口选项
  • void dispose():关闭窗口,并释放一部分资源。

dispose()和setVisible()方法,在表象上没有任何区别,它们的实质区别在于setVisible方法仅仅隐藏窗体,而dispose方法是关闭窗体,并释放一部分资源。 

Jpanel

JPanel提供面板,它是轻量级的容器; 面板中可以添加其它组件,也可以设置布局,我们一般使用面板来实现布局嵌套。

package Day1.Demo1;

import javax.swing.*;
import java.awt.*;

public class Demo1 extends JFrame {
    public static void main(String[] args) {
        //JFrame
        JFrame jFrame = new JFrame();//新建窗口
        //JFrame jFrame = new JFrame("我的GUI界面");//新建窗口,并设定标题
        jFrame.setSize(500,500);//设置窗口尺寸大小
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口选项
        jFrame.setTitle("我的GUI界面");//设置窗口标题
        jFrame.setResizable(false);//禁止更改界面大小
        jFrame.setLocation(500,500);//更改界面位置
        jFrame.setLocationRelativeTo(null);//窗口相对位置,水平居中

        //JPanel
        JPanel jPanel=new JPanel();//面板,面板默认流式布局,组件居中对齐
        JPanel jPanel1=new JPanel(new FlowLayout(FlowLayout.CENTER));//流式布局
        JPanel jPanel2=new JPanel(new GridLayout());//网格布局
        JPanel jPanel3=new JPanel(new BorderLayout());//边界布局
        jFrame.add(jPanel);//在窗口上添加面板
        Color color=new Color(200);//新建颜色
        jPanel.setBackground(color);//设置面板背景颜色

        //新建按钮JButton
        JButton jButton1=new JButton("按钮1");
        JButton jButton2=new JButton("按钮2");
        JButton jButton3=new JButton("按钮3");
        JButton jButton4=new JButton("按钮4");
        jButton1.setSize(50,50);//设置组件大小
        jButton2.setLocation(400,500);//设置组件位置
        jPanel.add(jButton1);//向面板内添加按钮
        jPanel.add(jButton2,BorderLayout.AFTER_LAST_LINE);//将组件放在面板的指定位置中
        jPanel.add(jButton3);
        jPanel.add(jButton4);

        //新建标签
        JLabel jLabel=new JLabel("用户名");
        jLabel.setForeground(color);//设置标签字体颜色
        jLabel.setFont(new Font("黑体",Font.BOLD,20));//设置标签字体
        jPanel.add(jLabel);//将标签添加到面板中

        //新建单行文本框
        JTextField jTextField=new JTextField(20);//新建单行文本框,设置字体数为20(也可以不设置)
        jPanel.add(jTextField,FlowLayout.CENTER);

        jPanel.setVisible(true);//显式面板
        jFrame.setVisible(true);//显式窗口,放在代码最后
        //this.setVisible(true);//this指当前窗口,显式窗口,放在代码最后
    }
}

布局管理器

swing中,提供了布局管理器类的对象可以管理。

每个Jpanel都有一个布局管理器对象,当容器需要对某个组件进行定位或判断其大小尺寸时,就会调用其对应的布局管理器,调用Jpanel的setLayout方法改变其布局管理器对象或通过构造方法设置。

三种常用的布局管理器:FlowLayout , BorderLayout, GridLayout。

 FlowLayout

FlowLayout布局管理器是流式布局管理器,它将组件按照从左到右、从上到下的顺序来安排,并在默认情况下使组件尽量居中放置。

FlowLayout布局管理器对组件逐行定位,行内从左到右,一行排满后换行。不改变组件的大小,按组件原有尺寸显示组件,可设置不 同的组件间距,行距以及对齐方式。

 

package Day1.Demo2;

import javax.swing.*;
import java.awt.*;

public class MyJFrame extends JFrame{

        public static void main(String[] args) {
            //JFrame
            JFrame jFrame = new JFrame();//新建窗口
            jFrame.setSize(500,500);//设置窗口尺寸大小
            jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口选项
            jFrame.setTitle("我的GUI界面");//设置窗口标题
            jFrame.setResizable(false);//禁止更改界面大小
            jFrame.setLocation(500,500);//更改界面位置
            jFrame.setLocationRelativeTo(null);//窗口相对位置,水平居中

            //JPanel
            //JPanel jPanel=new JPanel();//面板,面板默认流式布局,组件居中对齐
            JPanel jPanel=new JPanel(new FlowLayout(FlowLayout.CENTER));//流式布局
//            JPanel jPanel2=new JPanel(new GridLayout());//网格布局
//            JPanel jPanel3=new JPanel(new BorderLayout());//边界布局
            jFrame.add(jPanel);//在窗口上添加面板
            Color color=new Color(200);//新建颜色
            jPanel.setBackground(color);//设置面 板背景颜色

            //新建按钮JButton
            JButton jButton1=new JButton("按钮1");
            JButton jButton2=new JButton("按钮2");
            JButton jButton3=new JButton("按钮3");
            JButton jButton4=new JButton("按钮4");
            jButton1.setSize(50,50);//设置组件大小
            jButton2.setLocation(400,500);//设置组件位置
            jPanel.add(jButton1);//向面板内添加按钮
            jPanel.add(jButton2,BorderLayout.AFTER_LAST_LINE);//将组件放在面板的指定位置中
            jPanel.add(jButton3);
            jPanel.add(jButton4);


            jFrame.setVisible(true);//显式窗口,放在代码最后
            //this.setVisible(true);//this指当前窗口,显式窗口,放在代码最后
        }
    }


BorderLayout

BorderLayout布局管理器只允许在容器内放置5个组件,这5个组件的位置是由BorderLayout类中的 North、South、East、West和Center5个常量来确定的,他们对应着容器中的上下左右中。组件在BorderLayout中的大小都是可以改变的。一般情况下可以让中间区域大一些,而且可以只用其中几个区域。

BorderLayout将整个容器的布局划分成东(EAST)西(WEST)南(SOUTH)北(NORTH)中 (CENTER)五个区域,组件只能被添加到指定的区域。

BorderLayout布局管理器使用时要注意的事项:

  1. 如不指定组件的加入部位,则默认加入到CENTER区。
  2. 每个区域只能加入一个组件,如加入多个,则先前加入的会被覆盖。
  3. BorderLayout型布局容器尺寸缩放原则:
  4. 北、南两个区域在水平方向缩放。
  5. 东、西两个区域在垂直方向缩放。
  6. 中部可在两个方向上缩放。

 

package Day1.Demo2;

import javax.swing.*;
import java.awt.*;

public class MyJFrame extends JFrame{

        public static void main(String[] args) {
            //JFrame
            JFrame jFrame = new JFrame();//新建窗口
            jFrame.setSize(500,500);//设置窗口尺寸大小
            jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口选项
            jFrame.setTitle("我的GUI界面");//设置窗口标题
            jFrame.setResizable(false);//禁止更改界面大小
            jFrame.setLocation(500,500);//更改界面位置
            jFrame.setLocationRelativeTo(null);//窗口相对位置,水平居中

            //JPanel
            //JPanel jPanel=new JPanel();//面板,面板默认流式布局,组件居中对齐
            //JPanel jPanel=new JPanel(new FlowLayout(FlowLayout.CENTER));//流式布局
            //JPanel jPanel=new JPanel(new GridLayout());//网格布局
            JPanel jPanel=new JPanel(new BorderLayout());//边界布局
            jFrame.add(jPanel);//在窗口上添加面板
            Color color=new Color(200);//新建颜色
            jPanel.setBackground(color);//设置面 板背景颜色

            //新建按钮JButton
            JButton jButton1=new JButton("按钮1");
            JButton jButton2=new JButton("按钮2");
            JButton jButton3=new JButton("按钮3");
            JButton jButton4=new JButton("按钮4");
//            jButton1.setSize(50,50);//设置组件大小
//            jButton2.setLocation(400,500);//设置组件位置
            jPanel.add(jButton1,BorderLayout.CENTER);//向面板内添加按钮
            //jPanel.add(jButton2,BorderLayout.AFTER_LAST_LINE);//将组件放在面板的指定位置中
            jPanel.add(jButton2,BorderLayout.EAST);
            jPanel.add(jButton3,BorderLayout.WEST);
            jPanel.add(jButton4,BorderLayout.SOUTH);


            jFrame.setVisible(true);//显式窗口,放在代码最后
            //this.setVisible(true);//this指当前窗口,显式窗口,放在代码最后
        }
    }

GridLayout

GridLayout布局管理器是矩形网格,在网格中放置组件,每个网格的高度和宽度都相等,组件随着网格的大小而在水平和垂直方向上拉伸,网格的大小是由容器的大小和创建网格的多少来确定的。当组件数目大于网格数时,GridLayout保持行数不变而自动增加列数。

GridLayout型布局管理器将空间划分成规则的矩形网格,每个单元格区域大小相等。组件被添加到每个单元格中,先从左到右添满一行后换行,再从上到下。在 GridLayout 构造方法中指定分割的行数和列数。

package Day1.Demo2;

import javax.swing.*;
import java.awt.*;

public class MyJFrame extends JFrame{

        public static void main(String[] args) {
            //JFrame
            JFrame jFrame = new JFrame();//新建窗口
            jFrame.setSize(500,500);//设置窗口尺寸大小
            jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口选项
            jFrame.setTitle("我的GUI界面");//设置窗口标题
            jFrame.setResizable(false);//禁止更改界面大小
            jFrame.setLocation(500,500);//更改界面位置
            jFrame.setLocationRelativeTo(null);//窗口相对位置,水平居中

            //JPanel
            //JPanel jPanel=new JPanel();//面板,面板默认流式布局,组件居中对齐
            //JPanel jPanel=new JPanel(new FlowLayout(FlowLayout.CENTER));//流式布局
            JPanel jPanel=new JPanel(new GridLayout());//网格布局
//            JPanel jPanel3=new JPanel(new BorderLayout());//边界布局
            jFrame.add(jPanel);//在窗口上添加面板
            Color color=new Color(200);//新建颜色
            jPanel.setBackground(color);//设置面 板背景颜色

            //新建按钮JButton
            JButton jButton1=new JButton("按钮1");
            JButton jButton2=new JButton("按钮2");
            JButton jButton3=new JButton("按钮3");
            JButton jButton4=new JButton("按钮4");
            jButton1.setSize(50,50);//设置组件大小
            jButton2.setLocation(400,500);//设置组件位置
            jPanel.add(jButton1);//向面板内添加按钮
            jPanel.add(jButton2,BorderLayout.AFTER_LAST_LINE);//将组件放在面板的指定位置中
            jPanel.add(jButton3);
            jPanel.add(jButton4);


            jFrame.setVisible(true);//显式窗口,放在代码最后
            //this.setVisible(true);//this指当前窗口,显式窗口,放在代码最后
        }
    }


常用组件

JLabel标签

标签是容纳文本和图标的控件,通常用来在界面中标识别的控件。

构造函数:

  • JLabel() 创建一个空的标签
  • JLabel(String text) 创建一个带文本的标签
  • JLabel(Icon image) 创建一个带图像的标签

JLabel的方法有:

  • void setText(String text) 设置标签上的文本
  • String getText() 获得标签上的文本
  • setFont(new Font(“宋体”,Font.BOLD, 18)) 设置字体

JTextField单行文本

可以创建一个单行的文本框,可在其中输入内容。

JTextField的构造函数:

  • JTextField()创建一个空的文本框
  • JTextField(String text )创建有初始化文本的文本框
  • JTextField(int columns)创建指定文本列数的文本框
  • JTextField(String text, int columns)创建指定初始化文本和列数的文本框

JTextField的方法有:

  • void setText(String text) 设置文本框中的文本
  • String getText() 获得文本框中的文本
  • void setEditable(boolean b) 设置文本框是否可以编辑
  • setColumns(20); 设置列数

 

package Day1.Demo2;

import javax.swing.*;
import java.awt.*;

public class MyJFrame2 {
        public static void main(String[] args) {
            //JFrame
            JFrame jFrame = new JFrame();//新建窗口
            jFrame.setSize(500,500);//设置窗口尺寸大小
            jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口选项
            jFrame.setTitle("我的GUI界面");//设置窗口标题
            jFrame.setResizable(false);//禁止更改界面大小
            jFrame.setLocation(500,500);//更改界面位置
            jFrame.setLocationRelativeTo(null);//窗口相对位置,水平居中
            jFrame.dispose();

            //JPanel
            JPanel jPanel=new JPanel();//面板,面板默认流式布局,组件居中对齐
            jFrame.add(jPanel);//在窗口上添加面板
           

            //新建标签
            JLabel jLabel=new JLabel("用户名");
            jLabel.setForeground(color);//设置标签字体颜色
            jLabel.setFont(new Font("黑体",Font.BOLD,20));//设置标签字体
            jPanel.add(jLabel);//将标签添加到面板中

            //新建单行文本框
            JTextField jTextField=new JTextField(20);//新建单行文本框,设置字体数为20(也可以不设置)
            jPanel.add(jTextField,FlowLayout.CENTER);

            jFrame.setVisible(true);//显式窗口,放在代码最后
            //this.setVisible(true);//this指当前窗口,显式窗口,放在代码最后
        }
    }


JTextArea多行文本框

相较与单行文本框,JTextArea有多行文本可以输入。

构造函数:

  • JTextArea() 创建一个空的文本域
  • JTextArea(String text) 用指定文本初始化文本域
  • JTextArea(int rows, int columns) 创建一个指定行数和列数的空文本域
  • JTextArea(String text,int rows, int columns) 创建一个带文本,并指行数和列数的

方法:

  • void setText(String text) 设置文本域中的文本
  • String getText() 获得文本域中的文本
  • void setFont(Font font) 设置文本域中文本的字体
  • void setLineWrap(boolean wrap) //是否自动换行,默认false

JScrollPane文本区滚动条

如果需要文本区自动出现滚动条,可将文本区对象放入滚动窗格(JScrollPane)中。

JScrollPane scrollPane = new JScrollPane(txtArea);

add(scrollPane )

 

JPasswordField密码框

在密码框内输入的文字是看不见的,可以保护用户的隐私,如:

构造函数:

  • JPasswordField()创建一个空的密码框
  • JPasswordField(String text)创建一个带有初始文字的密码框
  • JPasswordField(String text, int columns)创建一个带有初始文字的密码框,并设定列数

方法:

char[] getPassword()返回文本框内容

package Day1.Demo2;

import javax.swing.*;

/*
多行文本框(JTextArea)
 */
public class MyJFrame3 extends JFrame {
    public void Demo(){
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        this.setSize(500,500);
        JPanel jPanel=new JPanel();
        this.add(jPanel);

        //多行文本框
        JTextArea jTextArea=new JTextArea(20,20);
        jPanel.add(jTextArea);
        jTextArea.setLineWrap(true);//设置是否自动换行
        jTextArea.setWrapStyleWord(true);//设置断行不断字,例如英文单词在换行时不会被分割

        //在多行文本框加滑动条
        JTextArea jTextArea1=new JTextArea(20,20);
        JScrollPane jScrollPane=new JScrollPane(jTextArea1);//滑动窗格
        jPanel.add(jScrollPane);

        //密码框
        JPasswordField jPasswordField=new JPasswordField(10);
        jPanel.add(jPasswordField);

        this.setVisible(true);
    }
    public static void main(String[] args) {
        new MyJFrame3().Demo();
    }
}

Menu菜单

 菜单由菜单栏,菜单,菜单项三个部分组成。

菜单栏组件:

  • 构造方法:JMenuBar();
  • 方法:add(menu)向菜单栏添加菜单

 菜单组件:

  • 构造方法:JMenu(“菜单名称");
  • 方法:add(menuItem)向菜单添加菜单选项

菜单项组件:

  • 构造方法:JMenuItem(“菜单项名称");   
package Day1.Demo2;

import javax.swing.*;

/*
菜单
 */
public class MyJFrame4 extends JFrame{
        public void Demo(){
            this.setLocationRelativeTo(null);
            this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            this.setSize(500,500);
            JPanel jPanel=new JPanel();
            this.add(jPanel);

            //菜单分为菜单栏、菜单、菜单项
            JMenuBar jMenuBar=new JMenuBar();//新建菜单栏
            this.setJMenuBar(jMenuBar);//向窗口添加菜单栏
            JMenu jMenu=new JMenu("菜单");//新建菜单
            JMenuItem jMenuItem=new JMenuItem("文件");//新建菜单项
            JMenuItem jMenuItem1=new JMenuItem("打开");
            jMenu.add(jMenuItem);
            jMenu.add(jMenuItem1);
            JMenu jMen1=new JMenu("编辑");
            JMenuItem jMenuItem2=new JMenuItem("保存");
            JMenuItem jMenuItem3=new JMenuItem("删除");
            jMen1.add(jMenuItem2);
            jMen1.add(jMenuItem3);
            JMenu jMenu2=new JMenu("工具");
            JMenuItem jMenuItem4=new JMenuItem("关于");
            jMenu2.add(jMenuItem4);
            jMenuBar.add(jMenu);
            jMenuBar.add(jMen1);
            jMenuBar.add(jMenu2);

            this.setVisible(true);
        }
        public static void main(String[] args) {
            new MyJFrame4().Demo();
        }
    }


事件处理

在设置完用户界面后,程序还需要用户与GUI组件进行交涉,这时候,要实现程序的各项功能,必须进行事件处理。

事件处理:一个源(事件源)产生一个事件(事件对象)并把它送到监听器那里, 监听器只是简单地等待,直到它收到一个事件,一旦事件被接受,监听器将处理这些事件。

为事件添加监听的方法有三种:

  • 一是创建继承事件监听(ActionListener)的类
  • 二是创建内部类
  • 三是当创建的监听只使用一次,可以创建匿名内部类,简化内部类
package Day1.Demo3;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

/*
事件监听
创建监听的方法有三种:
一是创建继承事件监听(ActionListener)的类
二是创建内部类
三是当创建的监听只使用一次,可以创建匿名内部类,简化内部类
 */
public class MyJFrame5 extends JFrame{

        public void Demo(){
            this.setLocationRelativeTo(null);
            this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            this.setSize(500,500);
            JPanel jPanel=new JPanel();
            this.add(jPanel);

            JButton jButton=new JButton("点我");
            jPanel.add(jButton);

            JTextArea jTextArea1=new JTextArea(20,20);
            JScrollPane jScrollPane=new JScrollPane(jTextArea1);
            jPanel.add(jScrollPane);

            JPasswordField jPasswordField=new JPasswordField(10);
            jPanel.add(jPasswordField);

            //为按钮创造监听,创建MyListener继承ActionListener的外部类
            //jButton.addActionListener(new MyListener());

            //为按钮创建监听,并创建内部类
            //jButton.addActionListener(new MyActionListener());

            //为按钮创建监听创建,ActionListener的匿名内部类对象
            jButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("不要点我");
                }
            });



            //为多行文本框创建监听创建,ActionListener的匿名内部类对象
            jTextArea1.addKeyListener(new KeyAdapter() {
                @Override
                public void keyReleased(KeyEvent e) {
                    System.out.println(jTextArea1.getText());
                }
            });

            this.setVisible(true);
        }

        class MyActionListener implements ActionListener{
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("不要在点我啦");
            }
        }

        public static void main(String[] args) {
            new MyJFrame5().Demo();
        }
    }


package Day1.Demo3;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MyListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("点我点我快点我!!!!");
    }
}

对话框

JOptionPane对话框是在用户进行一项事件后,另外弹出的,让用户进行确认、选择、输入或者有提醒的对话框。

showMessageDialog():消息对话框,主要有五种消息类型,类型不同,图标不同:

  • ERROR_MESSAGE 错误消息提示
  • INFORMATION_MESSAGE 信息提示
  • WARNING_MESSAGE 警告提示
  • QUESTION_MESSAGE 问题提示
  • PLAIN_MESSAGE 简洁提示

showConfirmDialog()确认对话框,主要有四种消息类型,类型不同,图标不同:

  • DEFAULT_OPTION 默认选项
  • YES_NO_OPTION /否选项
  • YES_NO_CANCEL_OPTION //取消选项
  • OK_CANCEL_OPTION 确定/取消
package Day1.Demo3;

import javax.swing.*;
import java.awt.event.ActionEvent;

/*
JOptionPane对话框
 */
public class MyJFrame6 extends JFrame {

    public void Demo() {
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        this.setSize(500, 500);
        JPanel jPanel = new JPanel();
        this.add(jPanel);

        JButton jButton = new JButton("点我");
        jPanel.add(jButton);
        JButton jButton2 = new JButton("退出");
        jPanel.add(jButton2);

        JTextArea jTextArea1 = new JTextArea(20, 20);
        JScrollPane jScrollPane = new JScrollPane(jTextArea1);
        jPanel.add(jScrollPane);

        JPasswordField jPasswordField = new JPasswordField(10);
        jPanel.add(jPasswordField);

        this.setVisible(true);

        //为按钮创建监听创建,ActionListener的匿名内部类对象
        jButton.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String word=jTextArea1.getText();
                if (word.length()>10){
                    System.out.println("账号不能超过10位数");
                    //JOptionPane.showMessageDialog(null,"账号不能超过10位数");
                    JOptionPane.showMessageDialog(null,"账号不能超过10位数\n请重新输入","登录提示",JOptionPane.ERROR_MESSAGE);
                    jTextArea1.setText("");
                }
            }
        });
        jButton2.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String word = jTextArea1.getText();
                if (word.length() == 0) {
                    int i = JOptionPane.showConfirmDialog(null, "真的要退出吗?", "提示框",JOptionPane.OK_CANCEL_OPTION);
                    if (i == 0) {
                        dispose();
                    }
                }
            }

        });

    }


        public static void main(String[] args) {
            new MyJFrame6().Demo();
        }
    }





  • 3
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值