AWT

2.1、AWT介绍

  • 其包含了很多的类和接口。

  • 元素:窗口,按钮,文本框。

  • Java.awt:

在这里插入图片描述

2.2、组件和容器

1、Frame

代码:

package com.edwin.lession01;
import java.awt.*;
//GUI第一个界面
/**
 * @author EdwinD
 * @create 2020.08.16 上午 10:03
 * @desc 
 **/
public class TextFrame1 {
    public static void main(String[] args) {
//        Frame,JDK,查看源码
        Frame frame = new Frame("My First Java 图形界面");

//        设置窗口可见性,无关于窗口大小.
        frame.setVisible(true);

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

//        设置背景颜色
        frame.setBackground(new Color(77,77,77));

//        设置初始位置
        frame.setLocation(777,77);

//        控制窗口大小是否可改变,默认为True,即可以改变。
        frame.setResizable(false);
    }
}

输出效果:

在这里插入图片描述

缺点:

此时的窗口无法关闭,只能通过IDEA停止代码,才可以关闭整个窗口。

封装后多窗口输出:

代码2.0:

package com.edwin.lession01;
import java.awt.*;
public class TextFrame2 {
    public static void main(String[] args) {
//        展示多个窗口new
        new MyFrame(77, 77, 350, 350, Color.blue);
        new MyFrame(77, 477, 350, 350, Color.red);
        new MyFrame(477, 77, 350, 350, Color.green);
        new MyFrame(477, 477, 350, 350, Color.gray);

    }

    static class MyFrame extends Frame{
        static int id = 0;//可能存在多个窗口,在此创造一个计数器.

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

        }
    }
}

输出2.0:

在这里插入图片描述

2、Panel

解决了关闭的小问题。

**注:**Frame在add一个Panel的时候,使用的是frame.add(Component comp),这是因为Panel类extends了Container,而Container类extends了Component。

在这里插入图片描述

监听器小剧透
  • 添加监听事件,使用窗口上方的小叉叉进行关闭.调用System.exit(0).

对于目前所编写的面板,窗口,都是无法直接通过点击上方的小叉进行关闭的,这里需要用到一些后面的监听器的内容进行功能的实现。

1.常规情况下的监听器:

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

    }
});

但是这里使用到的监听器是全部的,太过于全面,我们只需要里面的部分监听器进行工作即可。因此,我们可以尝试调用其子类:

在这里插入图片描述

frame.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent e) {
//      结束程序
        System.exit(0);
    }
});
  • System.exit(0):正常关闭;System.exit(1):异常关闭.其关闭对象是Java程序。

效果:
在这里插入图片描述

2.3、布局管理器

  • 流式布局

代码:

package com.edwin.lession01;
import java.awt.*;
/**
 * @author EdwinD
 * @create 2020.08.16 下午 09:29
 * @desc
 **/
public class TextFlowLayout {
    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(277, 277);

        frame.add(button1);
        frame.add(button2);
        frame.add(button3);

        frame.setVisible(true);
    }
}

效果:

在这里插入图片描述

不论如何拖动,三个按钮都会是居中显示。

  • 东西南北中布局

布局思想原理:

在这里插入图片描述

代码:

package com.edwin.lession01;
import java.awt.*;
/**
 * @author EdwinD
 * @create 2020.08.16 下午 09:58
 * @desc
 **/
public class TextBorderLayout {
    public static void main(String[] args) {
        Frame frame = new Frame("TextBorderLayout");

        Button east = new Button("East");
        Button west = new Button("West");
        Button north = new Button("North");
        Button south = new Button("South");
        Button center = new Button("Center");

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

        frame.setSize(277, 277);
        frame.setVisible(true);
    }
}

输出效果:

在这里插入图片描述

  • 表格布局

代码:

package com.edwin.lession01;
import java.awt.*;
/**
 * @author EdwinD
 * @create 2020.08.16 下午 10:12
 * @desc
 **/
public class TextGridLayout {
    public static void main(String[] args) {
        Frame frame = new Frame("TextGridLayout");
        Button but1 = new Button("but1");
        Button but2 = new Button("but2");
        Button but3 = new Button("but3");
        Button but4 = new Button("but4");
        Button but5 = new Button("but5");
        Button but6 = new Button("but6");
        Button but7 = new Button("but7");

        frame.setLayout(new GridLayout(3, 3));
        
        frame.add(but1);
        frame.add(but2);
        frame.add(but3);
        frame.add(but4);
        frame.add(but5);
        frame.add(but6);
        frame.add(but7);

        frame.setSize(277, 277);
        frame.setVisible(true);
    }
}

输出:

在这里插入图片描述

2.4、课堂练习

package com.edwin.lession01;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author EdwinD
 * @create 2020.08.16 下午 10:21
 * @desc
 **/
public class TextLayout {
    public static void main(String[] args) {
        Frame frame = new Frame("TextLayout");

        Panel panel1 = new Panel(new BorderLayout());
        Panel panel2 = new Panel(new GridLayout(2,1));
        Panel panel3 = new Panel(new BorderLayout());
        Panel panel4 = new Panel(new GridLayout(2,2));

        frame.setVisible(true);
        frame.setBackground(Color.blue);
        frame.setBounds(500, 500, 400, 300);
        frame.setResizable(false);
        frame.setLayout(new GridLayout(2,1));

        panel1.add(new Button("WEST-1"),BorderLayout.WEST);
        panel1.add(new Button("EAST-1"), BorderLayout.EAST);
        panel2.add(new Button("Cen1"));
        panel2.add(new Button("Cen2"));
        panel1.add(panel2,BorderLayout.CENTER);

        panel3.add(new Button("WEST-2"),BorderLayout.WEST);
        panel3.add(new Button("EAST-2"), BorderLayout.EAST);

        for (int i = 0; i < 4; i++) {
            panel4.add(new Button("for-" + i));
        }
        panel3.add(panel4, BorderLayout.CENTER);

        frame.add(panel1);
        frame.add(panel3);

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

输出:

在这里插入图片描述

小结

(1)Frame是一个顶级窗口。

(2)Panel无法单独显示,必须添加到某一个容器中。

(3)布局管理器:

​ - 流式布局

​ - 东西南北中布局

​ - 表格布局

(4)每一个元素的大小,定位,背景色,可见性以及是否使用监听。

2.5、事件监听

所谓事件监听,就是指当某个事情发生的时候,应该做出何种反应。

1.单一监听

代码:

package com.edwin.lession02;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author EdwinD
 * @create 2020.08.17 下午 01:30
 * @desc
 **/
public class TextActionEvent<implement> {
    public static void main(String[] args) {
//        初始化,目标:按下按钮,发生一些神奇的事情。
        Frame frame = new Frame("TextActionEvent");
        Button button = new Button();

//        因为,addActionListener需要一个ActionListener,所以,我们自己要创建一个ActionListener
        MyActionListener myActionListener = new MyActionListener();
        button.addActionListener(myActionListener);

        frame.setVisible(true);
        frame.setBounds(577, 577, 377, 377);
        frame.add(button);

        //关闭窗口
        windowClose(frame);
    }

    //窗口关闭事件
    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("Push the Button.");
    }
}

输出:

在这里插入图片描述

2.多按钮同时监听

代码:

package com.edwin.lession02;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author EdwinD
 * @create 2020.08.17 下午 01:47
 * @desc
 **/
public class TextActionTwo {
    public static void main(String[] args) {
//        两个按钮,实现同一个监听.
//        开始 & 停止
        Frame frame = new Frame("Start-Stop");
        Button button1 = new Button("Start");
        Button button2 = new Button("Stop");

        frame.pack();
        frame.setVisible(true);
        frame.setBounds(377, 377, 277, 277);

//        可以显示的定义触发会返回的命令,如果不显示定义,则会走默认的值!
//        可以多个按钮只写一个监听类
        button1.setActionCommand("Start-Button");
        button2.setActionCommand("Stop-Button");

        MyActionListener2 myActionListener2 = new MyActionListener2();
        button1.addActionListener(myActionListener2);
        button2.addActionListener(myActionListener2);

        frame.add(button1, BorderLayout.NORTH);
        frame.add(button2, BorderLayout.SOUTH);

        windowClose(frame);
    }

    private static void windowClose(Frame frame) {
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}
class MyActionListener2 implements ActionListener{
//    e.getActionCommand()获得按钮信息.
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("按钮被点击了,消息内容为:"+e.getActionCommand());
    }
}

输出:

在这里插入图片描述

2.6、输入框 TextFile 及监听

此功能用于类似于qq聊天的交流输入框,可以实现在肯本框中输入内容,在后台控制器中显示。

代码:

package com.edwin.lession02;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author EdwinD
 * @create 2020.08.17 下午 05:31
 * @desc
 **/
public class TextTextFile {
    public static void main(String[] args) {
//        启动
        MyFrame myFrame = new MyFrame();
        windowClose(myFrame);
    }

    private static void windowClose(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();
        add(textField);

//      监听此文本框的输入文字,
        MyActionListener3 myActionListener3 = new MyActionListener3();

//        按下Enter就会触发这个输入框的事件
        textField.addActionListener(myActionListener3);

//      设置替换编码,输入的内容被 setEchoChar('这里');的"这里"代替.
        textField.setEchoChar('!');

        setVisible(true);
        setBounds(377,377,277,277);

    }
}

class MyActionListener3 implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        TextField textFile = (TextField) e.getSource();
        System.out.println("输入框显示的为:\n"+textFile.getText());
//        设置清空的反馈.每次回车后,会自动用""代替原来输入的内容,这里不可以用null,
//        因为null是一个对象,而""中的空字符是一个字符串
        textFile.setText("");
    }
}

输出效果:

在这里插入图片描述

2.7、组合+内部类复习—>计算器

践行OOP原则:组合大于继承。

class A extends B{
    //正常继承,A有B的所有功能。
}
class A{
    public B b;
    //这就是组合的模式,可以减小耦合.
}

老式代码:

package com.edwin.lession02;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author EdwinD
 * @create 2020.08.18 上午 07:28
 * @desc
 **/
public class TextCalculator {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        windowClose(calculator);
    }

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

//计算器类
class Calculator extends Frame {
    public Calculator() {
//        三个文本框
        TextField num1 = new TextField(10);//字符数
        TextField num2 = new TextField(10);//字符数
        TextField num3 = new TextField(20);//字符数
//        一个按钮
        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);

        setVisible(true);
        pack();
        setBounds(377,377,300,200);
    }
}

//监听器类
class MyCalculatorListener implements ActionListener {
    private final 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.setText(""+(n1+n2));
//        3.清理前两个框中的数字
        num1.setText("");
        num2.setText("");
    }
}

输出:

在这里插入图片描述

新式·面向对象·代码:

package com.edwin.lession02;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author EdwinD
 * @create 2020.08.18 上午 07:28
 * @desc
 **/
public class TextCalculatorNew {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();

        windowClose(calculator);
    }

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

//计算器类
class Calculator2 extends Frame {
    TextField num1, num2, num3;
    public Calculator2() {
//        三个文本框
//        一个按钮
//        一个标签
        TextField num1 = new TextField(10);//字符数
        TextField num2 = new TextField(10);//字符数
        TextField num3 = new TextField(20);//字符数
        Label label = new Label("+");
        Button button = new Button("=");
//        监听事件
        button.addActionListener(new MyCalculatorListener2(this));
//        布局
        setLayout(new FlowLayout());
        add(num1);
        add(label);
        add(num2);
        add(button);
        add(num3);

        setVisible(true);
        pack();
        setBounds(377, 377, 300, 200);
    }
}

//监听器类
class MyCalculatorListener2 implements ActionListener {
    Calculator2 calculator2 = null;

    public MyCalculatorListener2(Calculator2 calculator) {
        this.calculator2 = calculator;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
//        1.获得加数,被加数
        int n1 = Integer.parseInt(calculator2.num1.getText());
        int n2 = Integer.parseInt(calculator2.num2.getText());
//        2.将两个值加法运算后,放到第三个框中,
        calculator2.num3.setText("" + (n1 + n2));
//        3.清理前两个框中的数字
        calculator2.num1.setText("");
        calculator2.num2.setText("");
    }
}

输出:

在这里插入图片描述

2.8、画笔

代码:

package com.edwin.lession03;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author EdwinD
 * @create 2020.08.18 上午 11:14
 * @desc
 **/
public class TextPaint {
    public static void main(String[] args) {
        MyPaint myPaint = new MyPaint();
        myPaint.loadFrame();
        windowClose(myPaint);
    }

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

class MyPaint extends Frame {
    @Override
    public void paint(Graphics g) {
//        画笔,颜料,画啥.
        g.setColor(Color.blue);
//        空心的圆
        g.drawOval(100, 100, 100, 100);
//        实心的圆
        g.fillOval(100, 300, 100, 100);

        g.setColor(Color.GRAY);
        g.fillRect(300, 300, 100, 100);

//        养成习惯:画笔用完之后,将其还原至最初的颜色.
    }

    public void loadFrame() {
        setBounds(277, 277, 677, 577);
        setVisible(true);
    }

输出:

在这里插入图片描述

2.9、窗口监听

Eg1,普通使用举例

代码:

package com.edwin.lession03;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author EdwinD
 * @create 2020.08.18 下午 05:02
 * @desc
 **/
public class TextWindow {
    public static void main(String[] args) {
        new WindowFrame();
    }
}

class WindowFrame extends Frame {
    public WindowFrame(){
        setBackground(Color.black);
        setBounds(377, 377, 277, 277);
        setVisible(true);

//        方法一对应的内部代码:
//        addWindowListener(new MyWindowListener());

//        方法二:推荐的方法。
//        匿名内部类,可以取代方法一
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("你点击了关闭的“X”");
                setVisible(false);
                System.exit(0);
            }
        });
    }
}

//    方法一:
//    内部类,非静态。
/*
    class MyWindowListener extends WindowAdapter {
        @Override
        public void windowClosing(WindowEvent e) {
//            隐藏窗体,并不关闭。
            setVisible(false);
//            正常退出,
            System.exit(0);
        }
    }
}
*/

输出:

在这里插入图片描述

Eg2:

窗口激活,窗口关闭。

代码:

package com.edwin.lession03;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author EdwinD
 * @create 2020.08.18 下午 05:02
 * @desc
 **/
public class TextWindow {
    public static void main(String[] args) {
        new WindowFrame();
    }
}

class WindowFrame extends Frame {
    public WindowFrame(){
        setBackground(Color.black);
        setBounds(377, 377, 277, 277);
        setVisible(true);

//        方法二:推荐的方法。
//        匿名内部类,可以取代方法一
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowActivated(WindowEvent e) {
                System.out.println("窗口激活了");
                WindowFrame source = (WindowFrame) e.getSource();
                source.setTitle("窗口激活了");
            }

            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("你点击了关闭的“X”");
                setVisible(false);
                System.exit(0);
            }
        });
    }
}

输出:

在这里插入图片描述

2.10、鼠标监听

目的:想要实现鼠标进行画画。

思路:

在这里插入图片描述

代码:

package com.edwin.lession03;
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;
/**
 * @author EdwinD
 * @create 2020.08.18 上午 11:39
 * @desc 测试鼠标监听事件
 **/
public class TextMouseListener {
    public static void main(String[] args) {
        MyFrame myFrame = new MyFrame("画图");
        windowClose(myFrame);
    }
    private static void windowClose(Frame frame) {
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

class MyFrame extends Frame {
//    思路:
//    1.画画需要画笔.
//    2.需要监听鼠标此刻的位置所在.
//    3.需要有集合来存储这个点.
    ArrayList points;

    public MyFrame(String title) {
        super(title);
        setBounds(277, 277, 377, 377);
        setVisible(true);
//        鼠标点击存放点
        points = new ArrayList<>();
//        此窗口的鼠标监听器
        this.addMouseListener(new MouseListener());
    }

    @Override
    public void paint(Graphics g) {
//        画画,鼠标的监听事件
        Iterator iterator = points.iterator();
        while (iterator.hasNext()) {
            Point point = (Point) iterator.next();
            g.setColor(Color.GREEN);
            g.fillOval(point.x, point.y, 7, 7);
        }
    }

    public void addPoint(Point point){
        points.add(point);
    }

    private class MouseListener extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            MyFrame frame = (MyFrame) e.getSource();
//            我们点击的时候,会在界面上产生一个点.
            frame.addPoint(new Point(e.getX(), e.getY()));
            frame.repaint();
        }
    }
}

输出:

在这里插入图片描述

2.11、键盘监听

目的:将从键盘输入的内容识别出来。

代码:

package com.edwin.lession03;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * @author EdwinD
 * @create 2020.08.18 下午 10:38
 * @desc Keyboard
 **/
public class TextKeyListener {
    public static void main(String[] args) {
        new KeyFrame();
    }
}

class KeyFrame extends Frame {
    public KeyFrame() {
        setBounds(377, 377, 277, 277);
        setVisible(true);

        this.addKeyListener(new KeyAdapter() {
            //键盘按下时的监听
            @Override
            public void keyPressed(KeyEvent e) {
//                获得键盘按下的键是哪一个,及当前按键的代号
                int keyCode = e.getKeyCode();
                System.out.println("You Have Pushed the Keyboard,the Num is"+keyCode);
                if (keyCode == KeyEvent.VK_UP) {
                    System.out.println("向上键被按下了。");
                }
            }
        });

        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("你点击了关闭X");
                System.exit(0);
            }
        });
    }
}

输出效果:

在这里插入图片描述
路漫漫其修远兮,吾将上下而求索。

参考文献

《【狂神说Java】GUI编程入门到游戏实战》
视频链接

2020.08.18

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐