GUI编程

GUI编程

告诉大家怎么学
  • 这是什么?

  • 它怎么玩?

  • 该如何在我们平时使用?

    组件
  • 窗口

  • 弹窗

  • 面板

  • 文本框

  • 列表框

  • 按钮

  • 图片

  • 监听事件

  • 鼠标

  • 键盘事件

  • 外挂 - Java(jvm)不容易被发现

  • 破解工具

1、简介

GUI 的核心技术: Swing AWT,但界面不美观,并且运行时需要jre运行环境

为什么我们要学习?

  1. 可以写出自己心中的一些小工具

  2. 工作的时候,也可能需要去维护Swing界面(如果公司需要,表示这家公司比较老)

  3. 了解MVC架构,了解监听!

2、AWT

  1. AWT介绍

包含了很多接口! GUI:

eclipse:使用Java写的软件

  1. 元素:窗口、按钮、文本框

  2. 组件和容器
  3. Frame

//Frame,JDK ,看源码
        Frame frame = new Frame("我的第一个Java图形窗口!");

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

        //设置窗口大小 w 宽 h 高
        frame.setSize(400,400);

        //设置背景颜色 Color
        new Color(100,100,100);
        frame.setBackground(Color.gray);
        //frame.setBackgroud(new Color(100,100,100));自己设置RGB,左边会显示颜色

        //弹出初始位置
        frame.setLocation(20,200);//坐标值

        //设置大小固定(如果没有即弹出的窗口大小可以随意变动)
        frame.setResizable(false);//当值为false的时候窗口大小不能调整,变成固定

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DODytXk4-1658630497811)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220622154833084.png)]

问题:窗口无法关闭,停止Java程序

尝试回顾封装:

import java.awt.*;

public class TestFrame2 {
    public static void main(String[] args) {
        //展示多个窗口
        new MyFrame(100,100,200,200,Color.BLUE);
        new MyFrame(400,100,200,200,Color.gray);
        new MyFrame(100,400,200,200,Color.cyan);
        new MyFrame(400,400,200,200,Color.LIGHT_GRAY);

    }
}

class MyFrame extends Frame {
    //可能存在多个窗口,需要一个计算器
    static int id = 0;

    public MyFrame(int x, int y,int w,int h,Color color){
        super("Myframe"+ (++id));
        setBackground(color);
        setVisible(true);
        setBounds(x,y,w,h);

    }




}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C08GHONg-1658630497812)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220622160005400.png)]

4.面板panel

panel可以看成一个空间,但是不能独立存在

内嵌不同的画面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8N17YZRM-1658630497813)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220622162312871.png)]

解决了窗口关闭事件

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

public class TestPanel {
    public static void main(String[] args) {
//        panel可以看成一个空间,但是不能独立存在

        Frame frame = new Frame();
        //布局概念
        Panel panel = new Panel();

        //设置布局
        frame.setLayout(null);

        //坐标
        frame.setBounds(400,400,1000,800);
        frame.setBackground(new Color(60, 168, 201));

        //panel设置坐标,相对于frame
        panel.setBounds(50,50,400,400);
        panel.setBackground(new Color(168,60,102));

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

        //监听事件,查看窗口是否关闭 System.exit(0)
        //适配器模式:只说明一个方法,不重写其他方法
        frame.addWindowListener(new WindowAdapter() {
            //窗口点击关闭的时候需要做的事情
            @Override
            public void windowClosing(WindowEvent e) {
//                super.windowClosing(e); 仅关闭窗口
                //结束程序
                System.exit(0);
            }
        });


        //以下为打开全部方式,不太方便
//        frame.addWindowListener(new WindowListener() {
//            @Override
//            public void windowOpened(WindowEvent e) {
//
//            }
//
//            @Override
//            public void windowClosing(WindowEvent e) {
//
//            }
//
//            @Override
//            public void windowClosed(WindowEvent e) {
//
//            }
//
//            @Override
//            public void windowIconified(WindowEvent e) {
//
//            }
//
//            @Override
//            public void windowDeiconified(WindowEvent e) {
//
//            }
//
//            @Override
//            public void windowActivated(WindowEvent e) {
//
//            }
//
//            @Override
//            public void windowDeactivated(WindowEvent e) {
//
//            }
//        });



    }


}

适配器可供选择

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q1az5UFl-1658630497813)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220622161701673.png)]

点击关闭时,窗口以及程序都会被关闭停止

3、布局管理器

  • 流式布局

    import java.awt.*;
    
    public class TestFlowLayout {
        public static void main(String[] args) {
            Frame frame = new Frame();
    
            //组件-按钮
            Button button1 = new Button("button1");
            Button button2 = new Button("button2");
            Button button3 = new Button("button3");
    
            //设置为流式布局
    //        frame.setLayout(new FlowLayout());自动居中
    //        frame.setLayout(new FlowLayout(FlowLayout.LEFT));//按钮靠左
            frame.setLayout(new FlowLayout(FlowLayout.RIGHT);//按钮靠右
    
            frame.setSize(800,800);
    
            //吧按钮添加上去
            frame.add(button1);
            frame.add(button2);
            frame.add(button3);
    
            frame.setVisible(true);
        }
    
    
    
    }
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UI535bm8-1658630497814)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220622163351027.png)]

  • 东西南北中

import java.awt.*;

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

        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.setSize(500,800);
        frame.setVisible(true);



    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nwe6I8Gt-1658630497814)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220622164233026.png)]

  • 表格布局

    import java.awt.*;
    
    public class TestBorderLayout {
        public static void main(String[] args) {
            Frame frame = new Frame("TestBorderLayout");
    
            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");
            Button c6 = new Button("C6");
    
            frame.setLayout(new GridLayout(3,2));
            frame.add(east);
            frame.add(west);
            frame.add(south);
            frame.add(north);
            frame.add(center);
            frame.add(c6);
    
            frame.pack();//Java函数!会自动填充大小
            frame.setSize(500,800);
            frame.setVisible(true);
    
    
    
        }
    }
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sc59ME6J-1658630497814)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220622164836820.png)]

框架与面板练习

需求

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EMb3Z7uD-1658630497814)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220703162247058.png)]

练习代码

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


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

    frame.setSize(500,600);
    frame.setLocation(500,400);
    frame.setBackground(Color.gray);
    frame.setVisible(true);
    frame.setLayout(new GridLayout(2,1)); //设置框架结构为两行一列(两部分)

    //创建四个面板
        Panel p1 = new Panel(new BorderLayout());
        Panel p2 = new Panel(new GridLayout(2,1)); //定义网格状面板,分行列排序
        Panel p3 = new Panel(new BorderLayout());
        Panel p4 = new Panel(new GridLayout(2,1));
        //上面按钮
        p1.add(new Button("East-1"),BorderLayout.EAST); //设置第一层面板右边的按钮
        p1.add(new Button("West-1"),BorderLayout.WEST);
        p2.add(new Button("p2-btn-1")); //设置第二层面板中按顺序第一个按钮
        p2.add(new Button("p2-btn-2"));
        p1.add(p2,BorderLayout.CENTER); //在第一层面板中嵌套p2面板

        //下面
        p3.add(new Button("East-2"),BorderLayout.EAST); //同上
        p3.add(new Button("West-2"),BorderLayout.WEST);

        //下层中间四按钮
        for(int i = 0;i < 4; i++){
            p4.add(new Button("for-" + i)); //按顺序增加四个第四层中的四个按钮
        }
        p3.add(p4,BorderLayout.CENTER);

        frame.add(p1); //在两行一列的框架中加入两个面板
        frame.add(p3);


        frame.addWindowListener(new WindowAdapter() {
            //窗口点击关闭的时候需要做的事情
            @Override
            public void windowClosing(WindowEvent e) {
//                super.windowClosing(e); 仅关闭窗口
                //结束程序
                System.exit(0);
            }
        });


    }


}

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-khhmOM31-1658630497815)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220703162507262.png)]

总结

  1. Fram是一个顶级窗口
  2. Panel无法单独显示,必须加在某一个容器中,窗口中
  3. 布局管理器
    • 流式
    • 东西南北中
    • 表格
    • 嵌套

​ 4.大小、定位、背景颜色、可见性监听!

事件监听

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

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();
        Button button = new Button();
        //因为addActionListener()需要一个ActionListener ,所以我们构造重载一个ActionListener
        MyActionListener myActionListener = new MyActionListener();
        button.addActionListener(myActionListener);



        frame.add(button,BorderLayout.CENTER);
        frame.pack();
        WindowClose(frame); //关闭窗口
        frame.setVisible(true);
    }
    //关闭窗体事件
    private  static  void WindowClose(Frame frame){
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }


}
//事件监听
class MyActionListener implements ActionListener{


    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("aaa");
    }
}

!!!多个按钮是可以共用一个事件的!

输入框事件监听TestFiled

创建一个窗口并且进行文本输入,在后台可以获得文本输入框的内容,并且可以对用户输入文本时加密(可加可不加)

代码展示

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 TestText1 {
    public static void main(String[] args) {

        //启动
        new MyFrame2();


    }

}

class MyFrame2 extends Frame{
    public MyFrame2(){
        TextField textField = new TextField();
        add(textField);

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

        //设置替换编码(在不设置这一part的情况下前台文本框显示与输入一致),一般用于密码加密输入
        textField.setEchoChar('*');

        //因为已经继承Frame,所以可以直接操作
        setVisible(true);
        pack();

        //关闭窗口事件
        addWindowListener(new WindowAdapter() {
            //窗口点击关闭的时候需要做的事情
            @Override
            public void windowClosing(WindowEvent e) {
//                super.windowClosing(e); 仅关闭窗口
                //结束程序
                System.exit(0);
            }
        });
    }
}

class MyActionListener2 implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        //获得一些资源(输入框),并且返回给后台一些资源
        TextField field = (TextField) e.getSource();
        //获得并输入文本框的内容
        System.out.println(field.getText());
        field.setText(""); //回车后输入文本框变null “”
    }
}

代码运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o47xqVZ5-1658630497815)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220703192152259.png)]

简易计算器,组合+内部类回顾

opp原则:组合,大于继承

目前代码:

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(){
        //三个文本框
        TextField num1 = new TextField(11);
        TextField num2 = new TextField(11);
        TextField num3   = new TextField(22); //允许输入的字符数

        //一个按钮
        Button button = new Button("=");
        button.addActionListener(new MyCalculatorListener(num1,num2,num3));

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

        //布局 流式布局可自适应
        setLayout(new FlowLayout());

        add(num1);
        add(label);
        add(num2);
        add(button);
        add(num3);


        pack();
        setSize(800,100);
        setVisible(true);

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



//计算器监听事件
class MyCalculatorListener implements ActionListener {

    //获取三个变量
    private TextField num1,num2,num3;
    public MyCalculatorListener(TextField num1,TextField num2,TextField num3){
            this.num1 = num1;
            this.num2 = num2;
            this.num3 = num3;
    }


    @Override
    public void actionPerformed(ActionEvent e) {

        //1.获得加数和被加数
        int n1 = Integer.parseInt(num1.getText());
        int n2 = Integer.parseInt(num2.getText());

        //2.运算两个参数,并且返回值给num3
            num3.setText("" + (n1 + n2));
        //3.清除前两个数
        num1.setText("");
        num2.setText("");

    }
}

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yHrc3enG-1658630497815)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220703195707305.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y9O7W1Dv-1658630497816)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220703195724861.png)]

以上为初级版代码展示

组合进阶版代码展示(符合面向对象要求)
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 TestCalc2 {

    //计算器类启动项
    public static void main(String[] args) {
        new Calculator().loadFrame();
    }
}

//计算器
class Calculator extends Frame{

    //属性
    TextField num1,num2,num3;

    //方法
    public void loadFrame(){
        //三个文本框
        num1 = new TextField(11);
        num2 = new TextField(11);
        num3   = new TextField(22); //允许输入的字符数

        //一个按钮
        Button button = new Button("=");
//        button.addActionListener(new MyCalculatorListener(num1,num2,num3)); 初级
        button.addActionListener(new MyCalculatorListener(this));

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

        //布局 流式布局可自适应
        setLayout(new FlowLayout());

        add(num1);
        add(label);
        add(num2);
        add(button);
        add(num3);


        pack();
        setSize(800,100);
        setVisible(true);

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




//计算器监听事件
class MyCalculatorListener implements ActionListener {

    //获取三个变量()初级
    //进阶版,在一个类中组合另外一个类
//    private TextField num1,num2,num3;
//    public MyCalculatorListener(TextField num1,TextField num2,TextField num3){
//            this.num1 = num1;
//            this.num2 = num2;
//            this.num3 = num3;
//    }
//进阶版(组合进对象)
    Calculator calculator = null;
    public MyCalculatorListener(Calculator calculator){
        this.calculator = calculator;
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        //1.获得加数和被加数()初级
//        int n1 = Integer.parseInt(num1.getText());
//        int n2 = Integer.parseInt(num2.getText());
        //组合版
        int n1 = Integer.parseInt(calculator.num1.getText());
        int n2 = Integer.parseInt(calculator.num2.getText());


        //2.运算两个参数,并且返回值给num3 ()初级
            //组合版
        calculator.num3.setText("" + (n1 + n2));

        //3.清除前两个数 ()初级
//        num1.setText("");
//        num2.setText("");
    //组合版
        calculator.num1.setText("");
        calculator.num2.setText("");


    }
}

代码展示同上

内部类
  • 用于更好的包装,便捷使用

    代码展示:

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 TestCalc3 {

    //计算器类启动项
    public static void main(String[] args) {
        new Calculator().loadFrame();
    }
}

//计算器
class Calculator extends Frame{

    //属性
    TextField num1,num2,num3;

    //方法
    public void loadFrame(){
        //三个文本框
        num1 = new TextField(11);
        num2 = new TextField(11);
        num3   = new TextField(22); //允许输入的字符数

        //一个按钮
        Button button = new Button("=");
//        button.addActionListener(new MyCalculatorListener(num1,num2,num3)); 初级
        button.addActionListener(new MyCalculatorListener());

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

        //布局 流式布局可自适应
        setLayout(new FlowLayout());

        add(num1);
        add(label);
        add(num2);
        add(button);
        add(num3);


        pack();
        setSize(800,100);
        setVisible(true);

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

    //计算器监听事件

    //内部类最大的好处,就是可以畅通无阻的访问外部类的操作,属性和方法!
   private class MyCalculatorListener implements ActionListener {

        //获取三个变量()初级
        //进阶版,在一个类中组合另外一个类
//    private TextField num1,num2,num3;
//    public MyCalculatorListener(TextField num1,TextField num2,TextField num3){
//            this.num1 = num1;
//            this.num2 = num2;
//            this.num3 = num3;
//    }
//进阶版(组合进对象)

        @Override
        public void actionPerformed(ActionEvent e) {

            //1.获得加数和被加数()初级
//        int n1 = Integer.parseInt(num1.getText());
//        int n2 = Integer.parseInt(num2.getText());
            //组合版
            int n1 = Integer.parseInt(num1.getText());
            int n2 = Integer.parseInt(num2.getText());


            //2.运算两个参数,并且返回值给num3 ()初级
            //组合版
            num3.setText("" + (n1 + n2));

            //3.清除前两个数 ()初级
//        num1.setText("");
//        num2.setText("");
            //组合版
            num1.setText("");
            num2.setText("");


        }
    }
}





输出同上!

2.7画笔Paint

代码展示:
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

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

class MyPaint extends Frame{
    public void loadFrame(){
        setBounds(200,200,800,600);
        setBackground(Color.pink);
        setVisible(true);


    }

    //画笔
    @Override
    public void paint(Graphics g) {
        //画笔,需要有颜色,画笔可以画画
        g.setColor(Color.gray);
        g.drawOval(100,100,100,100); //圆圈
        g.fillOval(200,200,100,100); //实心圆
        g.setColor(Color.LIGHT_GRAY);
        g.fillRect(300,300,100,100);
        //养成习惯,画笔用完就恢复默认颜色(黑色)


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

输出展示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zQzp03J7-1658630497816)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220703205320262.png)]

2.8鼠标监听

目的:使用鼠标画画(单点)

代码展示:
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Iterator;

public class TestMouseListiener {
    public static void main(String[] args) {
            new MyFrame("画图");
    }
}


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

    ArrayList points;

    public MyFrame(String title){
        super(title);
        setBounds(200,200,800,600);

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

        //鼠标监听器,正对这个窗口
        this.addMouseListener(new MyMouseListener());
        setVisible(true);
        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.LIGHT_GRAY);
            g.fillOval(point.x,point.y,20,20);
        }
    }

    //添加一个点到界面上去
    public void addPaint(Point point){
            points.add(point);
    }


    //适配器模式
    private class MyMouseListener extends MouseAdapter {
        //鼠标动作:按下,弹起,按住不放
        @Override
        public void mousePressed(MouseEvent e) {
            MyFrame myFrame = (MyFrame) e.getSource();
            //这个是我们点击的时候,就会产生一个点,画
            //这个点就是鼠标的点:
            addPaint(new Point(e.getX(),e.getY()));

            //每次点击鼠标都需要重新画一遍
            repaint(); // 刷新

        }
    }


}

运行展示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1tOd3N1F-1658630497817)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220703214101274.png)]

2.9窗口监听

2.10键盘监听

blic 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.LIGHT_GRAY);
        g.fillOval(point.x,point.y,20,20);
    }
}

//添加一个点到界面上去
public void addPaint(Point point){
        points.add(point);
}


//适配器模式
private class MyMouseListener extends MouseAdapter {
    //鼠标动作:按下,弹起,按住不放
    @Override
    public void mousePressed(MouseEvent e) {
        MyFrame myFrame = (MyFrame) e.getSource();
        //这个是我们点击的时候,就会产生一个点,画
        //这个点就是鼠标的点:
        addPaint(new Point(e.getX(),e.getY()));

        //每次点击鼠标都需要重新画一遍
        repaint(); // 刷新

    }
}

}


运行展示:

[外链图片转存中...(img-1tOd3N1F-1658630497817)]







## 2.9窗口监听









## 2.10键盘监听

唉,typora又不能用了,只有这个了咯,唉~~~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值