GUI AWT

简介

GUI的核心技术:Swing、AWT

学习原因:了解MVC架构;了解监听

1.用AWT进行一些底层的实现

AWT包含了很多类和接口,包含的元素有:窗口、按钮、文本框等
在这里插入图片描述

1.1、组件和容器

1. Frame

package com.kuang.lesson01;

import java.awt.*;

//GUI的第一个界面
public class TestFrame {
    public static void main(String[] args){
        //Fram JDK,看源码!
        Frame frame = new Frame("我的第一个java图形界面窗口");

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

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

        //设置窗口颜色
        frame.setBackground(new Color(255, 47, 77));

        //弹出的初始位置
        frame.setLocation(200, 200);

        //设置大小固定
        frame.setResizable(false);
    }
}

效果图:问题是发现窗口关闭不掉,解决办法是停止java的运行
在这里插入图片描述
在这里插入图片描述
效果图:
在这里插入图片描述

2. 面板Panel

解决了关闭事件!

package com.kuang.lesson01;

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

//Panel 可以看成是一个空间,但是不能单独存在
public class TestPanel {
    public static void main(String[] args) {
        //Frame是一个总的窗口,我们所有的命令都在上面
        Frame frame = new Frame();
        //布局的概念
        Panel panel = new Panel();
        //设置布局
        frame.setLayout(null);

        //坐标
        frame.setBounds(300,300,500,500);
        frame.setBackground(new Color(255,65,98));

        //panel设置坐标,相对于frame
        panel.setBounds(50,50,300,300);
        panel.setBackground(new Color(65,85,79));

        //往窗口上添加面板
        frame.add(panel);

        frame.setVisible(true);

        //解决界面不能关闭的问题:监听事件,监听窗口关闭时间。用适配器模式
        frame.addWindowListener(new WindowAdapter() {
            //窗口点击关闭需要做的事情
            @Override
            public void windowClosing(WindowEvent e) {
                //结束程序
                System.exit(0);
            }
        });
    }

}

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

3.布局管理器

  • 流式布局
package com.kuang.lesson01;

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.setSize(200,200);
        //把按钮添加上去
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);
        frame.setVisible(true);
    }
}

在这里插入图片描述

在这里插入图片描述

  • 东西南北中
package com.kuang.lesson01;

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

    }
}

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

  • 表格布局 Grid
package com.kuang.lesson01;

import java.awt.*;

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

        Button btn1 = new Button("btn1");
        Button btn2 = new Button("btn2");
        Button btn3 = new Button("btn2");
        Button btn4 = new Button("btn4");
        Button btn5 = new Button("btn5");
        Button btn6 = new Button("btn6");

        frame.setLayout((new GridLayout(3, 2)));

        frame.add(btn1);
        frame.add(btn2);
        frame.add(btn3);
        frame.add(btn4);
        frame.add(btn5);
        frame.add(btn6);

        frame.pack(); //java函数,会自动选择一个最优的按钮放置位置
        frame.setVisible(true);
    }
}

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

2.1 事件监听

当某个事情发生的时候干什么

package com.kuang.lesson02;

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();
        frame.setVisible(true);
        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("aaa");   //运行完之后,点击按钮会产生输出“aaa”这样一个事件
    }
}
package com.kuang.lesson02;

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

public class TestActionTwo {
    public static void main(String[] args) {
        //两个按钮,实现同一个监听
        //开始  停止
        Frame frame = new Frame("开始-停止");

        Button button1 = new Button("start");
        Button button2 = new Button("stop");

        button2.setActionCommand("button2-stop");

        //new一个事件
        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是获取到某些信息(按钮信息)
        System.out.println("按钮被点击了:msg" + e.getActionCommand());
    }
}
按钮被点击了:msg(点击start)
按钮被点击了:msgbutton2-stop(点击stop)
2.1.1 输入框事件监听

在这里插入图片描述
最终代码

package com.kuang.lesson02;

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

public class TestText01 {
    public static void main(String[] args) {
        new MyFrame();
    }
}

class MyFrame extends Frame{
    public MyFrame() throws HeadlessException {
        TextField textField = new TextField();
        add(textField);

        //监听输入的文本
        MyListener myListener = new MyListener();
        //按下回车,就会触发这个输入框的事件
        textField.addActionListener(myListener);
        //设置替换编码
        textField.setEchoChar('*');
        pack();
        setVisible(true);
    }
}
class MyListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        TextField field = (TextField)e.getSource();  //获得一些资源,返回一个对象(查看源代码知
             //getSource是Object对象,所以向下转型,监听的是谁,就转成谁,这样我们就在监听器里面拿到了textField对象)
        System.out.println(field.getText()); //就可以获得输入框中的文本
        field.setText(""); //回车之后把文本变成空
    }
}

替换编码效果图:

在这里插入图片描述
但在运行界面是真实的文本

2.1.2 简易计算器 组合加内部类复习

oop原则:组合 大于继承,不会产生较大的耦合性

class A extends B{ //继承
}
class A{  //A还是A,只是要把B组合进来
//怎么拥有B的功能呢?私有进来
    public B b;
}

目前代码(面向过程)

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();
    }
}

class Calculator extends Frame{
    public Calculator() throws HeadlessException {
        //3个文本框
        TextField textField1 = new TextField(10);
        TextField textField2 = new TextField(10);
        TextField textField3 = new TextField(20);

        //1个按钮
        Button button = new Button("=");
        button.addActionListener(new MyCalculator(textField1, textField2, textField3));

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

        //从左到右布局,流式布局
        setLayout(new FlowLayout());

        add(textField1);
        add(label);
        add(textField2);
        add(button);
        add(textField3);

        pack();
        setVisible(true);
    }
}

class MyCalculator implements ActionListener{
    //获取三个变量,采用有参构造器,在上面new MyCalculator的时候传参过来
    private TextField num1, num2, num3;
    public MyCalculator(TextField num1, TextField num2, TextField num3) {
        this.num1 = num1;
        this.num2 = num2;
        this. num3 = num3;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        //1.获得加数和被加数
        //num1.getText(); //为什么要num1. 是因为传过来的参数是一个对象,只有.了才能获取传过来的文本,
                        // 但是传过来的是String类型,需要转换成int类型
        int n1 = Integer.parseInt(num1.getText());  // 使用Integer转换
        int n2 = Integer.parseInt(num2.getText());

        //2.将这个值+法运算后,放到第三个框
        num3.setText(""+(n1+n2));

        //3.清除前面两个框
        num1.setText("");
        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(){
        //3个文本框
        TextField textField1 = new TextField(10);
        TextField textField2 = new TextField(10);
        TextField textField3 = new TextField(20);

        //1个按钮
        Button button = new Button("=");

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

        button.addActionListener(new MyCalculator(this));

        //从左到右布局,流式布局
        setLayout(new FlowLayout());

        add(textField1);
        add(label);
        add(textField2);
        add(button);
        add(textField3);

        pack();
        setVisible(true);
    }
}

//监听器类
class MyCalculator implements ActionListener{
    //获取计算器这个对象,在一个类中组合另一个类
    Calculator calculator = null;

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

    @Override
    public void actionPerformed(ActionEvent e) {
        //1.获得加数和被加数
        //num1.getText(); //为什么要num1. 是因为传过来的参数是一个对象,只有.了才能获取传过来的文本,
                        // 但是传过来的是String类型,需要转换成int类型
        int n1 = Integer.parseInt(calculator.num1.getText());
        int n2 = Integer.parseInt(calculator.num1.getText());
        //2.将这个值+法运算后,放到第三个框
        calculator.num3.setText(""+(n1+n2));

        //3.清除前面两个框
        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(){
        //3个文本框
        TextField textField1 = new TextField(10);
        TextField textField2 = new TextField(10);
        TextField textField3 = new TextField(20);

        //1个按钮
        Button button = new Button("=");

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

        button.addActionListener(new MyCalculator());

        //从左到右布局,流式布局
        setLayout(new FlowLayout());

        add(textField1);
        add(label);
        add(textField2);
        add(button);
        add(textField3);

        pack();
        setVisible(true);
    }
    //监听器类
    //内部类的最大好处就是可以畅通无阻的访问外部类的属性和方法
    private class MyCalculator implements ActionListener{
        //变成内部类之后就可以直接用自己的属性,不用单独new
//        //获取计算器这个对象,在一个类中组合另一个类
//        Calculator calculator = null;
//
//        public MyCalculator(Calculator calculator) {
//            this.calculator = calculator;
//        }

        @Override
        public void actionPerformed(ActionEvent e) {
            //1.获得加数和被加数
            //num1.getText(); //为什么要num1. 是因为传过来的参数是一个对象,只有.了才能获取传过来的文本,
            // 但是传过来的是String类型,需要转换成int类型
            int n1 = Integer.parseInt(num1.getText());
            int n2 = Integer.parseInt(num1.getText());
            //2.将这个值+法运算后,放到第三个框
            num3.setText(""+(n1+n2));

            //3.清除前面两个框
            num1.setText("");
            num2.setText("");
        }
    }
}

2.1.3 画笔paint

2.1.4 鼠标监听

目的:实现鼠标画画

原理图:
在这里插入图片描述

package com.kuang.lesson03;

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

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

class MyFrame extends Frame {
    //画画需要画笔,需要监听鼠标事件,需要集合来存储这些点
    ArrayList points;

    public MyFrame(String title) {
        super(title);
        //设置一个画板
        setBounds(200,200,400,400);

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

        //鼠标监听器,针对于这个窗口的  this表示当前这个窗口
        this.addMouseListener(new MyMouseListener());

        setVisible(true);
    }

    //重写画笔(具体实施的类)
    @Override
    public void paint(Graphics g) {
        //通过画笔画画,画下的每一个点都需要与鼠标绑定,所以需要监听鼠标的事件,添加一个鼠标的监听器
        //把集合里面的点迭代出来
        Iterator iterator = points.iterator();
        while (iterator.hasNext()){
            Point point = (Point) iterator.next();  //next指向了下一个后会返回一个当前的点
            g.setColor(Color.BLUE);
            g.fillOval(point.x, point.y,10,10);
        }
    }

    //添加一个点到界面上,用paint()把点画上去  怎么把paints里面的点拿到并画上去呢?
    //画到数组里面的类
    public void addPaint(Point point){  //把监听器里面的点添加到画笔里面
        points.add(point);
    }


//    private class MyMouseListener implements MouseListener{ // 如果直接这样写,需要重写MouseListener里面全部的方法
//
//    }

    //所以我们采用适配器模式写一个监听器(监听的类)
    private class MyMouseListener extends MouseAdapter {
        //鼠标 按下,弹起,按住不放
        @Override
        public void mousePressed(MouseEvent e) { //e获取鼠标资源
            //e.getSource();  //要返回当前对象,我们是用MyFrame调用的,所以需要返回同样类型的对象  向下转型
            MyFrame frame = (MyFrame) e.getSource();  //这样就拿到了窗口,拿到了之后我们就要画东西,点一下画一下
            // 点击的时候会在界面产生一个点,所以从这把思路转化到画笔即paint
            //产生一个点的坐标,鼠标的点怎么拿?e就代表当前的鼠标,e.getSource就代表调用它的,叫frame
            Point point = new Point(e.getX(), e.getY());
            frame.addPaint(point);  //当前的点是传到了集合里面去遍历,points
            //每次点击鼠标都需要重新画一遍,因为第一次执行画笔的时候,初始的集合里面并没有东西,所以画完就没了
            frame.repaint();//刷新
        }
    }
}
//监听器里面的点,放到集合里面(通过addPaint()类),再通过画笔即paint类画出来

2.1.5 窗口监听

package com.kuang.lesson03;

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.BLACK);
        setBounds(100,100,200,200);
        setVisible(true);
        //addWindowListener(new MyWindowsListener());
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                setVisible(false);
                System.exit(0);
            }
        });
    }

    //换匿名内部类来写
//    class MyWindowsListener extends WindowAdapter{
//        @Override
//        public void windowClosing(WindowEvent e) {
//            setVisible(false); //隐藏窗口,通过按钮,隐藏当前窗口
//            System.exit(0);  //正常退出
//        }
//    }
}

2.1.6 键盘监听

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值