AWT

  1. AWT(Abstract Window Toolkit),中文译为抽象窗口工具包,该包提供了一套与本地图形界面进行交互的接口,是Java提供的用来建立和设置Java的图形用户界面的基本工具。
  2. 常用组件:如下关系图

1.1、Frame

构造方法

Frame frame = new Frame("New Window");

要生成一个窗口,通常使用Window的子类Frame类进行实例化,而不是直接使用Window 类,框架的外观就像平常Windows系统下的窗口,有标题、边框菜单和大小等。

案例演示:

package awtdemo;

import java.awt.*;
import java.util.Set;

public class TestFrame {
    public static void main(String[] args) {
        //new一个窗口
        Frame frame = new Frame("我的第一个界面");
        //设置窗口的大小,这个传的参数只能是boolean类型,true为可变,false就是不可变
        frame.setResizable(true);
        //设置窗口的可见性,传的参数也只能是boolean类型
        frame.setVisible(true);
        //设置窗口的背景颜色,这里可以new一个Color类自己RGB颜色,也可以直接传一个Color
       // frame.setBackground(new Color(85,150,86));
        frame.setBackground(Color.BLACK);
        //设置窗口的大小
        frame.setSize(400,600);
        //设置窗口的初始弹出来的位置
        frame.setLocation(500,500);
    }
}

效果展示:

然后发现关闭不了,那是因为我们没有设置关闭时间,现在只能通过IDEA停止java程序来关闭,如上图箭头所示。

1.2、Panel

构造方法:

Panel pnl = new Panel();

面板是一种透明的容器,没有标题和边框。与Frame 不同,Panel不能作为最外层的容器单独存在,它首先必须作为一个组件放置在其他容器(一般为Frame)中,然后把组件添加到它里面。在java.swing中则是JPanel

案例演示:

package awtdemo;

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

public class TestPanel {
    public static void main(String[] args) {
        Frame frame = new Frame("我的第二个界面");
        //new一个Panel
        Panel panel = new Panel();
        //设置流式布局
        frame.setLayout(null);
        //设置最外面窗口弹出的坐标位置和背景颜色
        frame.setBounds(300,400,500,600);
        frame.setBackground(Color.BLUE);
        //设置透明画板的弹出位置和背景颜色
        panel.setBounds(50,50,400,500);
        panel.setBackground(Color.LIGHT_GRAY);
        //把panel添加进Frame中
        frame.add(panel);
        //把最外层窗口可见性设置为可见,两个就都可见了
        frame.setVisible(true);
        //设置关闭事件 这个是适配器模式,后面再继续探究,现在先用着
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

效果展示:

问题:如果把Panel的坐标设置的没有在Frame 的坐标范围内会怎么样?

出来的效果窗口就只会显示Frame不会显示Panel,因为我第一遍测试的时候试了,只会出现Frame设置的效果,要想让Panel显示只能通过放大Frame去看到他,想去尝试的小伙伴可以去尝试一下。

1.3、布局管理器

1.3.1、流布局管理器(FlowLayout)

FlowLayout是Panel 和 Applet 的默认布局管理器。在该布局管理器中,组件在容器中按照从上到下,从左到右的顺序进行排列,行满后则换行。

构造方法较多,例如:

  • FlowLayout();

    默认构造方法,设置居中对齐方式,横向和纵向间隔均为默认5像素

  • FlowLayout(FlowLayout.LEFT);

    设置居左对齐,横向和纵向间隔均为默认5像素

  • FlowLayout(FlowLayout.RIGHT,20,40);

    设置居右对齐,横向间隔20像素,纵向间隔40像

package awtdemo;

import java.awt.*;

public class TestLayout {
    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(FlowLayout.RIGHT,20,40));
        //frame.setLayout(new FlowLayout(FlowLayout.TRAILING);
        //frame.setLayout(new FlowLayout(FlowLayout.CENTER));
        //frame.setLayout(new FlowLayout(FlowLayout.LEFT));
        //frame.setLayout(new FlowLayout(FlowLayout.LEADING));
        frame.setSize(600,200);
        //把按钮添加到Frame面板中
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);

        frame.setVisible(true);


    }
}

效果展示:

1.3.2、边界布局管理器(BorderLayout)

构造方法:

BorderLayout bl = new BorderLayout();`

BorderLayout是Window、Frame和Dialog的默认布局管理器,其将容器分成North、South、East、West和Center 5个区域,每个区域只能放置一个组件。在使用add()方法添加组件到容器时,必须指定将其放置在哪个区域中。使用BorderLayout时,如果容器大小发生变换,组件的相对位置不变

案例演示:

package awtdemo;

import java.awt.*;

public class TestBorderLayout {
    public static void main(String[] args) {
        Frame frame = new Frame("我的第四个窗口");
        //创建五个按钮
        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(700,700);
        frame.setVisible(true);
    }
}

效果展示:

1.3.3、网格布局管理器(GridLayout)

构造方法:

GridLayout gl = new GridLayout(3,5); //3行5列

GridLayout 可使容器中的各个组件呈网格状布局,平局占据容器的空间,即使容器的大小发生变化,每个组件还是平均占据容器的空间。和FlowLayout一样,GridLayout也是按照从上到下,从左到右的规律进行排列的。

案例演示:

package awtdemo;

import java.awt.*;

public class TestGridLayout {
    public static void main(String[] args) {
        Frame frame = new Frame("我的第五个窗口");
        frame.setSize(400,500);
        Button button1 = new Button("1");
        Button button2 = new Button("1");
        Button button3 = new Button("1");
        Button button4 = new Button("1");
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);
        frame.add(button4);
        //设置为两行两列
        frame.setLayout(new GridLayout(2,2));
        frame.setVisible(true);

    }
}

效果展示:

练习:如何让按钮按照如下图所示布局

过程分析➕案例演示:

package awtdemo;

import java.awt.*;
/*
1.首先我们需要一个顶级的窗口Frame
2.把这个顶级Frame分割成上下两部分,我们就会想到Panel(特性:无法单独显示,必须添加到某个容器中)
3.再把上下两个再分割成两个部分(左右中这个结构),我们我们就需要四个Panel
4.把4个Panel用边界布局管理器排列好完成Panel和Panel之间的嵌套
5.把嵌套好的Panel添加大奥Frame中即可
*/

public class PractiseDemo {
    public static void main(String[] args) {
        //顶级窗口
        Frame frame = new Frame("我的第六个窗口");
        frame.setSize(500,400);
        frame.setLocation(500,500);
        frame.setBackground(Color.BLACK);
        frame.setVisible(true);
        frame.setLayout(new GridLayout(2,1));
        //4个面板
        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));
        //第一部分 
        //给面板1增添两个按钮并用边界布局管理器布局到左右两侧
        p1.add(new Button("p1-button"),BorderLayout.WEST);
        p1.add(new Button("p1-button"),BorderLayout.EAST);
        //给面板2增添两个按钮
        p2.add(new Button("p2-button"));
        p2.add(new Button("p2-button"));
        //把2面板用边界布局管理器添加到1面板的中间
        p1.add(p2,BorderLayout.CENTER);

        //第二部分
        //给面板3增添两个按钮并用边界布局管理器布局到左右两侧(跟面板1的操作相同)
        p3.add(new Button("p3-button"),BorderLayout.EAST);
        p3.add(new Button("p3-button"),BorderLayout.WEST);
        //中间四个我们可以用for循环去添加按钮,也可以手动一个个添加都行 这里用for循环
        for (int i = 0; i < 4; i++) {
            p4.add(new Button("p4-button"));
        }
        //把4面板用边界布局管理器添加到3面板的中间
        p3.add(p4,BorderLayout.CENTER);
        //因为上面我们已经把面板2和面板4添加到面板1和面板3上,所以我们只需要要把面板1和面板3添加到顶级窗口上即可显示
        frame.add(p1);
        frame.add(p3);
    }
}

效果展示:

1.4、事件监听

上面我们实现了在面板上面绘制按钮,但是有了按钮,我们如何让按钮按下去有他的功能,这就需要我们给他设置。Button源代码调中用接口方法,而我们的监听处理函数则必须要实现该接口(ActionListener),这样利用多态,使得Button虽调用的为该接口的方法,但运行的则是我们new出来的对象方法。类似于Button提供了这么一个钩子,但是钩子上面是什么东西他自己并不清楚,我们只需要人为地往上面挂上我们需要的东西即可

案例演示:

package awtdemo;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/*
事假监听的四步:
1.要有时间的源对象:button
2.要发生某种事件(类):TestActionEvent,封装了事件的信息  
3.要有监听器(接口):myActionlistener  接到事件后进行处理  
4.要把监听器注册到事件源对象上 button.addActionListener(myActionlistener); 
*/
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.setVisible(true);
        //关闭窗口事件
        windowClose(frame);
    }
    //关闭窗体的事件 适配器模式
    private static void windowClose(Frame frame){
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}
//构造一个 ActionListener我们要继承 ActionListener这个接口,继承接口我们就要重写它里面的方法
class MyActionlistener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("我爱你");
    }
}

效果展示:

案例演示:多个按钮,共享一个事件

package awtdemo;

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

public class TestActionEvent2 {
    public static void main(String[] args) {
        Frame frame = new Frame("我的第八个窗口");
        Button button1 = new Button("start");
        Button button2 = new Button("stop");
        //setActionCommand()可以显示的定义出发回返回的命令,不如果不显示定义,会显示默认的值(即按钮的名字)
        //可以多个按钮只写一个监听类
        button2.setActionCommand("button-stop");
        MyMonitor myMonitor = new MyMonitor();
        button1.addActionListener(myMonitor);
        button2.addActionListener(myMonitor);
        frame.add(button1,BorderLayout.NORTH);
        frame.add(button2,BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);
    }
}
class MyMonitor implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        //e.getActionCommand()接收定义的命令,并返回
        System.out.println("按钮被点击了:"+e.getActionCommand());
    }
}

效果展示:

1.5、输出框TextField监听

package awtdemo;

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

public class TestText1 {
    public static void main(String[] args) {
        new MyFrame();//启动面板
    }
}

class MyFrame extends Frame{
    public MyFrame(){
        TextField textField = new TextField();
         add(textField);//把文本框加入面板
          //监听这个文本框输入的文字
        MyActionlistener2 myActionlistener2 = new MyActionlistener2();
        //按下enter 就会触发这个输入框的事件
        textField.addActionListener(myActionlistener2);
         //设置替换编码
        textField.setEchoChar('*');
        setVisible(true);
        pack();
    }
}
//监听类
class MyActionlistener2 implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent e) {
        TextField field = (TextField) e.getSource();   //获得一些资源,返回的一个对象
        System.out.println(field.getText()); //获得输入框的文本
        field.setText(""); //清除文本框  ""=null
    }
}

效果展示:

1.6、简易加法计算器

package awtdemo;

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

public class TestCalc {
    public static void main(String[] args) {
        new Calclator();
    }
}
class Calclator extends Frame{
    public Calclator(){
        //1.三个文本框
        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);

        pack();
        setVisible(true);
    }
}
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.获得加数和被加数
        //因为getText()方法里面传的是String类型这里我们把它包装成int类型
        int n1 = Integer.parseInt(num1.getText());
        int n2 = Integer.parseInt(num2.getText());
        //2.将这个值加法运算后,放到第三个框
        num3.setText((n1+n2)+"");//自动装箱成String类型
        //3.清除前两个框
        num1.setText("");
        num2.setText("");

    }
}

效果展示:

改进:采用面向对象写法

package awtdemo;


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

//简易计算器
public class TestCalc {
    public static void main(String[] args) {
        new Calculator().loadFrame();
    }
}

//计算器类
class Calculator extends Frame{

    //属性
    TextField num1,num2,num3;

    //方法
    public void loadFrame(){
        num1 = new TextField(10);//字符数
        num2 = new TextField(10);//字符数
        num3 = new TextField(20);//字符数
        Button button = new Button("=");
        
        Label label = new Label("+");

        button.addActionListener(new MyCalculatorListener(this));

        //布局
        setLayout(new FlowLayout());
        add(num1);
        add(label);
        add(num2);
        add(button);
        add(num3);

        pack();
        setVisible(true);
    }


}

//监听器类
class MyCalculatorListener implements ActionListener{

    //获取计算器这个对象,在一个类中组合另外一个类;
    Calculator calculator = null;

    public MyCalculatorListener(Calculator calculator) {
        this.calculator = calculator;
    }

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

    }

}

继续优化:使用内部类(更好的封装)

package com.kuang.lesson02;


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

//简易计算器
public class TestCalc {
    public static void main(String[] args) {
        new Calculator().loadFrame();
    }
}

//计算器类
class Calculator extends Frame {

    //属性
    TextField num1, num2, num3;

    //方法
    public void loadFrame() {
        num1 = new TextField(10);//字符数
        num2 = new TextField(10);//字符数
        num3 = new TextField(20);//字符数
        Button button = new Button("=");

        Label label = new Label("+");

        button.addActionListener(new MyCalculatorListener());

        //布局
        setLayout(new FlowLayout());
        add(num1);
        add(label);
        add(num2);
        add(button);
        add(num3);

        pack();
        setVisible(true);
    }

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

        @Override
        public void actionPerformed(ActionEvent e) {
            //1. 获得加数和被加数
            //2. 将这个值 + 法运算后,放到第三个框
            //3. 清除前两个框
            int n1 = Integer.parseInt(num1.getText());//直接调用外部类的属性
            int n2 = Integer.parseInt(num2.getText());
            num3.setText("" + (n1 + n2));
            num1.setText("");
            num2.setText("");
        }
    }
}

1.7、画笔

案例演示:测试

package awtdemo;

import java.awt.*;

public class TextPaint {
    public static void main(String[] args) {
      new MyPaint().loadFrame();
    }
}
class MyPaint extends Frame{
    public void loadFrame(){
        setBounds(300,300,500,600);
        setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        //创建画笔的颜色
        g.setColor(Color.red);
        g.drawOval(200,100,100,100);
        g.fillRect(100,100,100,100);
        g.fillOval(200,200,200,200);

    }
}

效果展示:

上述只是电脑在画画,怎么实现鼠标画画,这就需要鼠标监听实现鼠标画画

1.8、鼠标监听实现鼠标画画

原理图:

案例演示:

package awtdemo;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
//鼠标监听事件
public class TestMouseListener {
    public static void main(String[] args) {
        new MyFrame2("画图");
    }
}
//画板的类
class MyFrame2 extends Frame{
    //画画需要画笔。需要监听鼠标当前的位置,需要集合来存储
    ArrayList points;
    public MyFrame2(String title){
        super(title);
        setBounds(200,200,400,300);
        points = new ArrayList<>();
        setVisible(true);
        //添加鼠标监听事件
        this.addMouseListener(new MyMouseListener());
    }
    
//重写画笔的方法
    @Override
    public void paint(Graphics g) {
        Iterator iterator = points.iterator();
        while (iterator.hasNext()){
            Point point = (Point)iterator.next();
            g.setColor(Color.black);
            g.fillOval(point.x,point.y,10,10);
        }
    }
    //添加一个点到界面上
    public void addPaint(Point point){
        points.add(point);
    }
   //鼠标监听事件(适配器模式)
    private class MyMouseListener extends MouseAdapter{
        //重写鼠标按压的方法
        @Override
        public void mousePressed(MouseEvent e) {
            MyFrame2 frame2 = (MyFrame2)e.getSource();
            //我们点击的时候,就会在界面上产生一个点,这个点就是我们鼠标的点
            frame2.addPaint(new Point(e.getX(),e.getY()));
          //每次点击鼠标都需要重新画一遍
            frame2.repaint();//刷新
        }
    }
}

效果展示:

1.9、键盘监听

案例演示:

package awtdemo;

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(){
        setBackground(Color.blue);
        setBounds(100,100,200,200);
        setVisible(true);
        this.addWindowListener(
                //匿名内部类
                //适配器模式
                new WindowAdapter() {
                    //关闭窗口
                    @Override
                    public void windowClosing(WindowEvent e) {
                        System.out.println("windowClosing");
                        //退出
                        System.exit(0);
                    }
                    //激活窗口
                    @Override
                    public void windowActivated(WindowEvent e) {
                        WindowFrame source = (WindowFrame) e.getSource();
                        source.setTitle("被激活了");
                        System.out.println("windowActivated");
                    }
                }
        );
    }

}

1.10、键盘监听

package awtdemo;

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

public class TestKetListener {
    public static void main(String[] args) {
     new KeyFrame();
    }
}
class KeyFrame extends Frame{
    public KeyFrame(){
        setBounds(100,200,300,400);
        setVisible(true);
        //匿名内部类
        this.addKeyListener(new KeyAdapter() {
            //键盘按下
            @Override
            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();
                //打印的是每个键所对应的编码
                System.out.println(keyCode);
                //可以根据按下的不同的操作,产生不同的结果
                if (keyCode == KeyEvent.VK_UP){
                    System.out.println("你按下了上键");
                }
            }
        });
    }
}

效果展示:

原文地址:https://www.cnblogs.com/godles/p/11972538.html