GUI编码-Awt

1、GUI简介

1.1、概述

图形用户界面简称GUI,又称图形用户接口,是指采用图形方式显示的计算机操作用户界面。是一种人与计算机通信的界面显示格式,允许用户使用鼠标等输入设备操纵屏幕上的图标或菜单选项,以选择命令、调用文件、启动程序或执行其他一些日常任务。
我们也可以使用Java来实现GUI编程。而在Java中Gui的核心技术为:Swing AWT;

1.2、组件

  • 窗口
  • 弹窗
  • 面板
  • 文本框
  • 列表框
  • 按钮
  • 图片
  • 监听事件
  • 鼠标事件
  • 键盘事件
  • 破解工具

2、AWT

2.1、Awt介绍

  1. 包含了很多类和接口!
  2. 元素:窗口、按钮、文本框
  3. java.awt

2.2、组件和容器

  1. 界面Frame
package org.star.demo;

import java.awt.*;

public class TestFrame {
    public static void main(String[] args) {

        Frame frame = new Frame("我的第一个Java图像界面窗口");

        //设置窗口大小
        frame.setSize(300, 400);

        //设置背景颜色
        frame.setBackground(Color.BLACK);
        //或者new Color类,后面的参数对应颜色
        //frame.setBackground(new Color(56,56,65));

        //弹出的窗口位置
        frame.setLocation(100, 100);

        //设置大小固定 false表示大小不可变
        frame.setResizable(false);

        //设置可见性
        frame.setVisible(true);

    }
}

在这里插入图片描述
由于没有设置窗口的关闭,所以点 X 无法关闭,我们可以直接停止Java程序

利用封装我们展示多个窗口:

package org.star.demo;

import java.awt.*;

public class TestFrame2 {
    public static void main(String[] args) {
        new MyFrame(100, 100, 200, 200, Color.blue);
        new MyFrame(300, 100, 200, 200, Color.yellow);
        new MyFrame(100, 300, 200, 200, Color.red);
        new MyFrame(300, 300, 200, 200, Color.green);
    }
}

class MyFrame extends Frame {
    static int num = 0;

    //我们在构造方法中传入窗口的位置、大小、颜色这几个参数
    public MyFrame(int x, int y, int w, int h, Color color) {

        //调用父类的构造方法给窗口命名
        super("MyFrame" + (++num));

        //由于继承了Frame,可以继承Frame类的所以方法
        setBounds(x, y, w, h);//此方法可以直接将位置,大小一起设置
        setBackground(color);
        setVisible(true);
    }
}

在这里插入图片描述

  1. Panel
    解决关闭事件!
package org.star.demo;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TestPanel {
    public static void main(String[] args) {
        //Panel可以看成时一个空间,但是不能单独存在,必须在窗口中
        Frame frame = new Frame();
        Panel panel = new Panel();
        //设置布局
        frame.setLayout(null);

        //设置位置颜色
        frame.setBounds(100, 100, 300, 400);
        frame.setBackground(Color.BLACK);
        //设置面板的坐标颜色,相对于窗口的坐标
        panel.setBounds(50, 50, 100, 100);
        panel.setBackground(Color.red);

        //将面板放入窗口中
        frame.add(panel);

        frame.setVisible(true);

        //要关闭窗口,就要监听窗口关闭事件  System.exit(0)
        //适配器模式 在匿名内部类中选择重写Closeing方法
        frame.addWindowListener(new WindowAdapter() {
            //在窗口关闭的时候需要做的事情
            @Override
            public void windowClosing(WindowEvent e) {
                //关闭窗口
                System.exit(0);
            }
        });
    }
}

在这里插入图片描述

2.3、布局管理器

  1. 流式布局 FlowLayout
package org.star.demo;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TestFlowLayout {
    public static void main(String[] args) {
        Frame frame = new Frame("FlowLayout");

        //组件-按钮
        Button button1 = new Button("button1");
        Button button2 = new Button("button2");
        Button button3 = new Button("button2");

        //将按钮以流式布局的方式分布在窗口上 流式布局有左中右三种方式
        //frame.setLayout(new FlowLayout());中间
        //frame.setLayout(new FlowLayout(FlowLayout.LEFT));左
        frame.setLayout(new FlowLayout(FlowLayout.RIGHT));//右

        //设置大小 默认位置
        frame.setSize(300, 400);

        //添加按钮
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);

        //可关闭窗口
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        //可视化
        frame.setVisible(true);

    }
}

在这里插入图片描述

  1. 东南西北中 BorderLayout
package org.star.demo;

import java.awt.*;

public class TestBorderLayout {
    public static void main(String[] args) {
        Frame frame = new Frame("TestBorderLayout");

        //BorderLayout有东南西北中五个方式
        Button east = new Button("East");
        Button west = new Button("West");
        Button south = new Button("South");
        Button north = new Button("North");
        Button center = new Button("Center");

        frame.add(east, BorderLayout.EAST);
        frame.add(west, BorderLayout.WEST);
        frame.add(south, BorderLayout.SOUTH);
        frame.add(north, BorderLayout.NORTH);
        frame.add(center, BorderLayout.CENTER);

        frame.setBackground(Color.BLACK);
        frame.setSize(300, 400);
        frame.setVisible(true);
    }
}

在这里插入图片描述

  1. 表格布局 GridLayout
package org.star.demo;

import java.awt.*;

public class TestGridLayout {
    public static void main(String[] args) {
        Frame frame = new Frame("GridLayout");

        Button button1 = new Button("button1");
        Button button2 = new Button("button2");
        Button button3 = new Button("button3");
        Button button4 = new Button("button4");
        Button button5 = new Button("button5");
        Button button6 = new Button("button6");

        //表格式要new GridLayout后面的参数表示表格几行几列,后面还有两个参数表示行列间距,这里默认间距
        //并且将表格格式使用setLatyou方法传入
        frame.setLayout(new GridLayout(3, 2));

        //添加按钮
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);
        frame.add(button4);
        frame.add(button5);
        frame.add(button6);

        //pack() Java函数是将按钮自动布局 可以不用
        frame.pack();
        frame.setSize(300, 400);
        frame.setVisible(true);
        frame.setBackground(Color.BLACK);
    }
}

在这里插入图片描述

2.3.1、接下来做一个练习

创建一个如下的窗口,按钮如图所示
在这里插入图片描述

2.3.2、分析:这是一个窗口Frame,有上下两个面板(都是东西中布局),所以窗口是表格布局2X1,上面板的东西是两个按钮,中间是有两个按钮(表格布局2X1)的面板,下面板的的东西是两个按钮,中间是有4个按钮(表格布局2X2)的面板,所以需要1个Frame,4个Panel,10个Button。

2.3.3、代码实现:

package org.star.demo;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Test {
    public static void main(String[] args) {
        //总的窗口
        Frame frame = new Frame("Test");
        frame.setBounds(100, 100, 400, 400);
        frame.setVisible(true);
        frame.setLayout(new GridLayout(2, 1));//表格布局

        //4个面板
        Panel panel1 = new Panel();//上面板
        Panel panel2 = new Panel();//上面板中的面板
        Panel panel3 = new Panel();//下面板
        Panel panel4 = new Panel();//下面板中的面板

        //面板的布局
        panel1.setLayout(new BorderLayout());//东南西北中
        panel2.setLayout(new GridLayout(2, 1));//表格式
        panel3.setLayout(new BorderLayout());//东南西北中
        panel4.setLayout(new GridLayout(2, 2));//表格式

        //按钮的添加
        panel1.add(new Button("button1-1"), BorderLayout.WEST);//西
        panel1.add(new Button("button1-2"), BorderLayout.EAST);//东
        panel2.add(new Button("Center-button1-1"));//列表式是直接添加按钮,一个参数
        panel2.add(new Button("Center-button1-2"));
        panel3.add(new Button("button2-1"), BorderLayout.WEST);
        panel3.add(new Button("button2-2"), BorderLayout.EAST);
        for (int i = 0; i < 4; i++) {//这里使用循环添加四个按钮
            panel4.add(new Button("Center-button2-" + i));
        }

        //分别将两个小面板添加到两个大面板
        panel1.add(panel2, BorderLayout.CENTER);
        panel3.add(panel4, BorderLayout.CENTER);

        //分别将两个大面板添加到窗口
        frame.add(panel1);
        frame.add(panel3);

        //关闭事件
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}
 

2.3.4、运行结果:

在这里插入图片描述

2.4、事件监听

事件监听:当某个事情发生的时候,干什么?

package org.star.demo2;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TestActionEvent {
    public static void main(String[] args) {

        Frame frame = new Frame("TestActionEvent");
        //我们设定按下按钮,发生事件
        Button button = new Button("Action");

        //按钮则需要调用addActionListener方法,查看源码,该方法需要传入一个ActionListener
        //我们新建一个myActionListener类来继承ActionListener类,然后创建该类对象传入该方法
        //或者使用匿名内部类
        /*
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("abc");
            }
        });
        */
        MyActionListener myActionListener = new MyActionListener();
        button.addActionListener(myActionListener);

        frame.add(button, BorderLayout.CENTER);//添加按钮

        //关闭窗口的事件
        windowClose(frame);

        frame.setVisible(true);//可视化
        frame.pack();
        frame.setSize(300, 400);//设置大小
    }

    private static void windowClose(Frame frame) {
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

//事件监听
class MyActionListener implements ActionListener {

    //继承ActionListener接口必须重写唯一的actionPerformed方法
    @Override
    public void actionPerformed(ActionEvent e) {
        //这里输出abc
        System.out.println("abc");
    }
}

在这里插入图片描述
多个按钮共享一个事件

package org.star.demo2;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TestActionTwo {
    public static void main(String[] args) {
        Frame frame = new Frame("Test");

        //两个按钮实现同一个事件监听
        //比如开始和停止
        Button button1 = new Button("start");
        Button button2 = new Button("stop");

        //给方法是设置按钮的信息,按钮1没有设置,则会显示默认的值
        button2.setActionCommand("button2-stop");

        MyMonitor myMonitor = new MyMonitor();
        button1.addActionListener(myMonitor);
        button2.addActionListener(myMonitor);

        frame.add(button1, BorderLayout.NORTH);
        frame.add(button2, BorderLayout.SOUTH);
        frame.pack();
        frame.setSize(300, 400);
        frame.setVisible(true);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

    }
}

class MyMonitor implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        //e.getActionCommand()该方法是获得按钮的信息
        System.out.println("按钮被点击了:msg=>" + e.getActionCommand());
        //这里判断按钮的信息可以进行一些操作,实现按钮的通用
        //即多个按钮共享一个事件,每个按钮分别进行一个操作
        if (e.getActionCommand().equals("button2-stop")) {
       	    System.exit(0);
        }
    }
}

在这里插入图片描述
在这里插入图片描述

2.5、输入框TextField监听

package org.star.demo2;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TestTextField {
    public static void main(String[] args) {
        //为了看起来更简介,我们创建其他的类来实现操作
        //这里只需启动程序
        new MyFrame();
    }
}


class MyFrame extends Frame {//继承Frame类可以直接使用Frame方法

    public MyFrame() {
        //创建textField类添加到窗口
        TextField textField = new TextField();
        add(textField);

        //文本框要输入文字则必须要监听这个文本框输入的文字
        MyActionListener2 myActionListener2 = new MyActionListener2();
        //按下enter就会触发这个输入框事件
        textField.addActionListener(myActionListener2);

        //我们也可以设置替换编码,在输入框中看不到真实的文本
        textField.setEchoChar('*');
        setVisible(true);
        setSize(300, 400);

        //关闭窗口
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

class MyActionListener2 implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        //e.getSource()该方法时获得一些资源,返回的是一个对象
        //将得到的对象转成TextField类
        TextField field = (TextField) e.getSource();

        //field.getText()获取输入框的文本
        System.out.println(field.getText());//将输出输入框的文本

        field.setText("");//将文本框清空
    }
}

在这里插入图片描述
在这里插入图片描述

2.6、简易计算器

在这里插入图片描述
实现则这样一个简易计算器,两个文本框,一个加号标签,一个等号按钮,分别往两个文本框输入数字,按下按钮会将两个输入框中的数据相加输出到第三个文本框。

package org.star.demo2;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TestCalc {
    public static void main(String[] args) {
        //启动
        new Calculator();
    }
}

class Calculator extends Frame {
    public Calculator() {
        //3个文本框
        TextField field1 = new TextField(10);//后面的参数为字符数
        TextField field2 = new TextField(10);
        TextField field3 = new TextField(20);

        //一个标签
        Label label = new Label("+");

        //一个按钮
        Button button = new Button("=");
        MyCalculatorListener myCalculatorListener = new MyCalculatorListener(field1, field2, field3);
        button.addActionListener(myCalculatorListener);

        //布局
        setLayout(new FlowLayout());//流式布局
        add(field1);
        add(label);
        add(field2);
        add(button);
        add(field3);

        pack();
        setVisible(true);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

class MyCalculatorListener implements ActionListener {

    private static TextField field1, field2, field3;
    
    //利用构造方法将三个文本框传传入该类,利于操作
    public MyCalculatorListener(TextField field1, TextField field2, TextField field3) {
        this.field1 = field1;
        this.field2 = field2;
        this.field3 = field3;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        //获取文本框的数据
        String text1 = field1.getText();
        String text2 = field2.getText();

        //String-->int
        int num1 = Integer.parseInt(text1);
        int num2 = Integer.parseInt(text2);

        //将两个加数相加,并将结果以字符串的类型写到第三个文本框
        int num3 = num1 + num2;
        field3.setText(num3 + "");

        //将前面两个框清除
        field1.setText("");
        field2.setText("");

    }
}

在这里插入图片描述
在这里插入图片描述
完全改造为面向对象写法

package org.star.demo2;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TestCalc {
    public static void main(String[] args) {
        new MyCalculator().loadFrame();
    }
}

class MyCalculator extends Frame {
    TextField field1, field2, field3;

    public void loadFrame() {
        field1 = new TextField(10);
        field2 = new TextField(10);
        field3 = new TextField(20);

        Label label = new Label("+");

        Button button = new Button("=");
        button.addActionListener(new CalcuatorListener(this));

        setLayout(new FlowLayout());
        add(field1);
        add(label);
        add(field2);
        add(button);
        add(field3);

        pack();
        setVisible(true);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

    }
}

class CalcuatorListener implements ActionListener {
    private static MyCalculator myCalculator = null;

    public CalcuatorListener(MyCalculator myCalculator) {
        this.myCalculator = myCalculator;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String text1 = myCalculator.field1.getText();
        String text2 = myCalculator.field2.getText();

        int num1 = Integer.parseInt(text1);
        int num2 = Integer.parseInt(text2);

        myCalculator.field3.setText((num1 + num2) + "");

        myCalculator.field1.setText("");
        myCalculator.field2.setText("");
    }
}

在这里插入图片描述
在这里插入图片描述
内部类:更好的包装

package org.star.demo3;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TextCalc {
    public static void main(String[] args) {
        new MyCalculator().loadFrame();
    }
}

class MyCalculator extends Frame {
    //属性
    TextField field1, field2, field3;

    //方法
    public void loadFrame() {
        field1 = new TextField(10);
        field2 = new TextField(10);
        field3 = new TextField(20);

        Label label = new Label("+");

        Button button = new Button("=");
        button.addActionListener(new CalculatorListener());

        setLayout(new FlowLayout());
        add(field1);
        add(label);
        add(field2);
        add(button);
        add(field3);

        pack();
        setVisible(true);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

    }

    //内部类可以访问外部类的属性个方法
    class CalculatorListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            int text1 = Integer.parseInt(field1.getText());
            int text2 = Integer.parseInt(field2.getText());
            field3.setText((text1 + text2) + "");
            field1.setText("");
            field2.setText("");
        }
    }
}

在这里插入图片描述
在这里插入图片描述

2.7、画笔

package org.star.demo3;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TestPaint {
    public static void main(String[] args) {
        new MyPaint();
    }
}

class MyPaint extends Frame {
    public MyPaint() {
        setBounds(100, 100, 400, 400);
        setVisible(true);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    //重写Frame类的paint方法
    //画笔
    @Override
    public void paint(Graphics g) {
        //画笔需要有颜色,画笔可以画画
        //g.setColor(Color.red);//设置颜色

        g.drawOval(100, 100, 100, 100);//画一个圆 参数是相对于窗口的位置,大小
        g.fillOval(200, 100, 100, 100);//实心圆

        g.drawRect(100, 200, 100, 100);//矩形
        g.fillRect(200, 200, 100, 100);//实心矩形

        //画笔用完,将它还原到最初的颜色,即将设置颜色代码注释掉
    }
}

在这里插入图片描述
还原颜色后在这里插入图片描述

2.8、鼠标监听

实现鼠标画画
在这里插入图片描述

package org.star.demo3;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Iterator;

//鼠标监听事件
public class TestMouseListener {
    public static void main(String[] args) {
        new MyFrame("TestMouse");
    }
}

class MyFrame extends Frame {
    //画画需要画笔,需要监听鼠标当前的位置,需要集合来存储这个点
    ArrayList points;

    public MyFrame(String title) {
        super(title);//给窗口命名

        setBounds(200, 200, 300, 400);

        //存储鼠标点击的点
        points = new ArrayList<Point>();

        setVisible(true);
        //鼠标监听器,正对这个窗口
        addMouseListener(new MyMouseListener());

        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    //画笔
    @Override
    public void paint(Graphics g) {
        //画画,监听鼠标的事件
        //遍历集合中的点,将点画上去
        Iterator iterator = points.iterator();
        while (iterator.hasNext()) {
            Point point = (Point) iterator.next();
            g.setColor(Color.BLUE);

            //Point类中的方法:point.x,point.y 获取坐标
            g.fillOval(point.x, point.y, 10, 10);//点是一个很小的实心圆
        }
    }

    //适配器模式 在鼠标监听器中想重写哪一个方法就重写哪一个方法,不用重写所有的方法
    private class MyMouseListener extends MouseAdapter {
        //鼠标有:按下 弹起 按住不放几种

        //该方法就是鼠标按压
        //只需重写该方法
        @Override
        public void mousePressed(MouseEvent e) {
            //MyFrame调用该类,所以得到的资源要转成MyFrame类型
            MyFrame frame = (MyFrame) e.getSource();

            //我们点击的时候,就会在界面上产生一个点!画
            //e.getX(),e.getY是获得鼠标点击的点的坐标
            //将鼠标点击的点存入集合points
            points.add(new Point(e.getX(), e.getY()));

            //每次点击都要重画一次
            frame.repaint();//刷新
        }
    }
}

在这里插入图片描述

2.9、窗口监听

package org.star.demo3;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TestWindow {
    public static void main(String[] args) {
        new WindowFrame();
    }
}

class WindowFrame extends Frame {
    public WindowFrame() {
        setBounds(100, 100, 300, 400);
        setVisible(true);

        //使用匿名内类 适配器模式,可以选择方法进行重写
        addWindowListener(new WindowAdapter() {
            //关闭窗口
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("windowClosing");
                System.exit(0);
            }

            //激活窗口
            @Override
            public void windowDeactivated(WindowEvent e) {
                //当窗口最小化时就会执行
                System.out.println("windowDeactivated");
            }
        });
    }
}

在这里插入图片描述
在这里插入图片描述

2.10、键盘监听

package org.star.demo3;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TestKeyListener {
    public static void main(String[] args) {
        new KeyFrame();
    }
}

class KeyFrame extends Frame {
    public KeyFrame() {
        setVisible(true);
        setBounds(100, 100, 300, 400);
        //关闭窗口
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        //键盘键听 同样使用适配器模式,重写想要的方法
        addKeyListener(new KeyAdapter() {
            //键盘按下
            @Override
            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();//获取按下键对应的ARCII码值
		System.out.println(keyCode);

                //KeyEvent.VK_XXX 可以得到所有的键
                if (keyCode == KeyEvent.VK_E) {
                    System.out.println("你按下了E键");
                }
            }
        });
    }
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值