GUI编程
告诉大家怎么学
1、简介
GUI 的核心技术: Swing AWT,但界面不美观,并且运行时需要jre运行环境
为什么我们要学习?
-
可以写出自己心中的一些小工具
-
工作的时候,也可能需要去维护Swing界面(如果公司需要,表示这家公司比较老)
-
了解MVC架构,了解监听!
2、AWT
包含了很多接口! GUI:
eclipse:使用Java写的软件
//Frame,JDK ,看源码
Frame frame = new Frame("我的第一个Java图形窗口!");
//需要设置可见性
frame.setVisible(true);
//设置窗口大小 w 宽 h 高
frame.setSize(400,400);
//设置背景颜色 Color
new Color(100,100,100);
frame.setBackground(Color.gray);
//frame.setBackgroud(new Color(100,100,100));自己设置RGB,左边会显示颜色
//弹出初始位置
frame.setLocation(20,200);//坐标值
//设置大小固定(如果没有即弹出的窗口大小可以随意变动)
frame.setResizable(false);//当值为false的时候窗口大小不能调整,变成固定
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DODytXk4-1658630497811)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220622154833084.png)]
问题:窗口无法关闭,停止Java程序
尝试回顾封装:
import java.awt.*;
public class TestFrame2 {
public static void main(String[] args) {
//展示多个窗口
new MyFrame(100,100,200,200,Color.BLUE);
new MyFrame(400,100,200,200,Color.gray);
new MyFrame(100,400,200,200,Color.cyan);
new MyFrame(400,400,200,200,Color.LIGHT_GRAY);
}
}
class MyFrame extends Frame {
//可能存在多个窗口,需要一个计算器
static int id = 0;
public MyFrame(int x, int y,int w,int h,Color color){
super("Myframe"+ (++id));
setBackground(color);
setVisible(true);
setBounds(x,y,w,h);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C08GHONg-1658630497812)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220622160005400.png)]
4.面板panel
panel可以看成一个空间,但是不能独立存在
内嵌不同的画面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8N17YZRM-1658630497813)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220622162312871.png)]
解决了窗口关闭事件
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class TestPanel {
public static void main(String[] args) {
// panel可以看成一个空间,但是不能独立存在
Frame frame = new Frame();
//布局概念
Panel panel = new Panel();
//设置布局
frame.setLayout(null);
//坐标
frame.setBounds(400,400,1000,800);
frame.setBackground(new Color(60, 168, 201));
//panel设置坐标,相对于frame
panel.setBounds(50,50,400,400);
panel.setBackground(new Color(168,60,102));
//frame.add(Panel);
frame.add(panel);
frame.setVisible(true);//设置可见性
//监听事件,查看窗口是否关闭 System.exit(0)
//适配器模式:只说明一个方法,不重写其他方法
frame.addWindowListener(new WindowAdapter() {
//窗口点击关闭的时候需要做的事情
@Override
public void windowClosing(WindowEvent e) {
// super.windowClosing(e); 仅关闭窗口
//结束程序
System.exit(0);
}
});
//以下为打开全部方式,不太方便
// 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) {
//
// }
// });
}
}
适配器可供选择
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q1az5UFl-1658630497813)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220622161701673.png)]
点击关闭时,窗口以及程序都会被关闭停止
3、布局管理器
-
流式布局
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.setLayout(new FlowLayout(FlowLayout.RIGHT);//按钮靠右 frame.setSize(800,800); //吧按钮添加上去 frame.add(button1); frame.add(button2); frame.add(button3); frame.setVisible(true); } }
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UI535bm8-1658630497814)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220622163351027.png)]
-
东西南北中
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,800);
frame.setVisible(true);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nwe6I8Gt-1658630497814)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220622164233026.png)]
-
表格布局
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"); Button c6 = new Button("C6"); frame.setLayout(new GridLayout(3,2)); frame.add(east); frame.add(west); frame.add(south); frame.add(north); frame.add(center); frame.add(c6); frame.pack();//Java函数!会自动填充大小 frame.setSize(500,800); frame.setVisible(true); } }
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sc59ME6J-1658630497814)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220622164836820.png)]
框架与面板练习
需求
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EMb3Z7uD-1658630497814)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220703162247058.png)]
练习代码
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class ExDemo {
public static void main(String[] args){
Frame frame = new Frame();
frame.setSize(500,600);
frame.setLocation(500,400);
frame.setBackground(Color.gray);
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,1));
//上面按钮
p1.add(new Button("East-1"),BorderLayout.EAST); //设置第一层面板右边的按钮
p1.add(new Button("West-1"),BorderLayout.WEST);
p2.add(new Button("p2-btn-1")); //设置第二层面板中按顺序第一个按钮
p2.add(new Button("p2-btn-2"));
p1.add(p2,BorderLayout.CENTER); //在第一层面板中嵌套p2面板
//下面
p3.add(new Button("East-2"),BorderLayout.EAST); //同上
p3.add(new Button("West-2"),BorderLayout.WEST);
//下层中间四按钮
for(int i = 0;i < 4; i++){
p4.add(new Button("for-" + i)); //按顺序增加四个第四层中的四个按钮
}
p3.add(p4,BorderLayout.CENTER);
frame.add(p1); //在两行一列的框架中加入两个面板
frame.add(p3);
frame.addWindowListener(new WindowAdapter() {
//窗口点击关闭的时候需要做的事情
@Override
public void windowClosing(WindowEvent e) {
// super.windowClosing(e); 仅关闭窗口
//结束程序
System.exit(0);
}
});
}
}
运行结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-khhmOM31-1658630497815)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220703162507262.png)]
总结
- Fram是一个顶级窗口
- Panel无法单独显示,必须加在某一个容器中,窗口中
- 布局管理器
- 流式
- 东西南北中
- 表格
- 嵌套
4.大小、定位、背景颜色、可见性监听!
事件监听
事件监听:当某个事情发生的时候,干什么,?
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();
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");
}
}
!!!多个按钮是可以共用一个事件的!
输入框事件监听TestFiled
创建一个窗口并且进行文本输入,在后台可以获得文本输入框的内容,并且可以对用户输入文本时加密(可加可不加)
代码展示
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 TestText1 {
public static void main(String[] args) {
//启动
new MyFrame2();
}
}
class MyFrame2 extends Frame{
public MyFrame2(){
TextField textField = new TextField();
add(textField);
//监听这个文本框输入的文字
MyActionListener2 myActionListener2 = new MyActionListener2();
//按下enter 就会触发这个输入框的事件
textField.addActionListener(myActionListener2);
//设置替换编码(在不设置这一part的情况下前台文本框显示与输入一致),一般用于密码加密输入
textField.setEchoChar('*');
//因为已经继承Frame,所以可以直接操作
setVisible(true);
pack();
//关闭窗口事件
addWindowListener(new WindowAdapter() {
//窗口点击关闭的时候需要做的事情
@Override
public void windowClosing(WindowEvent e) {
// super.windowClosing(e); 仅关闭窗口
//结束程序
System.exit(0);
}
});
}
}
class MyActionListener2 implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
//获得一些资源(输入框),并且返回给后台一些资源
TextField field = (TextField) e.getSource();
//获得并输入文本框的内容
System.out.println(field.getText());
field.setText(""); //回车后输入文本框变null “”
}
}
代码运行结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o47xqVZ5-1658630497815)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220703192152259.png)]
简易计算器,组合+内部类回顾
opp原则:组合,大于继承
目前代码:
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 TestCalc {
//计算器类启动项
public static void main(String[] args) {
new Calculator();
}
}
//计算器
class Calculator extends Frame{
public Calculator(){
//三个文本框
TextField num1 = new TextField(11);
TextField num2 = new TextField(11);
TextField num3 = new TextField(22); //允许输入的字符数
//一个按钮
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();
setSize(800,100);
setVisible(true);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
//计算器监听事件
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.获得加数和被加数
int n1 = Integer.parseInt(num1.getText());
int n2 = Integer.parseInt(num2.getText());
//2.运算两个参数,并且返回值给num3
num3.setText("" + (n1 + n2));
//3.清除前两个数
num1.setText("");
num2.setText("");
}
}
运行结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yHrc3enG-1658630497815)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220703195707305.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y9O7W1Dv-1658630497816)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220703195724861.png)]
以上为初级版代码展示
组合进阶版代码展示(符合面向对象要求)
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 TestCalc2 {
//计算器类启动项
public static void main(String[] args) {
new Calculator().loadFrame();
}
}
//计算器
class Calculator extends Frame{
//属性
TextField num1,num2,num3;
//方法
public void loadFrame(){
//三个文本框
num1 = new TextField(11);
num2 = new TextField(11);
num3 = new TextField(22); //允许输入的字符数
//一个按钮
Button button = new Button("=");
// button.addActionListener(new MyCalculatorListener(num1,num2,num3)); 初级
button.addActionListener(new MyCalculatorListener(this));
//一个标签
Label label = new Label("+");
//布局 流式布局可自适应
setLayout(new FlowLayout());
add(num1);
add(label);
add(num2);
add(button);
add(num3);
pack();
setSize(800,100);
setVisible(true);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
//计算器监听事件
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;
// }
//进阶版(组合进对象)
Calculator calculator = null;
public MyCalculatorListener(Calculator calculator){
this.calculator = calculator;
}
@Override
public void actionPerformed(ActionEvent e) {
//1.获得加数和被加数()初级
// int n1 = Integer.parseInt(num1.getText());
// int n2 = Integer.parseInt(num2.getText());
//组合版
int n1 = Integer.parseInt(calculator.num1.getText());
int n2 = Integer.parseInt(calculator.num2.getText());
//2.运算两个参数,并且返回值给num3 ()初级
//组合版
calculator.num3.setText("" + (n1 + n2));
//3.清除前两个数 ()初级
// num1.setText("");
// num2.setText("");
//组合版
calculator.num1.setText("");
calculator.num2.setText("");
}
}
代码展示同上
内部类
-
用于更好的包装,便捷使用
代码展示:
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 TestCalc3 {
//计算器类启动项
public static void main(String[] args) {
new Calculator().loadFrame();
}
}
//计算器
class Calculator extends Frame{
//属性
TextField num1,num2,num3;
//方法
public void loadFrame(){
//三个文本框
num1 = new TextField(11);
num2 = new TextField(11);
num3 = new TextField(22); //允许输入的字符数
//一个按钮
Button button = new Button("=");
// button.addActionListener(new MyCalculatorListener(num1,num2,num3)); 初级
button.addActionListener(new MyCalculatorListener());
//一个标签
Label label = new Label("+");
//布局 流式布局可自适应
setLayout(new FlowLayout());
add(num1);
add(label);
add(num2);
add(button);
add(num3);
pack();
setSize(800,100);
setVisible(true);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
//计算器监听事件
//内部类最大的好处,就是可以畅通无阻的访问外部类的操作,属性和方法!
private 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.获得加数和被加数()初级
// int n1 = Integer.parseInt(num1.getText());
// int n2 = Integer.parseInt(num2.getText());
//组合版
int n1 = Integer.parseInt(num1.getText());
int n2 = Integer.parseInt(num2.getText());
//2.运算两个参数,并且返回值给num3 ()初级
//组合版
num3.setText("" + (n1 + n2));
//3.清除前两个数 ()初级
// num1.setText("");
// num2.setText("");
//组合版
num1.setText("");
num2.setText("");
}
}
}
输出同上!
2.7画笔Paint
代码展示:
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestPaint {
public static void main(String[] args) {
new MyPaint().loadFrame();
}
}
class MyPaint extends Frame{
public void loadFrame(){
setBounds(200,200,800,600);
setBackground(Color.pink);
setVisible(true);
}
//画笔
@Override
public void paint(Graphics g) {
//画笔,需要有颜色,画笔可以画画
g.setColor(Color.gray);
g.drawOval(100,100,100,100); //圆圈
g.fillOval(200,200,100,100); //实心圆
g.setColor(Color.LIGHT_GRAY);
g.fillRect(300,300,100,100);
//养成习惯,画笔用完就恢复默认颜色(黑色)
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
输出展示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zQzp03J7-1658630497816)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220703205320262.png)]
2.8鼠标监听
目的:使用鼠标画画(单点)
代码展示:
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Iterator;
public class TestMouseListiener {
public static void main(String[] args) {
new MyFrame("画图");
}
}
class MyFrame extends Frame{
//画画需要画画,需要监听鼠标当前的位置,需要集合来存储这些点
ArrayList points;
public MyFrame(String title){
super(title);
setBounds(200,200,800,600);
//存鼠标的点
points = new ArrayList<>();
//鼠标监听器,正对这个窗口
this.addMouseListener(new MyMouseListener());
setVisible(true);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
@Override
public void paint(Graphics g) {
//画画,监听鼠标的事件
Iterator iterator = points.iterator();
while (iterator.hasNext()){
Point point = (Point) iterator.next();
g.setColor(Color.LIGHT_GRAY);
g.fillOval(point.x,point.y,20,20);
}
}
//添加一个点到界面上去
public void addPaint(Point point){
points.add(point);
}
//适配器模式
private class MyMouseListener extends MouseAdapter {
//鼠标动作:按下,弹起,按住不放
@Override
public void mousePressed(MouseEvent e) {
MyFrame myFrame = (MyFrame) e.getSource();
//这个是我们点击的时候,就会产生一个点,画
//这个点就是鼠标的点:
addPaint(new Point(e.getX(),e.getY()));
//每次点击鼠标都需要重新画一遍
repaint(); // 刷新
}
}
}
运行展示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1tOd3N1F-1658630497817)(C:\Users\根号X\AppData\Roaming\Typora\typora-user-images\image-20220703214101274.png)]
2.9窗口监听
2.10键盘监听
blic void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
@Override
public void paint(Graphics g) {
//画画,监听鼠标的事件
Iterator iterator = points.iterator();
while (iterator.hasNext()){
Point point = (Point) iterator.next();
g.setColor(Color.LIGHT_GRAY);
g.fillOval(point.x,point.y,20,20);
}
}
//添加一个点到界面上去
public void addPaint(Point point){
points.add(point);
}
//适配器模式
private class MyMouseListener extends MouseAdapter {
//鼠标动作:按下,弹起,按住不放
@Override
public void mousePressed(MouseEvent e) {
MyFrame myFrame = (MyFrame) e.getSource();
//这个是我们点击的时候,就会产生一个点,画
//这个点就是鼠标的点:
addPaint(new Point(e.getX(),e.getY()));
//每次点击鼠标都需要重新画一遍
repaint(); // 刷新
}
}
}
运行展示:
[外链图片转存中...(img-1tOd3N1F-1658630497817)]
## 2.9窗口监听
## 2.10键盘监听
唉,typora又不能用了,只有这个了咯,唉~~~