GUI基础01
GUI编程 graphics User iterface
1. 组件
- 窗口
- 弹窗
- 面板
- 文本框
- 列表框
- 按钮
- 图片
- 监听事件
- 鼠标
- 键盘事件
- 破解工具
2. 简介
GUI核心技术: Swing 、 AWT
缺点:
- 界面不美观
- 需要jre环境
我们为什么要学习?
- 可以写出自己心中想要的一些小工具
- 工作的时候可以维护到Swing界面,但是概率很小,现在的公司不会做这些
- 了解MVC架构,了解监听!
1. AWT abstract windows tools
1、 AWT介绍
- 包含了很多类跟接口
- 元素:窗口、按钮、文本域
- java.awt包
2、 组件和容器
1、Frame
package com.lesson01;
import java.awt.*;
public class TextFrame {
public static void main(String[] args) {
Frame frame = new Frame("我的第一个窗口");
frame.setVisible(true);
frame.setSize(100,100);
frame.setBackground(new Color(100,100,100));
frame.setLocation(200,200);
frame.setResizable(false);
}
}
2、对窗口的封装
package com.lesson01;
import java.awt.*;
public class TextFrame2 {
public static void main(String[] args) {
//展示多个窗口
MyFrame myFrame = new MyFrame(100,100,200,200,Color.blue);
MyFrame myFrame2 = new MyFrame(100,100,200,200,Color.blue);
MyFrame myFrame3= new MyFrame(100,100,200,200,Color.blue);
MyFrame myFrame4 = new MyFrame(100,100,200,200,Color.blue);
MyFrame myFrame5 = new MyFrame(100,100,200,200,Color.blue);
MyFrame myFrame6 = new MyFrame(100,100,200,200,Color.blue);
}
}
class MyFrame extends Frame {
static int count = 0;
public MyFrame(int x, int y,int width,int height,Color color) {
super("MyFrame" + (++count));
//继承父类后,父类中的方法直接可以用,不用再写对象名
setBounds(x,y,width,height);
setBackground(color);
setResizable(false);
setVisible(true);
}
}
3、面板Panel
解决了关闭事件
package com.lesson01;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
//panel可以看成一个空间,但是不能单独存在
public class TextPanel {
public static void main(String[] args) {
Frame frame = new Frame();
Panel panel = new Panel();
//设置布局
frame.setLayout(null);
frame.setBounds(100,100,200,200);
frame.setBackground(new Color(100,100,100));
//panel的坐标是相对于frame的
panel.setBounds(50,50,50,50);
panel.setBackground(new Color(2,1,3));
//在窗口中加入面板
frame.add(panel);
frame.setVisible(true);
//监听事件。设置窗口关闭事件, System.exit(0)
//适配器模式
frame.addWindowListener(new WindowAdapter() {
//点击窗口的X号时需要做的事情
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
4、布局管理器
1、 流式布局管理器
package com.lesson01;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TextFlowLayout {
public static void main(String[] args) {
Frame frame = new Frame();
Button button01 = new Button("button1");
Button button02 = new Button("button2");
Button button03 = new Button("button3");
frame.setBounds(100,100,200,200);
//frame.setLayout(new FlowLayout());
//frame.setLayout(new FlowLayout(FlowLayout.LEFT));
frame.setLayout(new FlowLayout(FlowLayout.RIGHT));
frame.setResizable(false);
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);
}
});
}
}
2、边境布局 东西南北中
package com.lesson01;
import com.OOP.demo07.B;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
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 south = new Button("south");
Button north = new Button("north");
Button center = new Button("center");
frame.setBounds(500,500,500,500);
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.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
3、表格布局 Grid
package com.lesson01;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TextGridLayout {
public static void main(String[] args) {
Frame frame = new Frame();
Button button1 = new Button("1");
Button button2 = new Button("2");
Button button3 = new Button("3");
Button button4 = new Button("4");
Button button5 = new Button("5");
Button button6 = new Button("6");
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.add(button4);
frame.add(button5);
frame.add(button6);
frame.setBounds(100,100,600,600);
frame.setLayout(new GridLayout(3,2));
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
4、ExampleDemo
5、总结
-
Frame是一个顶级容器
-
Panel无法单独显示,必须添加到某个容器中
-
布局管理器
- 流式布局 FlowLayout
- 边境布局 东西南北中 BorderLayout
- 表格 GridLayout
-
属性:大小、定位、背景颜色、可见性、窗口大小可变、监听、适配器:Adaper...
5、事件监听
package com.lessen02;
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 TextActionEvent {
public static void main(String[] args) {
Frame frame = new Frame("TextActionListener");
Button button = new Button("please click");
MyActionListener myActionListener = new MyActionListener();
//因为addActionListener()需要一个ActionListener,所以我们需要构造一个ActionListener
button.addActionListener(myActionListener);
frame.add(button);
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");
}
}
package com.lessen02;
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 TextActionTwo {
public static void main(String[] args) {
Frame frame = new Frame("开始-停止");
Button button1 = new Button("start");
Button button2 = new Button("stop" );
//可以显示的定义触发会返回的命令,如果不显示定义,则会走默认的值
//可以多个按钮只写一个监听类
button1.setActionCommand("button1-start");
button2.setActionCommand("button2-stop");
MyMonitor myMonitor = new MyMonitor();
button1.addActionListener(myMonitor);
button2.addActionListener(myMonitor);
frame.add(button1,BorderLayout.NORTH);
frame.add(button2,BorderLayout.SOUTH);
frame.setBounds(100,100,200,200);
frame.setResizable(true);
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 MyMonitor implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
//e.getActionCommand 获得按钮信息
System.out.println("按钮被点击了:msg => " + e.getActionCommand());
}
}
5.1、输入框TextField监听
package com.lessen02;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TextText01 {
public static void main(String[] args) {
new MyFrame();
}
}
class MyFrame extends Frame {
public MyFrame() {
TextField textField = new TextField();
add(textField);
//监听这个文本框输入的文字
MyActionListener02 myActionListener02 = new MyActionListener02();
//按下Enter 就会触发这个输入框的事件
textField.addActionListener(myActionListener02);
//设置替换编码
textField.setEchoChar('*');
setVisible(true);
pack();
}
}
class MyActionListener02 implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
TextField field = (TextField) e.getSource(); //获得一些资源,返回的一个对象
System.out.println(field.getText()); //获得输入框中的文本
field.setText(""); //回车清空输入框
}
}
5. 1、鼠标监听
目的:想要实现鼠标画画
package com.lesson03;
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;
//鼠标监听事件
public class TextMouseListener {
public static void main(String[] args) {
new MyFrame("画图software");
}
}
//自己的类
class MyFrame extends Frame {
//画画需要画笔,需要监听鼠标当前位置,需要一个集合来存储这个点
ArrayList points;
public MyFrame(String title) {
super(title);
setBounds(200,200,400,400);
setVisible(true);
//存鼠标点击的点
points = new ArrayList();
//鼠标监听器,针对这个窗口
this.addMouseListener(new MyMouseListener());
WindowClose(this);
}
@Override
public void paint(Graphics g) {
Iterator iterator = points.iterator();
while (iterator.hasNext()) {
Point point = (Point) iterator.next();
g.setColor(Color.blue);
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) {
MyFrame myFrame = (MyFrame) e.getSource();
//点击的时候会在界面上产生一个点
//这个点就是鼠标的点
myFrame.addPaint(new Point(e.getX(),e.getY()));
//每次点击鼠标都需要重新画一次
myFrame.repaint();//刷新 帧率
}
}
private void WindowClose(Frame frame) {
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
5.2、窗口监听
package com.lesson03;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TextWindow {
public static void main(String[] args) {
new WindowFrame();
}
}
class WindowFrame extends Frame {
public WindowFrame() {
setBounds(200,200,400,400);
setVisible(true);
addWindowListener(new MyWindowListener());
}
class MyWindowListener extends WindowAdapter {
@Override
public void windowClosing(WindowEvent e) {
setVisible(false); //通过按钮,隐藏当前窗口
System.exit(0);//正常退出
}
}
}
package com.lesson03;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TextWindow {
public static void main(String[] args) {
new WindowFrame();
}
}
class WindowFrame extends Frame {
public WindowFrame() {
setBounds(200,200,400,400);
setVisible(true);
addWindowListener(new MyWindowListener());
}
class MyWindowListener extends WindowAdapter {
@Override
public void windowClosing(WindowEvent e) {
setVisible(false); //通过按钮,隐藏当前窗口
System.exit(0);//正常退出
}
}
}
5.3、键盘监听
package com.lesson03;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TextKeyListener {
public static void main(String[] args) {
new MyKeyFrame();
}
}
class MyKeyFrame extends Frame {
public MyKeyFrame(){
setBounds(1,2,300,500);
setVisible(true);
windowClose(this);
this.addKeyListener(new KeyAdapter() {
//键盘按下
@Override
public void keyPressed(KeyEvent e) {
//获得键盘按下的是哪一个键,通过当前的码值确定
int keyCode = e.getKeyCode(); //不需要去记录这个数值,直接使用静态属性 VK_XXX
System.out.println(keyCode);
if (keyCode == KeyEvent.VK_UP) {
System.out.println("↑");
}
}
});
}
private void windowClose(Frame frame) {
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
练习:组合 + 内部类
oop原则:组合大于继承!
尽量不要使用继承与多态
继承会增加耦合性
多态会使代码变得复杂
1、原本使用继承方法下的代码
package com.lessen02;
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 TextCalculator {
public static void main(String[] args) {
new Calculator();
}
}
//计算器类
class Calculator extends Frame {
public Calculator(){
Frame frame = new Frame();
//组建
//三个文本框
TextField number01 = new TextField(10);
TextField number02 = new TextField(10);
TextField number03 = new TextField(20);
//一个按钮 计算器对等号进行监听
Button button = new Button(" = ");
button.addActionListener(new MyCalculatorListener(number01,number02,number03));
//一个标签
Label label = new Label(" + ");
//布局
frame.setLayout(new FlowLayout());
frame.add(number01);
frame.add(label);
frame.add(number02);
frame.add(button);
frame.add(number03);
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 MyCalculatorListener implements ActionListener {
private TextField number01,number02,number03;
public MyCalculatorListener(TextField number01,TextField number02,TextField number03) {
this.number01 = number01;
this.number02 = number02;
this.number03 = number03;
}
@Override
public void actionPerformed(ActionEvent e) {
//1. 获得加数和被加数
int i = Integer.parseInt(number01.getText());
int j = Integer.parseInt(number02.getText());
//2. 将这个值进行 +法运算后,放到第三个框
number03.setText("" + (i + j));
//3. 清除前两个框
number01.setText("");
number02.setText("");
}
}
2、使用组合
package com.lessen02;
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 TextCalculator {
public static void main(String[] args) {
new Calculator().loadFrame();
}
}
//计算器类
class Calculator extends Frame {
//属性
TextField number01,number02,number03;
//方法
public void loadFrame(){
Frame frame = new Frame();
//组建
number01 = new TextField(10);
number02 = new TextField(10);
number03 = new TextField(20);
//一个按钮 计算器对等号进行监听
Button button = new Button(" = ");
Label label = new Label(" + ");
button.addActionListener(new MyCalculatorListener(this));
//布局
frame.setLayout(new FlowLayout());
frame.add(number01);
frame.add(label);
frame.add(number02);
frame.add(button);
frame.add(number03);
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 MyCalculatorListener implements ActionListener {
//获得计算器这个对象,在一个类中组合另一个类
Calculator calculator = null;
public MyCalculatorListener(Calculator calculator) {
this.calculator = calculator;
}
@Override
public void actionPerformed(ActionEvent e) {
//1. 获得加数和被加数
//2. 将这个值进行 +法运算后,放到第三个框
//3. 清除前两个框
int i = Integer.parseInt(calculator.number01.getText());
int j = Integer.parseInt(calculator.number02.getText());
calculator.number03.setText("" + (i + j));
calculator.number01.setText("");
calculator.number02.setText("");
}
}
3、完全改造成面向对象写法 使用内部类方法
- 内部类能更好的包装
package com.lessen02;
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 TextCalculator {
public static void main(String[] args) {
new Calculator().loadFrame();
}
}
//计算器类
class Calculator extends Frame {
//属性
TextField number01,number02,number03;
//方法
public void loadFrame(){
Frame frame = new Frame();
//组建
number01 = new TextField(10);
number02 = new TextField(10);
number03 = new TextField(20);
//一个按钮 计算器对等号进行监听
Button button = new Button(" = ");
Label label = new Label(" + ");
button.addActionListener(new MyCalculatorListener());
//布局
frame.setLayout(new FlowLayout());
frame.add(number01);
frame.add(label);
frame.add(number02);
frame.add(button);
frame.add(number03);
frame.pack();
frame.setVisible(true);
windowClose(frame);
}
//监听器类
//内部类最大的好处,就是能畅通无阻的访问外部类的属性和方法!
private class MyCalculatorListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
//1. 获得加数和被加数
//2. 将这个值进行 +法运算后,放到第三个框
//3. 清除前两个框
int i = Integer.parseInt(number01.getText());
int j = Integer.parseInt(number02.getText());
number03.setText("" + (i + j));
number01.setText("");
number02.setText("");
}
}
public static void windowClose (Frame frame){
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
6. 画笔 paint
package com.lesson03;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TextPaint {
public static void main(String[] args) {
new MyPaint().loadFrame();
}
}
class MyPaint extends Frame {
public void loadFrame() {
Frame frame = new Frame();
frame.setBounds(200,200,1000,1000);
frame.setVisible(true);
windowClose(frame);
}
//画笔
@Override
public void paint(Graphics g) {
g.setColor(Color.red);
g.setColor(Color.black);
g.drawOval(100,100,200,200);
g.fillOval(400,400,200,200);
//养成习惯,画笔用完,将他还原到最初的颜色
}
public static void windowClose(Frame frame) {
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现