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号时需要做的事情@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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,所以我们需要构造一个ActionListenerbutton.addActionListener(myActionListener);frame.add(button);frame.pack();windowClose(frame);frame.setVisible(true);}private static void windowClose(Frame frame) {frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});}
}class MyActionListener implements ActionListener {@Overridepublic 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() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});}}class MyMonitor implements ActionListener {@Overridepublic 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 {@Overridepublic 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);}@Overridepublic 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 {@Overridepublic 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() {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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() {//键盘按下@Overridepublic void keyPressed(KeyEvent e) {//获得键盘按下的是哪一个键,通过当前的码值确定int keyCode = e.getKeyCode(); //不需要去记录这个数值,直接使用静态属性 VK_XXXSystem.out.println(keyCode);if (keyCode == KeyEvent.VK_UP) {System.out.println("↑");}}});}private void windowClose(Frame frame) {frame.addWindowListener(new WindowAdapter() {@Overridepublic 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() {@Overridepublic 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;}@Overridepublic 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() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});}
}//监听器类
class MyCalculatorListener implements ActionListener {//获得计算器这个对象,在一个类中组合另一个类Calculator calculator = null;public MyCalculatorListener(Calculator calculator) {this.calculator = calculator;}@Overridepublic 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 {@Overridepublic 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() {@Overridepublic 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);}//画笔@Overridepublic 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() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});
}