JAVA从入门到放弃23—GUI/AWT

01 GUI图形用户界面

  • 用于基本GUI程序设计的类库:AWT和Swing
AWT:Abstract Window Toolkit,抽象窗口工具箱,基于对等体方法。
Swing:不对等基于GUI工具箱,Java基础类库JFC的一部分

注:Swing没有完全替代AWT。而是基于AWT架构之上。在采用Swing编写的程序中,还需要使用基本的AWT处理事件。
绝大多数Swing组件类都以J开头,例如JButton、JFrame等。

02 AWT概述

  • 组件Component类/容器Container类/事件监听ActionListener接口
Component 是一个具有图形表示能力的对象,可在屏幕上显示,并可与用户进行交互。Component 类是与菜单不相关的 Abstract Window Toolkit 组件的抽象超类。
常用子类有:
	Label 继承了Component,对象是一个可在容器中放置文本的组件。一个标签只显示一行只读文本。
    Button 继承了Component,此类创建一个标签按钮。当按下该按钮时,应用程序能执行某项动作。
Container继承了Component类,一般的 Abstract Window Toolkit(AWT) 容器对象是一个可包含其他 AWT 组件的组件。
常用子类有:
	Panel继承了Container类,是最简单的容器类。应用程序可以将其他组件放在面板提供的空间内,这些组件包括其他面板。
	window 继承了Container类,是一个没有边界和菜单栏的顶层窗口。
	(Frame 继承了Window类,是带有标题和边框的顶层窗口。窗体的大小包括为边框指定的所有区域。)
ActionListener 用于接收操作事件的侦听器接口。对处理操作事件感兴趣的类可以实现此接口,而使用该类创建的对象可使用组件的 addActionListener 方法向该组件注册。在发生操作事件时,调用该对象的 actionPerformed 方法。
  • Component常用方法
void add(PopupMenu popup) 
          向组件添加指定的弹出菜单。 
void addComponentListener(ComponentListener l) 
          添加指定的组件侦听器,以接收发自此组件的组件事件。 
void addKeyListener(KeyListener l) 
          添加指定的按键侦听器,以接收发自此组件的按键事件。 
void addMouseListener(MouseListener l) 
          添加指定的鼠标侦听器,以接收发自此组件的鼠标事件。 
void addActionListener(ActionListener l) 
          添加指定的事件侦听器,在发生操作事件时,调用该对象的 actionPerformed 方法。           
void setBackground(Color c) 
          设置组件的背景色。 
void setBounds(int x, int y, int width, int height) 
          移动组件并调整其大小。 
void setBounds(Rectangle r) 
          移动组件并调整其大小,使其符合新的有界矩形 r。 
void setFont(Font f) 
          设置组件的字体。 
void setSize(Dimension d) 
         调整组件的大小,使其宽度为 d.width,高度为 d.height。 
void setSize(int width, int height) 
         调整组件的大小,使其宽度为 width,高度为 height。 
void setVisible(boolean b) 
         根据参数 b 的值显示或隐藏此组件。
  • Container常用方法
Component add(Component comp) 
          将指定组件追加到此容器的尾部。 
void setFont(Font f) 
          设置此容器的字体。 
void setLayout(LayoutManager mgr) 
          设置此容器的布局管理器。  


注释:LayoutManager接口:定义知道如何布置 Container 类的接口。
     常用的LayoutManager接口的实现类有BorderLayout,FlowLayout,GridLayout等
     BorderLayout是一个布置容器的边框布局,它可以对容器组件进行安排,并调整其大小,使其符合下列五个区域:北、南、东、西、中。每个区域最多只能包含一个组件,并通过相应的常量进行标识:NORTH、SOUTH、EAST、WEST、CENTER。
     FlowLayout流布局用于安排有向流中的组件,这非常类似于段落中的文本行。流布局一般用来安排面板中的按钮。它使得按钮呈水平放置,直到同一条线上再也没有适合的按钮。线的对齐方式由 align 属性确定。可能的值为: 
LEFT RIGHT CENTER LEADING TRAILING 
	GridLayout类是一个布局处理器,它以矩形网格形式对容器的组件进行布置。容器被分成大小相等的矩形,一个矩形中放置一个组件。通常通过构造方法GridLayout(int rows, int cols) 创建具有指定行数和列数的网格布局。
  • window常用方法
void addWindowFocusListener(WindowFocusListener l) 
         添加指定的窗口焦点侦听器,以从此窗口接收窗口事件。 
void addWindowListener(WindowListener l) 
         添加指定的窗口侦听器,以从此窗口接收窗口事件。 
void addWindowStateListener(WindowStateListener l) 
         添加指定的窗口状态侦听器,以从此窗口接收窗口事件。 
void pack() 
         调整此窗口的大小,以适合其子组件的首选大小和布局。 
void setBounds(int x, int y, int width, int height) 
         移动组件并调整其大小。 
void setBounds(Rectangle r) 
         移动组件并调整其大小,使其符合新的有界矩形 r。 
void setSize(Dimension d) 
         调整组件的大小,使其宽度为 d.width,高度为 d.height。 
void setSize(int width, int height) 
         调整组件的大小,使其宽度为 width,高度为 height。 
void setVisible(boolean b) 
         根据参数 b 的值显示或隐藏此 Window 
void setAlwaysOnTop(boolean alwaysOnTop) 
         设置此窗口是否应该始终位于其他窗口上方
  • Panel的构造方法和常用方法
构造方法:
Panel() 
          使用默认的布局管理器创建新面板。 
Panel(LayoutManager layout) 
          创建具有指定布局管理器的新面板。 
常用方法:
panel对象主要使用父类Container和Component提供的方法
  • Frame的构造方法和常用方法
构造方法:
Frame() 
          构造一个最初不可见的 Frame 新实例()。 
Frame(GraphicsConfiguration gc) 
          使用指定的 GraphicsConfiguration 构造一个最初不可见的新 Frame。 
Frame(String title) 
          构造一个新的、最初不可见的、具有指定标题的 Frame 对象。 
Frame(String title, GraphicsConfiguration gc) 
          构造一个新的、初始不可见的、具有指定标题和 GraphicsConfiguration 的 Frame 对象。 
常用方法:
Frame对象主要使用父类Window,Container和Component提供的方法
  • Label的构造方法和常用方法
构造方法:
Label() 
          构造一个空标签。 
Label(String text) 
          使用指定的文本字符串构造一个新的标签,其文本对齐方式为左对齐。 
Label(String text, int alignment) 
          构造一个显示指定的文本字符串的新标签,其文本对齐方式为指定的方式。 
常用方法:
void setText(String text) 
          将此标签的文本设置为指定的文本。 
String getText() 
          获取此标签的文本。
  • Button的构造方法和常用方法
构造方法:
Button() 
          构造一个标签字符串为空的按钮。 
Button(String label) 
          构造一个带指定标签的按钮。 
常用方法:
Button对象主要使用父类Component提供的方法

02 示例

//通过封装类快速创建四个小窗口
public class Test {
    public static void main(String[] args) {
        MyFrame f1 = new MyFrame(100, 100, 200, 200, Color.red);
        MyFrame f2 = new MyFrame(300, 100, 200, 200, Color.blue);
        MyFrame f3 = new MyFrame(100, 300, 200, 200, Color.yellow);
        MyFrame f4 = new MyFrame(300, 300, 200, 200, Color.black);
    }
}

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);
        setLayout(null);//布局为空
        setBounds(x,y,w,h);
        setVisible(true);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }

        });
    }
}

运行结果:



//使用流布局创建一个窗口
public class Test {
    public static void main(String[] args) {
        Frame frame = new Frame("Frame");
        Button button1 = new Button("File");
        button1.setSize(20,20);
        Button button2 = new Button("Edit");
        button2.setSize(20,20);
        frame.setBounds(200,200,500,500);
        frame.setBackground(Color.lightGray);
        frame.add(button1);
        frame.add(button2);
        frame.setLayout(new FlowLayout(FlowLayout.LEFT));
        frame.setVisible(true);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

运行结果:



//使用BorderLayout布局创建一个窗口
public class Test {
    public static void main(String[] args) {
        Frame frame = new Frame("Frame");
        Button button1 = new Button("East");
        Button button2 = new Button("West");
        Button button3 = new Button("South");
        Button button4 = new Button("North");
        Button button5 = new Button("Center");
        frame.add(button1,BorderLayout.EAST);
        frame.add(button2,BorderLayout.WEST);
        frame.add(button3,BorderLayout.SOUTH);
        frame.add(button4,BorderLayout.NORTH);
        frame.add(button5,BorderLayout.CENTER);
        frame.setSize(500,500);
        frame.setVisible(true);

    }
}

运行结果:



//使用网格布局建立一个窗口
public class Test{
    public static void main(String[] args) {
        Frame frame = new Frame("Frame");
        Button button1 = new Button("1");
        Button button2 = new Button("2");
        Button button3 = new Button("3");
        Button button4 = new Button("4");
        frame.setLayout(new GridLayout(4,1));
        frame.setSize(500,500);
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);
        frame.add(button4);
        frame.setVisible(true);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

运行结果:



//使用多种布局管理实现一个综合窗口
public class Test{
    public static void main(String[] args) {
        Frame frame = new Frame("Frame");
        frame.setLayout(new GridLayout(2,1));
        frame.setSize(500,500);

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

        p1.add(new Button("W1"),BorderLayout.WEST);
        p1.add(new Button("E1"),BorderLayout.EAST);
        p2.add(new Button("C1"));
        p2.add(new Button("C2"));
        p3.add(new Button("W2"),BorderLayout.WEST);
        p3.add(new Button("E2"),BorderLayout.EAST);

        for (int i = 1; i <= 4; i++) {
            p4.add(new Button("C"+i));
        }

        p1.add(p2,BorderLayout.CENTER);
        p3.add(p4,BorderLayout.CENTER);

        frame.add(p1);
        frame.add(p3);

        frame.setVisible(true);

        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

运行结果:



//使用事件侦听实现一个计算器
public class Test07 {
    public static void main(String[] args) {
        Frame frame = new Frame("Calculator");
        frame.setBounds(100,200,700,300);
        frame.setVisible(true);

        Panel panel = new Panel();

        TextField textField1 = new TextField(10);
        TextField textField2 = new TextField(10);
        TextField textField3 = new TextField(10);

        Label label1 = new Label("+");

        Button button = new Button("=");
        Label label = new Label();

        panel.setLayout(new FlowLayout());
        panel.add(textField1);
        panel.add(label1);
        panel.add(textField2);
        panel.add(button);
        panel.add(textField3);
        panel.add(label);

        frame.add(panel);


        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
		//给按钮添加事件监听,传入ActionListener的已实现类
        button.addActionListener(new MyActionPerformed(textField1,textField2,textField3,label));


    }
}
//自定义一个监听事件实现ActionListener接口,必须重写actionPerformed方法
class MyActionPerformed implements ActionListener{

    TextField textField1,textField2,textField3;
    Label label;

     public MyActionPerformed() {
     }

     public MyActionPerformed(TextField textField1, TextField textField2, TextField textField3, Label label) {
         this.textField1 = textField1;
         this.textField2 = textField2;
         this.textField3 = textField3;
         this.label = label;
     }

     @Override
     public void actionPerformed(ActionEvent e) {
         String text1 = textField1.getText();
         String text2 = textField2.getText();

         textField3.setText(Integer.parseInt(text1)+Integer.parseInt(text2)+"");

         textField1.setText("");
         textField2.setText("");
         label.setText(textField3.getText());
         label.setSize(100,20);
     }
 }

运行结果: