文章目录
- 前言
- 一 GUI编程简介
- 二 AWT简介
- 2.1 组件(Component)和容器(Container)
- 2.2 Frame
- 2.2.1 演示1-创建一个窗口
- 2.2.2 演示2-多个窗口的创建
 
- 2.3 Panel
- 2.3.1 演示-Panel使用
 
 
- 三 布局管理
- 3.1 布局管理器之FlowLayout
- 3.1.1 FlowLayout简介
- 3.1.2 演示-FlowLayout使用
 
- 3.2 布局管理器之BorderLayout
- 3.2.1 BorderLayout简介
- 3.2.2 演示-BorderLayout使用
 
- 3.3 布局管理器之GridLayout
- 3.3.1 GridLayout简介
- 3.3.2 演示-GridLayout使用
 
- 3.4 布局管理器练习
- 3.4.1 实现的效果
- 3.4.2 实现的代码
 
- 3.5 布局管理器总结
- 四 事件监听
- 4.1 演示1-监听点击Button事件
- 4.2 演示2-多个按钮共享事件
 
- 五 TextField事件监听
- 5.1 TextField事件监听简介
- 5.2 演示1-实现密码框效果
- 5.3 演示2-实现简单的计算器
- 5.4 演示3-计算器2.0【组合】
- 5.5 演示4-计算器3.0【组合+内部类】
 
- 六 Graphics 类
- 6.1 Graphics简介
- 6.2 演示-paint的使用
 
- 七 鼠标事件适配器
- 7.1 鼠标事件适配器简介
- 7.2 演示-画点练习
 
- 八 window事件
- 8.1 WindowListener&WindowAdapter
- 8.2 演示-窗口的状态显示
 
- 九 键盘响应事件
- 9.1 KeyAdapter类简介
- 9.2 演示-键盘响应事件测试
 
前言
- 学自狂神,感谢您的付出和贡献!
- 刚开始的概念可以不太懂,先学会使用,然后有一定了解了,可以再回过头来看。
一 GUI编程简介
- GUI:Graphical User Interface 图形用户界面
- 两个常用技术 
  - AWT:Abstract Window Toolkit 抽象窗口工具包。
- Swing:用于开发Java应用程序用户界面的工具包。以抽象窗口工具包(AWT)为基础使跨平台应用程序可以使用任何可插拔的外观风格。Swing开发人员只用很少的代码就可以利用Swing丰富、灵活的功能和模块化组件来创建优雅的用户界面。 工具包中所有的包都是以swing作为名称。
 
- 虽然GUI因为运行环境成本过高,没有流行起来。但是作为java的学习者。有助于我们增强内功,为以后的学习奠定基础。
二 AWT简介
- AWT(Abstract Window Toolkit)包括了很多类和接口,用于Java Application的GUI(GraphicsUser Interface 图形用户界面)编程。
- GUI的各种元素(如:窗口,按钮,文本框等)由Java类来实现。
- 使用AWT所涉及的类一般在Java.AWT包及其子包中。
- Container和Component是AWT中的两个核心类。
  
- 所有的可以显示出来的图形元素都称为Component,Component代表了所有的可见的图形元素,Component里面有一种比较特殊的图形元素叫Container,Container(容器)在图形界面里面是一种可以容纳其它Component元素的一种容器,Container本身也是一种Component的,Container里面也可以容纳别的Container
- Container里面又分为Window和Pannel。 
  - Window是可以独立显示出来的,各种各样的应用程序的窗口都可以称为Window【这里不是windows操作系统】,Window作为一个应用程序窗口独立显示出来。
- Pannel也可以容纳其它的图形元素,但一般看不见Pannel,Pannel不能作为应用程序的独立窗口显示出来,Pannel要想显示出来就必须得把自己装入到Window里面才能显示出来。
 
- Pannel应用比较典型的就是Applet(JAVA的页面小应用程序),现在基本上已经不用了,AJAX和JAVASCRIPT完全取代了它的应用。
- Window本身又可以分为Frame和Dialog 
  - Frame就是我们平时看到的一般的窗口
- Dialog则是那些需要用户进行了某些操作(如点击某个下拉菜单的项)才出现的对话框,这种对话框就是Dialog。
 
2.1 组件(Component)和容器(Container)
- Java的图形用户界面的最基本组成部分是Component,Component类和其子类的对象用来描述以图形化的方式显示再屏幕上并能与用户进行交互的GUI元素
- 一般的Component对象不能独立地显示出来,需要放在Container对象中。
- Container是Component的子类,Container子类对象可以容纳别的Component对象。
- Container对象使用 a d d ( ) add() add()向其中添加Component对象。
- 两种常用的Container: 
  - WIndow:其对象表示自由停泊的顶级窗口。
- Panel:其对象者可作为容纳它的Component对象,但不能独立存在,必须添加到其它Container中(如:Window)
 
2.2 Frame
- Frame是WIndow的子类,由Frame或者子类创建的对象为一个窗口。
| 方法 | 说明 | 
|---|---|
| 构造方法 Frame() | 构造的新实例 Frame初始时不可见 | 
| 构造方法 Frame(String title)  | 构造一个新的,最初不可见的 Frame对象,其中包含指定的标题。 | 
| setResizable(boolean resizable) | 设置该框架是否可以由用户调整大小。 | 
| setTitle(String title) | 将此框架的标题设置为指定的字符串。 | 
| setBounds(int x,int y,int width,int height) | 设置窗口位置和大小,x,y是左上角坐标 | 
| setSize(int width,int height) | 设置窗口大小 | 
| setLocation(int x,int y) | 设置位置,x,y是左上角坐标 | 
| setBackground(Color c) | 设置背景颜色,参数为Color对象 | 
| setVisible(boolean b) | 设置是否可见 | 
| setTitile(String name)String getTitle() | 设置和获取窗口的标题 | 
2.2.1 演示1-创建一个窗口
import java.awt.*;
/**
 * @author 缘友一世
 * date 2022/12/28-21:22
 */
//gui
public class TestFrame01 {
    public static void main(String[] args) {
        Frame frame = new Frame("hello java GUI");
        //设置可见性
        frame.setVisible(true);
        //设置窗口大小
        frame.setSize(500,500);
        //设置弹出的初始位置
        frame.setLocation(300,300);
        //设置背景颜色
        frame.setBackground(new Color(41, 71, 224, 255));
        //设置固定大小 默认是true
        frame.setResizable(false);
    }
}

2.2.2 演示2-多个窗口的创建
/**
 * @author 缘友一世
 * date 2022/12/28-21:38
 */
public class TestFrame02 {
    public static void main(String[] args) {
        //展示多个窗口
        MyFrame myFrame01 = new MyFrame(100, 100, 300, 300, Color.black);
        MyFrame myFrame02 = new MyFrame(400, 100, 300, 300, Color.red);
        MyFrame myFrame03 = new MyFrame(100, 400, 300, 300, Color.yellow);
        MyFrame myFrame04 = new MyFrame(400, 400, 300, 300, Color.blue);
    }
}
class MyFrame extends Frame {
    static int id=0;
    public MyFrame(int x,int y,int height,int width,Color color)  {
        super("MyFrame"+(++id));
        //setBound=setLocation+setSize
        setBounds(x,y,width,height);
        setVisible(true);
        setBackground(color);
    }
}

2.3 Panel
- Panel对象可以看成可以容纳Component的空间
- Panel对象可以拥有自己的布局管理器
- Panel类拥有从其父类维承来的
| 方法 | 说明 | 
|---|---|
| 构造方法 Panel() | 使用默认的FlowLayout类布局管理器初始化 | 
| 构造方法 Panel(LayoutManager layout) | 使用指定的布局管理器初始化 | 
| setBounds(int x,Int y,Int width,int height) | 设置大小和初始位置【相较于Frame】 | 
| setSize(int width,int height) | 设置大小 | 
| setLocation(int x,int y) | 设置位置 | 
| setBackground(Color c) | 设置背景颜色 | 
| setLayout(Layout Managermgr) | 设置布局 | 
2.3.1 演示-Panel使用
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author 缘友一世
 * date 2022/12/28-21:44
 */
//Panel 可以看作一个空间,但不是单独存在
public class TestPanel01 {
    public static void main(String[] args) {
        Frame frame = new Frame();
        Panel panel = new Panel();
        //设置布局 取消默认置顶的设置
        frame.setLayout(null);
        //坐标
        frame.setBounds(300,300,500,500);
        frame.setBackground(new Color(130, 192, 199));
        //Panel 设置坐标,相对于frame
        panel.setBounds(30,30,100,200);
        panel.setBackground(Color.green);
        frame.add(panel);
        frame.setVisible(true);
        //监听事件,监听窗口关闭事件
        //适配器模式
        frame.addWindowListener(new WindowAdapter() {
            //窗口点击关闭时需要做的事情
            @Override
            public void windowClosing(WindowEvent e) {
                //结束程序
                System.exit(0);
            }
        });
    }
}

三 布局管理
- Java语言中,提供了布局管理器类的对象可以管理 
  - 管理Component在Cortainer中的布局,不必直接设置Component位置和大小
- 每个Container都有一个布局管理器对象,当容器需要对某个组件进行定位或判断其大小尺寸时,就会调用其对应的布局管理器,调用Container的setLayout方法改变其布局管理器对象
 
- Awt提供了5种布局管理器类 
  - FlowLayout
- BorderLayout
- GridLayou
- CardLayout
- GridBagLayout
 
3.1 布局管理器之FlowLayout
3.1.1 FlowLayout简介
-  FlowLayout布局管理器对组件从左到右,进行逐行定位,行满换行。 
-  不改变组件的大小,按照组件原有尺寸显示组件,可设置不同组件间距,行距以及对齐方式。 
-  FlowLayout默认的对齐方式是居中。 
-  FlowLayout构造方法 
| 方法 | 说明 | 
|---|---|
| new FlowLayout(FlowLayout.RIGHT,int x,int y) | 右对齐,组件之间水平间距x个像素,垂直间距y个像素 | 
| new FlowLayout(FlowLayout.LEFT) | 左对齐,水平和垂直间距为缺省值(5) | 
| new FlowLayout() | 使用缺省的居中对齐方式,水平和垂直间距为缺省值 | 
3.1.2 演示-FlowLayout使用
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author 缘友一世
 * date 2022/12/28-22:07
 */
public class TestFlowLayout01 {
    public static void main(String[] args) {
        Frame frame = new Frame();
        Button button01 = new Button("button01");
        Button button02 = new Button("button02");
        Button button03 = new Button("button03");
        //设置流式布局
        frame.setLayout(new FlowLayout(FlowLayout.CENTER));
        frame.setSize(300,300);
        frame.add(button01);
        frame.add(button02);
        frame.add(button03);
        frame.setVisible(true);
        //监听事件,监听窗口关闭事件
        //适配器模式
        frame.addWindowListener(new WindowAdapter() {
            //窗口点击关闭时需要做的事情
            @Override
            public void windowClosing(WindowEvent e) {
                //结束程序
                System.exit(0);
            }
        });
    }
}

3.2 布局管理器之BorderLayout
3.2.1 BorderLayout简介
- BorderLayout是Frame类的默认布局管理器
- BorderLayout将整个容器的布局划分成:东(EAST)、西(WEST)、南(SOUTH)、北(NORTH)、中(CENTER)五个区域,组件只能被添加到指定的区域。
- 如果不指定组件的加入部位,则默认加入到CENTER区。
- 每个区域只能加入一个组件,如加入多个,则先前加入的会被覆盖。
- BorderLayout型布局容器尺寸缩放原则: 
  - 南、北两个区域在水平方向缩放。
- 东、西两个区域在垂直方向缩放。
- 中间可在两个方向缩放。
 
3.2.2 演示-BorderLayout使用
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author 缘友一世
 * date 2022/12/28-22:12
 */
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(300,300);
        frame.setVisible(true);
        //监听事件,监听窗口关闭事件
        //适配器模式
        frame.addWindowListener(new WindowAdapter() {
            //窗口点击关闭时需要做的事情
            @Override
            public void windowClosing(WindowEvent e) {
                //结束程序
                System.exit(0);
            }
        });
    }
}

3.3 布局管理器之GridLayout
3.3.1 GridLayout简介
- GridLayout型布局管理器将空间划分成规则的矩形网格,每个单元格区域大小相等。组件被添加到每个单元格中,先从左到右添满一行后换行,再从上到下。
- 在GridLayout构造方法中指定分割的行数和列数
3.3.2 演示-GridLayout使用
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author 缘友一世
 * date 2022/12/28-22:18
 */
public class TestGridLayout {
    public static void main(String[] args) {
        Frame frame = new Frame("TestGridLayout");
        Button button01 = new Button("button01");
        Button button02 = new Button("button02");
        Button button03 = new Button("button03");
        Button button04 = new Button("button04");
        Button button05 = new Button("button05");
        Button button06 = new Button("button06");
        frame.setLayout(new GridLayout(3,2));
        frame.add(button01);
        frame.add(button02);
        frame.add(button03);
        frame.add(button04);
        frame.add(button05);
        frame.add(button06);
        frame.pack();
        frame.setSize(300,300);
        frame.setVisible(true);
        //监听事件,监听窗口关闭事件
        //适配器模式
        frame.addWindowListener(new WindowAdapter() {
            //窗口点击关闭时需要做的事情
            @Override
            public void windowClosing(WindowEvent e) {
                //结束程序
                System.exit(0);
            }
        });
    }
}

3.4 布局管理器练习
3.4.1 实现的效果

3.4.2 实现的代码
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author 缘友一世
 * date 2022/12/28-22:32
 */
public class TestDemo {
    public static void main(String[] args) {
        Frame frame = new Frame();
        frame.setSize(400,300);
        frame.setLocation(300,300);
        frame.setBackground(Color.GREEN);
        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, 2));
        p1.add(new Button("East-1"),BorderLayout.EAST);
        p1.add(new Button("West-1"),BorderLayout.WEST);
        p2.add(new Button("center-1"));
        p2.add(new Button("center-2"));
        p1.add(p2,BorderLayout.CENTER);
        p3.add(new Button("East-2"),BorderLayout.EAST);
        p3.add(new Button("West-2"),BorderLayout.WEST);
        for (int i = 1; i <= 4; i++) {
            p4.add(new Button("center2-"+i));
        }
        p3.add(p4,BorderLayout.CENTER);
        frame.add(p1);
        frame.add(p3);
        frame.setSize(300,300);
        frame.setVisible(true);
        //监听事件,监听窗口关闭事件
        //适配器模式
        frame.addWindowListener(new WindowAdapter() {
            //窗口点击关闭时需要做的事情
            @Override
            public void windowClosing(WindowEvent e) {
                //结束程序
                System.exit(0);
            }
        });
    }
}
3.5 布局管理器总结

- Frame是一个顶级窗口,Frame的缺省布局管理器为BorderLayout
- Panel无法单独显示,必须添加到某个容器中。
- Panel的缺省布局管理器为FlowLayout
- 当把Panel作为一个组件添加到某个容器中后,该Panel仍然可以有自己的布局管理器。
- 使用布局管理器时,布局管理器负责各个组件的大小和位置,因此用户无法在这种情况下设置组件大小和位置属性,如果试图使用Java语言提供的setLocation(),setSize(),setBounds()等方法,则都会被布局管理器覆盖。
- 如果用户确实需要亲自设置组件大小或位置,则应取消该容器的布局管理器,方法为:setLayout(null)
四 事件监听

4.1 演示1-监听点击Button事件
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author 缘友一世
 * date 2022/12/29-9:33
 */
public class TestActionEvent {
    public static void main(String[] args) {
        Frame frame = new Frame("TestActionEvent");
        //设置布局 取消默认置顶的设置
        frame.setLayout(null);
        frame.setBackground(Color.CYAN);
        frame.setBounds(300,300,800,800);
        Button button = new Button("button");
        button.setBackground(Color.orange);
        button.setBounds(300,300,100,100);
        //assActionListener需要一个ActionListener,所以我们需要一个ActionListener
        button.addActionListener(new MyActionListener());
        frame.add(button,BorderLayout.CENTER);
        frame.setVisible(true);
        windowClose(frame);
    }
    public 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("开玩笑了!");
    }
}

4.2 演示2-多个按钮共享事件
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author 缘友一世
 * date 2022/12/29-9:53
 */
public class TestActionTwo {
    public static void main(String[] args) {
        Frame frame = new Frame("多按钮共享一个事件");
        Button button01 = new Button("button01-start");
        Button button02 = new Button("button-2");
        //可以显式定义触发返回的命令,如果不显式定义,则会有默认的值即button的文本内容
        //多个按钮只写一个监听类
        button02.setActionCommand("button02-stop");
        MyMonitor myMonitor = new MyMonitor();
        button01.addActionListener(myMonitor);
        button02.addActionListener(myMonitor);
        frame.add(button01,BorderLayout.NORTH);
        frame.add(button02,BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);
        windowClose(frame);
    }
    public static void windowClose(Frame frame) {
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}
class MyMonitor implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getActionCommand().equals("button01-start")) {
            System.out.println(">>>"+e.getActionCommand());
        }else if(e.getActionCommand().equals("button02-stop")) {
            System.out.println(">>>"+e.getActionCommand());
        }
    }
}

五 TextField事件监听
5.1 TextField事件监听简介
- TextField对象可能发生Action(光标在文本框内敲回车)事件。与该事件对应
 的事件类是java.awt.event.ActionEvent。用来处理ActionEvent事件是实现了java.awt.event.ActionListener接口的类的对象。
- ActionListener接口定义有方法:public void actionPerformed(ActionEvent e)
- 实现该接口的类要在该方法中添加处理该事件(Action)的语句。
- 使用addActionListener(ActionListener I)方法为TextField对象注册一个ActlonListener对象,当TextFleld对象发生Action事件时,会生成一个ActionEvent对象,该对象作为参数传递给ActionListener对象的actlonPerformer方法在方法中可以获取该对象的信息,并做相应的处理。
5.2 演示1-实现密码框效果
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author 缘友一世
 * date 2022/12/29-10:28
 */
public class TestTextField {
    public static void main(String[] args) {
        close( new MyFrame());
    }
    public static void close(Frame frame) {
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}
class MyFrame extends Frame {
    public MyFrame() {
        TextField textField = new TextField();
        //调用Frame的add方法
        add(textField);
        //设置替换编码
        textField.setEchoChar('*');
        setVisible(true);
        pack();
        //按下回车键就会触发,输入框的事件
        textField.addActionListener(new MyActionListener2());
    }
}
/**
 * 监听文本输入框的文字
 */
class MyActionListener2 implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        //获得一些资源返回一个对象。
        TextField textField= (TextField) e.getSource();
        System.out.println(textField.getText());
        //回车之后,设置文本框内容为空
        textField.setText("");
    }
}

5.3 演示2-实现简单的计算器
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author 缘友一世
 * date 2022/12/29-10:51
 */
public class TestCalculator {
    public static void main(String[] args) {
        Calculator.close(new Calculator());
    }
}
class Calculator extends Frame{
    public Calculator() {
        //第一步 确定组件
        //3个文本框
        TextField num1 = new TextField(10);
        TextField num2 = new TextField(10);
        TextField num3 = new TextField(20);
        //2个标签
        Label label1 = new Label("+");
        Label label2 = new Label("=");
        //2个按钮
        Button enter = new Button("enter");
        Button clear = new Button("clear");
        //第二步 布局 流式布局 依次放入组件
        setLayout(new FlowLayout());
        add(num1);
        add(label1);
        add(num2);
        add(label2);
        add(num3);
        add(enter);
        add(clear);
        setBounds(300,300,600,600);
        setVisible(true);
        //第三步 添加监听
        enter.addActionListener(new MyCalculatorListener(num1,num2,num3));
        clear.addActionListener(new MyCalculatorListener(num1,num2,num3));
    }
    public static void close(Frame frame) {
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}
class MyCalculatorListener implements ActionListener {
    private TextField num1,num2,num3;
    public MyCalculatorListener() {
    }
    public MyCalculatorListener(TextField num1, TextField num2, TextField num3) {
        this.num1 = num1;
        this.num2 = num2;
        this.num3 = num3;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        //获得加数和被加数
        int x = Integer.parseInt(num1.getText());
        int y = Integer.parseInt(num2.getText());
        //将运算的结果放入文本框
        num3.setText(""+(x+y));
        if(e.getActionCommand().equals("clear")) {
            num1.setText("");
            num2.setText("");
            num3.setText("");
        }
    }
}

5.4 演示3-计算器2.0【组合】
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author 缘友一世
 * date 2022/12/29-10:51
 */
//组合
public class TestCalculator02 {
    public static void main(String[] args) {
        Calculator02 calculator = new Calculator02();
        calculator.LoadFrame();
        Calculator02.close(calculator);
       ;
    }
}
//计算器类
class Calculator02 extends Frame{
    //属性
   TextField num1,num2,num3;
   //方法
    public void LoadFrame() {
        //第一步 确定组件
        //3个文本框
        num1 = new TextField(10);
        num2 = new TextField(10);
        num3 = new TextField(20);
        //2个标签
        Label label1 = new Label("+");
        Label label2 = new Label("=");
        //2个按钮
        Button enter = new Button("enter");
        Button clear = new Button("clear");
        //第二步 布局 流式布局 依次放入组件
        setLayout(new FlowLayout());
        add(num1);
        add(label1);
        add(num2);
        add(label2);
        add(num3);
        add(enter);
        add(clear);
        setBounds(300,300,600,600);
        setVisible(true);
        //第三步 添加监听
        enter.addActionListener(new MyCalculatorListener02(this));
        clear.addActionListener(new MyCalculatorListener02(this));
    }
    public static void close(Frame frame) {
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}
class MyCalculatorListener02 implements ActionListener {
    //组合
    Calculator02 calculator=null;
    public MyCalculatorListener02(Calculator02 calculator) {
        this.calculator=calculator;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        //获得加数和被加数
        int x = Integer.parseInt(calculator.num1.getText());
        int y = Integer.parseInt(calculator.num2.getText());
        //将运算的结果放入文本框
        calculator.num3.setText(""+(x+y));
        if(e.getActionCommand().equals("clear")) {
            calculator.num1.setText("");
            calculator.num2.setText("");
            calculator.num3.setText("");
        }
    }
}

5.5 演示4-计算器3.0【组合+内部类】
- 优势 
  - 可以方便的访问包装类的成员。
- 可以更清楚的组织逻辑,防止不应该被其他类 访问的类 进行访问。
 
- 使用时机: 
  - 该类不允许或不需要其它类进行访问时使用。
 
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author 缘友一世
 * date 2022/12/29-10:51
 */
//组合+内部类
public class TestCalculator03 {
    public static void main(String[] args) {
        Calculator02 calculator = new Calculator02();
        calculator.LoadFrame();
        Calculator02.close(calculator);
       ;
    }
}
//计算器类
class Calculator03 extends Frame{
    //属性
   TextField num1,num2,num3;
   //方法
    public void LoadFrame() {
        //第一步 确定组件
        //3个文本框
        num1 = new TextField(10);
        num2 = new TextField(10);
        num3 = new TextField(20);
        //2个标签
        Label label1 = new Label("+");
        Label label2 = new Label("=");
        //2个按钮
        Button enter = new Button("enter");
        Button clear = new Button("clear");
        //第二步 布局 流式布局 依次放入组件
        setLayout(new FlowLayout());
        add(num1);
        add(label1);
        add(num2);
        add(label2);
        add(num3);
        add(enter);
        add(clear);
        setBounds(300,300,600,600);
        setVisible(true);
        //第三步 添加监听
        enter.addActionListener(new MyCalculatorListener03());
        clear.addActionListener(new MyCalculatorListener03());
    }
    public static void close(Frame frame) {
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
    private class MyCalculatorListener03 implements ActionListener {
        //组合
        @Override
        public void actionPerformed(ActionEvent e) {
            //获得加数和被加数
            int x = Integer.parseInt(num1.getText());
            int y = Integer.parseInt(num2.getText());
            //将运算的结果放入文本框
            num3.setText(""+(x+y));
            if(e.getActionCommand().equals("clear")) {
                num1.setText("");
                num2.setText("");
                num3.setText("");
            }
        }
    }
}

六 Graphics 类
6.1 Graphics简介
- 每个Component都有一个paint(Graphics g)用于实现绘图目的,每次重画该Component时都自动调用paint方法。
  
6.2 演示-paint的使用
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author 缘友一世
 * date 2022/12/29-14:16
 */
public class TestPaint {
    public static void main(String[] args) {
        MyPaint myPaint = new MyPaint();
        myPaint.loadFrame();
        windowClose(myPaint);
    }
    public static void windowClose(Frame frame) {
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}
class MyPaint extends Frame{
    public void loadFrame() {
        setBounds(200,200,600,800);
        setVisible(true);
        setBackground(Color.GRAY);
    }
    @Override
    public void paint(Graphics g) {
        //画笔用完,还原颜色
        g.setColor(Color.green);
        g.drawOval(100,100,100,100);
        g.fillOval(300,300,50,50);
        g.fill3DRect(400,400,100,100,true);
    }
}

七 鼠标事件适配器
7.1 鼠标事件适配器简介
- 抽象类java.awt.event.MouseAdapter实现了MouseListener接口,可以使用其子类作为
 MouseEvent的监听器,只要重写其相应的方法即可。
- 对于其他的监听器,也有对应的适配器。
- 适用适配器可以避免监听器定义没有必要的空方法。
7.2 演示-画点练习
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Iterator;
/**
 * @author 缘友一世
 * date 2022/12/29-15:11
 */
//鼠标监听
public class TestMouseListener {
    public static void main(String[] args) {
        MyFrame.close(new MyFrame("TestMouseListener"));
    }
}
//画板
class MyFrame extends Frame {
    ArrayList points;
    public MyFrame(String title) {
        super(title);
        setBounds(200,200,600,600);
        setVisible(true);
        //创建集合存放鼠标点击的点
        points=new ArrayList<>();
        //设置鼠标监听器
        this.addMouseListener(new MyMouseListener());
    }
    //单独的方法将点存入集合
    private void addPaint(Point point) {
        points.add(point);
    }
    //监听鼠标
    private class MyMouseListener extends MouseAdapter{
        @Override
        public void mousePressed(MouseEvent e) {
            //通过getSource获得MyFrame类的方法和属性
            MyFrame myFrame= (MyFrame) e.getSource();
            //调用addPaint方法,将鼠标点击的坐标存入集合
            myFrame.addPaint(new Point(e.getX(),e.getY()));
            //每次点击鼠标都重新画一遍
            myFrame.repaint();
        }
    }
    //画笔画画
    @Override
    public void paint(Graphics g) {
        //真正的画画操作 使用迭代器
        Iterator iterator = points.iterator();
        while(iterator.hasNext()) {
            //iterator.next(); 返回的是Object类型 需要强制转化
            Point point= (Point) iterator.next();
            g.setColor(Color.black);
            g.fillOval(point.x,point.y,10,10);
        }
    }
    public static void close(Frame frame) {
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

八 window事件
8.1 WindowListener&WindowAdapter
- Window事件所对应的事件类为WindowEvent,所对应的事件监听接口为
 WindowListener
- 与WindowLjstener对应的适配器为WindowAdapter
- 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) {}
8.2 演示-窗口的状态显示
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author 缘友一世
 * date 2022/12/29-15:45
 */
//窗口监听
public class TestWindow {
    public static void main(String[] args) {
        new WindowFrame();
    }
}
class WindowFrame extends Frame{
    public WindowFrame() {
        super("窗口打开了!");
        setBounds(200,200,800,800);
        setBackground(Color.pink);
        setVisible(true);
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("窗口被关闭了!");
                System.exit(0);
            }
            @Override
            public void windowActivated(WindowEvent e) {
                WindowFrame windowFrame= (WindowFrame) e.getSource();
                windowFrame.setTitle("窗口被激活!");
                System.out.println("窗口被激活了!");
            }
            @Override
            public void windowDeactivated(WindowEvent e) {
                System.out.println("窗口失效了!");
            }
        });
    }
}

九 键盘响应事件
9.1 KeyAdapter类简介
- 键盘适配器KeyAdapter类继承了KeyListener接口,只需要重写需要用到的方法即可,这种做法比直接实现KeyListener接口要简单方便。
9.2 演示-键盘响应事件测试
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author 缘友一世
 * date 2022/12/29-16:01
 */
public class TestKeyListener {
    public static void main(String[] args) {
        close(new KeyFrame());
    }
    public static void close(Frame frame) {
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}
class KeyFrame extends Frame{
    public KeyFrame() {
        super("KeyListener");
        setBounds(50,50,300,300);
        setVisible(true);
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();
                if (keyCode==KeyEvent.VK_UP) {
                    System.out.println("点击了上键位");
                }
            }
        });
    }
}














![【WSL】[01] windows subsytem linux 配置和使用 - ubuntu GUI安装](https://img-blog.csdnimg.cn/d92b42e3f789407289d57d08aa2ce5a4.png)





