Swing图形用户界面编程之事件处理模式

简介: 笔记

图形界面的组件要响应用户操作,就必须添加事件处理机制。Swing采用AWT的事件处理模型进行事件处理。在事件处理的过程中涉及三个要素:

事件:是用户对界面的操作,例如按钮单击事件

事件源:是事件发生的场所,就是各个组件,例如按钮单击事件的事件源是按钮(Button)

事件处理者:是事件处理程序,在Java中事件处理者是实现特定接口的事件对象。

在事件处理模型中最重要的是事件处理者,它根据事件(假设XXXEvent事件)的不同会实现不同的接 口,这些接口命名为XXXListener,所以事件处理者也称为事件监听器。最后事件源通过 addXXXListener()方法添加事件监听,监听XXXEvent事件。


事件处理者可以是实现了XXXListener接口任何形式,即:外部类、内部类、匿名内部类和Lambda表 达式;如果XXXListener接口只有一个抽象方法,事件处理者还可以是Lambda表达式。为了访问窗口 中的组件方便,往往使用内部类、匿名内部类和Lambda表达式情况很多。

事件类型和事件监听器接口:

26.png


一、采用内部类处理事件


学习事件处理主要是复习之前所学的内部类以及Lambda知识;

事件处理模型示例 示例代码如下:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
 * @author : 蔡政洁
 * @email :caizhengjie888@icloud.com
 * @date : 2020/2/23
 * @time : 9:04 上午
 */
public class MyFrame extends JFrame {
//    声明标签
    JLabel label;
    public MyFrame(String title){
        super(title);
//        创建标签
        label = new JLabel("caizhengjie");
//        添加到内容面板
        getContentPane().add(label, BorderLayout.NORTH);
//        创建Button1
        JButton button1 = new JButton("Button1");
//        添加到内容面板
        getContentPane().add(button1,BorderLayout.CENTER);
//        创建Button2
        JButton button2 = new JButton("Button1");
//        添加到内容面板
        getContentPane().add(button2,BorderLayout.SOUTH);
//        设置窗口大小
        setSize(350,120);
//        设置窗口可见
        setVisible(true);
//        注册事件监听器,监听Button2单机事件,这里采用内部类写法
        button2.addActionListener(new ActionEventerHandler());
//        注册事件监听器,监听Button1单机事件,这里采用匿名内部类写法
        button1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                label.setText("Hello Swing");
            }
        });
    }
//        Button2事件处理者
    class ActionEventerHandler implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            label.setText("Hello World!");
        }
    }
}

调用代码:

public class HelloWorld {
    public static void main(String[] args) {
        MyFrame myFrame = new MyFrame("hehehe");
    }
}

运行结果:

28.png


二、采用Lambda表达式处理事件


如果一个事件监听器接口只有一个抽象方法,则可以使用Lambda表达式实现事件处理

展示代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
 * @author : 蔡政洁
 * @email :caizhengjie888@icloud.com
 * @date : 2020/2/23
 * @time : 9:25 上午
 */
public class MyFrame extends JFrame implements ActionListener {
//    声明标签
    JLabel label;
    public MyFrame(String title) {
        super(title);
//        创建标签
        label = new JLabel("caizhengjie");
//        添加到内容面板
        getContentPane().add(label, BorderLayout.NORTH);
//        创建Button1
        JButton button1 = new JButton("Button1");
//        添加到内容面板
        getContentPane().add(button1, BorderLayout.CENTER);
//        创建Button2
        JButton button2 = new JButton("Button1");
//        添加到内容面板
        getContentPane().add(button2, BorderLayout.SOUTH);
//        设置窗口大小
        setSize(350, 120);
//        设置窗口可见
        setVisible(true);
//        注册事件监听器,监听Button2单机事件
        button2.addActionListener(this);
//        注册事件监听器,监听Button1单机事件,这里采用Lambda表达式写法
        button1.addActionListener((envent) ->{
            label.setText("Hello World");
        });
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        label.setText("Hello Swing");
    }
}

调用代码:

public class Helloworld {
    public static void main(String[] args) {
        MyFrame myFrame = new MyFrame("caizhengjie");
    }
}

运行结果和上面一样


三、使用适配器


事件监听器都是接口,在Java中接口中定义的抽象方法必须全部是实现,哪怕你对某些方法并不关 心,你也要给一对空的大括号表示实现。

例如WindowListener是窗口事件(WindowEvent)监听器接 口,为了在窗口中接收到窗口事件,需要在窗口中注册WindowListener事件监听器,示例代码如下:

this.addWindowListener(new WindowListener() {
          @Override
          public void windowActivated(WindowEvent e) {
          }
          @Override
          public void windowClosed(WindowEvent e) {
          }
          @Override
          public void windowClosing(WindowEvent e) {            
// 退出系统
        System.exit(0); }
          @Override
          public void windowDeactivated(WindowEvent e) {
          }
          @Override
          public void windowDeiconified(WindowEvent e) {
          }
          @Override
          public void windowIconified(WindowEvent e) {
          }
          @Override
          public void windowOpened(WindowEvent e) {
          }
});

这样的代码看起来很臃肿,为此Java还提供了一些与监听器相配套的适配器。

监听器是接 口,命名采用XXXListener,而适配器是类,命名采用XXX Adapter。

使用适配器的目的是:在使用时通过继承事件所对应的 适配器类,覆盖所需要的方法,无关方法不用实现,使代码看起来简洁。


采用适配器注册接收窗口事件代码如下:

this.addWindowListener(new WindowAdapter(){ 
@Override
  public void windowClosing(WindowEvent e) { 
  // 退出系统
    System.exit(0);
  }
});


可见代码非常的简洁。事件适配器提供了一种简单的实现监听器的手段,可以缩短程序代码。

并非所有的监听器接口都有对应的适配器类,一般定义了多个方法的监听器接口,例如 WindowListener有多个方法对应多种不同的窗口事件时,才需要配套的适配器,主要的适配器如下:


ComponentAdapter:组件适配器。

ContainerAdapter:容器适配器。

FocusAdapter:焦点适配器。

KeyAdapter:键盘适配器。

MouseAdapter:鼠标适配器。

MouseMotionAdapter:鼠标运动适配器。

WindowAdapter:窗口适配器。


相关文章
|
容器
|
数据安全/隐私保护
|
1月前
|
JavaScript 前端开发
事件处理机制
【9月更文挑战第02天】
43 9
|
5月前
|
图形学 C++ 容器
QT信号与槽机制 和 常用控件介绍
QT信号与槽机制 和 常用控件介绍
QT信号与槽机制 和 常用控件介绍
|
5月前
|
前端开发 Java 程序员
【JAVA】<GUI编程>AWT & Swing 图形化编程库
【1月更文挑战第19天】【JAVA】<GUI编程>AWT & Swing 图形化编程库
|
Linux C# iOS开发
C#之十八 GUI用户界面编程
C#之十八 GUI用户界面编程
254 0
|
程序员 Python
Python Qt GUI设计:窗口之间数据传递(拓展篇—5)
在开发程序时,如果这个程序只有一个窗口,则应该关心这个窗口里面的各个控件之间是如何传递数据的。如果这个程序有多个窗口,那么还应该关心不同的窗口之间是如何传递数据的。 本篇博文首先给出一个例子,说明在一个窗口中不同控件之间的数据是如何传递的。对于多窗口的情况,一般有两种解决方法:一种是主窗口获取子窗口中控件的属性,另一种是通过信号与槽机制,一般是子窗口通过发射信号的形式传递数据,主窗口的槽函数获取这些数据。