JavaGUI-01-AWT
简介
AWT
AWT介绍
AWT:抽象的窗口工具
GUI:图形用户编程
1.组件和容器
窗口(Windows)
Frame
package AWT_Study;
import java.awt.*;
public class Frame_Test {
public static void main(String[] args) {
//Frame,JDK,看源码
Frame frame = new Frame("我的第一个Java图形界面窗口");
//设置窗口大小
frame.setSize(400,400);
//设置背景颜色
frame.setBackground(new Color(1,1,1));
//设置弹出的初始位置
frame.setLocation(200,200);
//设置窗口大小固定(不可拉伸)
frame.setResizable(false);
//需要设置可见性
frame.setVisible(true);
}
}
回顾封装
package AWT_Study;
import java.awt.*;
public class Frame_Test02 {
public static void main(String[] args) {
//展示多个窗口
MyFrame myFrame1 = new MyFrame(100, 100, 200, 200, Color.blue);
MyFrame myFrame2 = new MyFrame(300, 100, 200, 200, Color.cyan);
MyFrame myFrame3 = new MyFrame(100, 300, 200, 200, Color.black);
MyFrame myFrame4 = new MyFrame(300, 300, 200, 200, Color.GREEN);
}
}
class MyFrame extends Frame {
//全局变量,可能存在多个窗口,需要计数
static int id = 0;
//构造方法,参数:初始坐标(x,y),长宽,颜色
public MyFrame(int x, int y, int w, int h, Color color) {
//调用父类构造方法,Frame(String);
//MyFrame1,MyFrame2...
super("MyFrame" + (++id));
//由于继承了Frame 可直接调用Frame的共有方法
setBounds(x, y, w, h);
setBackground(color);
setVisible(true);
}
}
面板(Panel)
Panel放在Frame里面
package AWT_Study;
import java.awt.*;
public class Panel_Test01 {
public static void main(String[] args) {
Frame frame = new Frame();
Panel panel = new Panel();
//设置布局(默认会把frame置顶)
frame.setLayout(null);
//设置frame
frame.setBounds(300,300,500,500);
frame.setBackground(new Color(204, 255, 124));
//设置panel
panel.setBounds(50,50,400,400);//设置坐标(相对于frame)
panel.setBackground(new Color(238, 248, 211, 176));
//给frame添加panel
//add(Component),Panel继承自Container继承自Component
frame.add(panel);
frame.setVisible(true);
}
}
2.布局管理器
- 流式布局-FlowLayout
package AWT_Study;
import java.awt.*;
public class FlowLayout_Test {
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.CENTER));
//frame.setLayout(new FlowLayout(FlowLayout.LEFT));
frame.setLayout(new FlowLayout(FlowLayout.RIGHT));
frame.setBounds(100,100,200,200);
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.setVisible(true);
}
}
以FlowLayout.RIGHT为例
- 东西南北中-BorderLayout
package AWT_Study;
import java.awt.*;
public class BorderLayout_Test {
public static void main(String[] args) {
Frame frame = new Frame();
Button north = new Button("North");
Button south = new Button("South");
Button west = new Button("West");
Button east = new Button("East");
Button center = new Button("Center");
frame.add(north,BorderLayout.NORTH);
frame.add(south,BorderLayout.SOUTH);
frame.add(west,BorderLayout.WEST);
frame.add(east,BorderLayout.EAST);
frame.add(center,BorderLayout.CENTER);
frame.setSize(100,100);
frame.setVisible(true);
}
}
- 表格布局-GridLayout
package AWT_Study;
import java.awt.*;
public class GridLayout_Test {
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");
Button button4 = new Button("button4");
Button button5 = new Button("button5");
Button button6 = new Button("button6");
frame.setLayout(new GridLayout(3,2));
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.add(button4);
frame.add(button5);
frame.add(button6);
frame.setSize(100,100);
frame.setVisible(true);
}
}
练习题
我的答案
//frame
Frame frame = new Frame();
frame.setBounds(200,200,500,300);
frame.setBackground(Color.black);
//设置为Grid布局 两行一列
frame.setLayout(new GridLayout(2,1));
//填充frame
Panel pUp = new Panel(new BorderLayout());
pUp.setBackground(Color.blue);
Panel pDown = new Panel(new BorderLayout());
pDown.setBackground(Color.GRAY);
frame.add(pUp);
frame.add(pDown);
//填充pUp
Button pUp_Button_west = new Button("west_Up");
Button pUp_Button_east = new Button("east_Up");
Panel pUp_Panel = new Panel(new GridLayout(2,1));
Button pUp_Panel_Button1 = new Button("pUp_Panel_Button1");
Button pUp_Panel_Button2 = new Button("pUp_Panel_Button2");
pUp_Panel.add(pUp_Panel_Button1);
pUp_Panel.add(pUp_Panel_Button2);
pUp.add(pUp_Button_west,BorderLayout.WEST);
pUp.add(pUp_Button_east,BorderLayout.EAST);
pUp.add(pUp_Panel,BorderLayout.CENTER);
//填充pDown
Button pDown_Button_west = new Button("west_Do");
Button pDown_Button_east = new Button("east_Do");
Panel pDown_Panel = new Panel(new GridLayout(2,2));
Button pDown_Panel_Button1 = new Button("pDown_Panel_Button1");
Button pDown_Panel_Button2 = new Button("pDown_Panel_Button2");
Button pDown_Panel_Button3 = new Button("pDown_Panel_Button3");
Button pDown_Panel_Button4 = new Button("pDown_Panel_Button4");
pDown_Panel.add(pDown_Panel_Button1);
pDown_Panel.add(pDown_Panel_Button2);
pDown_Panel.add(pDown_Panel_Button3);
pDown_Panel.add(pDown_Panel_Button4);
pDown.add(pDown_Button_west,BorderLayout.WEST);
pDown.add(pDown_Button_east,BorderLayout.EAST);
pDown.add(pDown_Panel,BorderLayout.CENTER);
更好的写法
//frame(装p1,p2)
Frame frame = new Frame();
frame.setBounds(200,200,500,300);
frame.setBackground(Color.black);
//设置为Grid布局 两行一列
frame.setLayout(new GridLayout(2,1));
//四个面板(p1装p2 p3装p4)
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));
//上面
p2.add(new Button("p2-Btn-1"));
p2.add(new Button("p2-Btn-2"));
p1.add(new Button("West-1"),BorderLayout.WEST);
p1.add(new Button("Eest-1"),BorderLayout.EAST);
p1.add(p2,BorderLayout.CENTER);
//下面
for (int i = 0; i < 4; i++) {
p4.add(new Button("for-"+i));
}
p3.add(new Button("West-2"),BorderLayout.WEST);
p3.add(new Button("Eest-2"),BorderLayout.EAST);
p3.add(p4,BorderLayout.CENTER);
frame.add(p1);
frame.add(p3);
frame.setVisible(true);
总结
3.事件与监听
1.ActionEvent
try1:一个Button的监听事件,点击按钮在控制台输出字符串
package AWT_Study;
import java.awt.*;
import java.awt.event.*;
public class ActionEvent_Test {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setSize(100,100);
Button button = new Button("Hello! I’m Button");
//因为addActionListener(ActionListener)需要一个ActionListener,所以要构造一个ActionListener
MyActionListenner myActionListenner = new MyActionListenner();
button.addActionListener(myActionListenner);
frame.add(button,BorderLayout.CENTER);
windowClose(frame);//关闭窗口
frame.setVisible(true);
}
//关闭窗口的事件
private static void windowClose(Frame frame){
//addWindowListener(WindowListener)
//我们需要在addWindowListener()中”填上“一个实现了WindowListener接口的“实现类”
//抽象类WindowAdapter implements WindowListener接口
/*
WindowAdapter是抽象类不能“new”(不能实例化)
我们需要在addWindowListener()的”括号里“
写一个匿名内部类
写出new出对象的具体的实现方法
相当于new了一个继承自addWindowListener抽象类的”实现类“
为什么不new一个继承自WindowListener接口的”实现类“呢?
因为继承接口就需要实现接口的所有方法,而这里我们只需要windowClosing()方法
所以选择继承抽象类addWindowListener,只需要重写windowClosing()方法就可以了
*/
frame.addWindowListener(new WindowAdapter() {
@Override
//点击关闭时
public void windowClosing(WindowEvent e) {
//退出程序
System.exit(0);
}
});
}
}
//public interface ActionListener extends EventListener
//ActionListener extends EventListener接口,需要实现void actionPerformed(ActionEvent var1)方法
//IDEA快捷键:选中“ActionListener” alt+insert
//事件监听
class MyActionListenner implements ActionListener{
@Override
public void actionPerformed(ActionEvent actionEvent) {
System.out.println("我是一个Button!!!");
}
}
补充:
1.extends和implements
(54条消息) java中extends和implements的区别_foreverhuylee的博客-CSDN博客
extends是继承类,implements是实现接口。
类只能继承一个,接口可以实现多个。
extends继承父类的时候可以重写父类的方法,也可以调用父类的非私有方法;implements实现接口,必须实现接口的所有方法
内部类和匿名内部类的用法
(54条消息) Java内部类和匿名内部类的用法_pan_jinquan的博客-CSDN博客_java匿名类和匿名内部类
try2:多个按钮共用一个事件(Listenner);
点击“start”按钮输出开始,点击“stop”按钮输出停止
package AWT_Study;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ActionEvent_Test02 {
public static void main(String[] args) {
Frame frame = new Frame("start-stop");
frame.setSize(200,200);
frame.setLayout(new GridLayout(2,1));
Button buttonStart = new Button("Start");
Button buttonStop = new Button("Stop");
//可以显示的设置按钮被点击后getActionCommand()返回的命令,默认值为按钮的label
///buttonStart.setActionCommand("START!");
MyMonitor myMonitor = new MyMonitor();
buttonStart.addActionListener(myMonitor);
buttonStop.addActionListener(myMonitor);
frame.add(buttonStart);
frame.add(buttonStop);
frame.setVisible(true);
}
}
class MyMonitor implements ActionListener {
@Override
public void actionPerformed(ActionEvent actionEvent) {
if(actionEvent.getActionCommand().equals("Start")){
System.out.println("开始");
}
if(actionEvent.getActionCommand().equals("Stop")){
System.out.println("停止");
}
}
}
2.输入框事件监听
文本框输入,控制台输出
public class Text_Test01 {
public static void main(String[] args) {
TextFrame textFrame = new TextFrame();
}
}
class TextFrame extends Frame{
public TextFrame(){
setSize(200,70);
TextField textField = new TextField();
add(textField);
//监听文本框输入的文字
TextListener textListener = new TextListener();
//按下enter触发事件
textField.addActionListener(textListener);
setVisible(true);
}
}
class TextListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent actionEvent) {
//拿到触发该事件的文本框(一个特定的实例)
//tF是个引用吧
TextField tF = (TextField)actionEvent.getSource();//返回一个Object对象,把它强制转化为TextField
System.out.println(tF.getText());
//清屏
tF.setText("");
}
}
简易计算器,组合+内部类回顾复习
oop原则:组合优先于继承 (可减少耦合)
class B{
...
}
//继承
class A extends B{
}
//组合
class A{
public B b;
}
//两种方式 A 都 可以用到 B 的功能
简易计算器,点击“=”后计算两数之和,同时清空输入框
1.面向过程实现(虽然用了类,但实际上是面向过程的思维)
(逻辑全部在计算器类的构造器中实现了,这是面向过程的写法)
public class calculator_Test {
public static void main(String[] args) {
calculator calculator = new calculator();
}
}
//计算器类
class calculator extends Frame{
public calculator(){
//三个文本框
TextField textF_A = new TextField(10);//可输入的最大长度
TextField textF_B = new TextField(10);
TextField textF_Sum = new TextField(20);
//一个标签
Label lableAdd = new Label("+");
//一个按钮
Button button = new Button("=");
//事件传参
button.addActionListener(new myCalculatorMonitor(textF_A, textF_B, textF_Sum));
//设置布局
setLayout(new FlowLayout());
//add
add(textF_A);
add(lableAdd);
add(textF_B);
add(button);
add(textF_Sum);
//大小自适应
pack();
setVisible(true);
}
}
//计算器监视器
class myCalculatorMonitor implements ActionListener{
private TextField tFA, tFB, tFS;
public myCalculatorMonitor(TextField textF_A, TextField textF_B, TextField textF_Sum) {
this.tFA = textF_A;
this.tFB = textF_B;
this.tFS = textF_Sum;
}
//按下等号按钮后
@Override
public void actionPerformed(ActionEvent actionEvent) {
//1.从前两个输入框获得两个加数
int a = Integer.parseInt(tFA.getText());//字符串转Int
int b = Integer.parseInt(tFB.getText());
//2.计算和,显示到第三个输入框
tFS.setText(""+(a+b));//不加括号输出的是字符串“a+b”,而不是a+b值的字符串
//3.清空前两个输入框
tFA.setText("");
tFB.setText("");
}
}
优化一次后的代码(更标准的面向对象编程:用到组合类)
(监听器类组合了计算机类)
public class calculator_Test {
public static void main(String[] args) {
Calculator calculator1 = new Calculator();
Calculator calculator2 = new Calculator();
Calculator calculator3 = new Calculator();
calculator1.loadFrame();
calculator2.loadFrame();
calculator3.loadFrame();
}
}
//计算器类
class Calculator extends Frame{
//属性(private只能在类内访问)
public TextField textF_A;
public TextField textF_B;
public TextField textF_Sum;
//方法
public void loadFrame(){
//实例化三个文本框属性
textF_A = new TextField(10);//可输入的最大长度
textF_B = new TextField(10);
textF_Sum = new TextField(20);
//实例化一个标签
Label lableAdd = new Label("+");
//实例化一个按钮
Button button = new Button("=");
//添加监视器(把自己作为参数传给监视器,当Button被按下后,监视器将拿到拥有这个Button的calculator实例)
button.addActionListener(new myCalculatorMonitor(this));
//设置布局
setLayout(new FlowLayout());
//add
add(textF_A);
add(lableAdd);
add(textF_B);
add(button);
add(textF_Sum);
//大小自适应
pack();
setVisible(true);
}
}
//计算器监视器
class myCalculatorMonitor implements ActionListener{
//属性(监视器类组合了计算机类,计算机类是在外部定义的)
Calculator calculator_Has_Pressed_Button;
//构造器
public myCalculatorMonitor(Calculator calculator) {
this.calculator_Has_Pressed_Button = calculator;
}
//按下等号按钮后的动作
@Override
public void actionPerformed(ActionEvent actionEvent) {
//1.从前两个输入框获得两个加数
int a = Integer.parseInt(calculator_Has_Pressed_Button.textF_A.getText());//字符串转Int
int b = Integer.parseInt(calculator_Has_Pressed_Button.textF_B.getText());
//2.计算和,显示到第三个输入框
calculator_Has_Pressed_Button.textF_Sum.setText(""+(a+b));//不加括号输出的是字符串“a+b”,而不是a+b值的字符串
//3.清空前两个输入框
calculator_Has_Pressed_Button.textF_A.setText("");
calculator_Has_Pressed_Button.textF_B.setText("");
}
}
依次按下等号按钮
完全改造为面向对象
上面代码中存在一个问题:有关计算的操作是在另一个类(myCalculatorMonitor)中完成的,我们希望可以直接在Calculator类中完成
使用内部类:实现更好的包装
内部类的最大好处:可以畅通无阻的访问外部的属性和方法!
具体操作:把监听器类作为计算器类的内部类(用面向对象的思维来看监听器是计算器的一个属性)
public class calculator_Test {
public static void main(String[] args) {
Calculator calculator1 = new Calculator();
Calculator calculator2 = new Calculator();
Calculator calculator3 = new Calculator();
calculator1.loadFrame();
calculator2.loadFrame();
calculator3.loadFrame();
}
}
//计算器类
class Calculator extends Frame{
//属性(private只能在类内访问)
public TextField textF_A;
public TextField textF_B;
public TextField textF_Sum;
//监听器(是计算器类“内部”的类,在计算器类的内部定义)
//内部类的最大好处:可以畅通无阻的访问外部的属性和方法!
//myCalculatorMonitor可以直接使用Calculator的所有属性和方法
private class myCalculatorMonitor implements ActionListener{
//按下等号按钮后的动作
@Override
public void actionPerformed(ActionEvent actionEvent) {
//1.从前两个输入框获得两个加数
int a = Integer.parseInt(textF_A.getText());//字符串转Int
int b = Integer.parseInt(textF_B.getText());
//2.计算和,显示到第三个输入框
textF_Sum.setText(""+(a+b));//不加括号输出的是字符串“a+b”,而不是a+b值的字符串
//3.清空前两个输入框
textF_A.setText("");
textF_B.setText("");
}
}
//方法
public void loadFrame(){
//实例化三个文本框属性
textF_A = new TextField(10);//可输入的最大长度
textF_B = new TextField(10);
textF_Sum = new TextField(20);
//实例化一个标签
Label lableAdd = new Label("+");
//实例化一个按钮
Button button = new Button("=");
//添加监视器
button.addActionListener(new myCalculatorMonitor());
//设置布局
setLayout(new FlowLayout());
//add
add(textF_A);
add(lableAdd);
add(textF_B);
add(button);
add(textF_Sum);
//大小自适应
pack();
setVisible(true);
}
}
3.画笔
public class Paint_Test {
public static void main(String[] args) {
new MyPaint().LoadFrame();
}
}
class MyPaint extends Frame{
public void LoadFrame(){
setBounds(200,200,500,400);
setVisible(true);
}
@Override
public void paint(Graphics g) {
g.setColor(Color.blue);
//椭圆(空心)
g.drawOval(100,100,50,60);
//椭圆(实心)
g.fillOval(200,200,50,60);
g.setColor(Color.BLACK);
g.fillRect(150,150,50,50);
}
}
4.鼠标监听
目标:在鼠标点击的处画上一个点
public class MouseListener_Test {
public static void main(String[] args) {
new MyFrame("画点").loadFrame();
}
}
class MyFrame extends Frame{
//属性
//存鼠标点击的所有坐标
private ArrayList points;
public MyFrame(String title){
//调用父类构造器
super(title);
}
public void loadFrame(){
setBounds(300,300,500,400);
//实例化points
points = new ArrayList<>();
//为窗口添加鼠标监听器
this.addMouseListener(new MyMouseMonitor());
setVisible(true);
}
//画points中的所有点
@Override
public void paint(Graphics g) {
g.setColor(Color.BLACK);
//用迭代器遍历points,画出points中存储的所有点
Iterator iterator = points.iterator();
while(iterator.hasNext()){
Point point = (Point) iterator.next();
g.fillOval(point.x,point.y,10,10);
}
}
//适配器模式
//MouseAdapter是MouseListener接口的一个实现类
//我们直接继承MouseAdapter,只需要重写MouseAdapter的部分方法即可
//(如果implement MouseListener接口的话需要实现接口的所有方法)
private class MyMouseMonitor extends MouseAdapter{
@Override
public void mousePressed(MouseEvent e) {
//监听的对象是MyFrame所以返回的是MyFrame类型
MyFrame frame = (MyFrame) e.getSource();
//获得mousePressed事件发生时,鼠标的坐标点
Point point = e.getPoint();
//把这个点存储到points中
frame.points.add(point);
//重新绘制
frame.repaint();//会调用paint方法(把所有的点重新画一遍)
}
}
}
5.窗口监听
public class WindowListener_Test {
public static void main(String[] args) {
new WindowFrame().loadFrame();
}
}
class WindowFrame extends Frame{
public void loadFrame(){
setBounds(200,200,300,200);
//用到匿名内部类
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println("窗口关闭中");
System.exit(0);
}
@Override
public void windowActivated(WindowEvent e) {
WindowFrame windowFrame = (WindowFrame) e.getSource();
windowFrame.setTitle("窗口已激活");
}
});
setVisible(true);
}
}
6.键盘监听
public class KeyListener_Test {
public static void main(String[] args) {
new KeyFrame().loadFrame();
}
}
class KeyFrame extends Frame{
public void loadFrame(){
this.setBounds(200,200,100,100);
this.setVisible(true);
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
//获得当前按下的是哪个键 每个键对应一个code(int类型)
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_A)
System.out.println("你按下了 A 键");
}
});
}
}

浙公网安备 33010602011771号