前言
推荐一个网站给想要了解或者学习人工智能知识的读者,这个网站里内容讲解通俗易懂且风趣幽默,对我帮助很大。我想与大家分享这个宝藏网站,请点击下方链接查看。 https://www.captainbed.cn/f1
AWT事件处理涉及Java AWT(抽象窗口工具包)中定义的事件及其处理机制。它允许开发者为图形用户界面组件(如按钮、文本框等)定义事件响应行为,如点击、键盘输入等。通过注册事件监听器并编写事件处理逻辑,AWT能够响应用户与界面元素的交互,实现动态和交互式的应用体验。
前面的文章介绍了如何放置各种组件,从而得到了丰富多彩的图形界面,但这些界面还不能响应用户的任何操作。比如单击前面所有窗口右上角的“X”按钮,但窗口依然不会关闭。因为在 AWT 编程中 ,所有用户的操作,都必须都需要经过一套事件处理机制来完成,而 Frame 和组件本身并没有事件处理能力 。
一、GUI事件处理机制
定义
当在某个组件上发生某些操作的时候,会自动的触发一段代码的执行。
在GUI事件处理机制中涉及到4个重要的概念需要理解:
事件源(Event Source):操作发生的场所,通常指某个组件,例如按钮、窗口等; 事件(Event):在事件源上发生的操作可以叫做事件,GUI会把事件都封装到一个Event对象中,如果需要知道该事件的详细信息,就可以通过Event对象来获取。 事件监听器(Event Listener):当在某个事件源上发生了某个事件,事件监听器就可以对这个事件进行处理。
注册监听:把某个事件监听器(A)通过某个事件(B)绑定到某个事件源( C )上,当在事件源C上发生了事件B之后,那么事件监听器A的代码就会自动执行。
使用步骤
- 创建事件源组件对象;
- 自定义类,实现XxxListener接口,重写方法;
- 创建事件监听器对象(自定义类对象)
- 调用事件源组件对象的addXxxListener方法完成注册监听
Swing事件处理机制与AWT的区别
Swing 的事件处理机制与 AWT 保持一致,甚至很多事件的处理仍然使用的是java.awt.event
包中的类和接口。为了扩展事件处理能力,在javax.swing.event
包中新增了一些新的事件类及其监听器接口。
二、GUI中常见事件和事件监听器
事件监听器必须实现事件监听器接口, AWT 提供了大量的事件监听器接口用于实现不同类型的事件监听器,用于监听不同类型的事件 。 AWT 中提供了丰富的事件类,用于封装不同组件上所发生的特定操作, AWT 的事件类都是 AWTEvent 类的子类 , AWTEvent是 EventObject 的子类。
事件
AWT把事件分为了两大类:
低级事件
这类事件是基于某个特定动作的事件。比如进入、点击、拖放等动作的鼠标事件,再比如得到焦点和失去焦点等焦点事件。
事件 | 触发时机 |
---|---|
ComponentEvent | 组件事件 , 当 组件尺寸发生变化、位置发生移动、显示/隐藏状态发生改变时触发该事件。 |
ContainerEvent | 容器事件 , 当容器里发生添加组件、删除组件时触发该事件 。 |
WindowEvent | 窗口事件, 当窗 口状态发生改变 ( 如打开、关闭、最大化、最 小化)时触发该事件 。 |
FocusEvent | 焦点事件 , 当组件得到焦点或失去焦点 时触发该事件 。 |
KeyEvent | 键盘事件 , 当按键被按下、松开、单击时触发该事件。 |
MouseEvent | 鼠标事件,当进行单击、按下、松开、移动鼠标等动作 时触发该事件。 |
PaintEvent | 组件绘制事件 , 该事件是一个特殊的事件类型 , 当 GUI 组件调 用 update/paint 方法 来呈现自身时触发该事件,该事件并非专用于事件处理模型 。 |
高级事件
这类事件并不会基于某个特定动作,而是根据功能含义定义的事件。
事件 | 触发时机 |
---|---|
ActionEvent | 动作事件 ,当按钮、菜单项被单击,在 TextField 中按 Enter 键时触发 |
AjustmentEvent | 调节事件,在滑动条上移动滑块以调节数值时触发该事件。 |
ltemEvent | 选项事件,当用户选中某项, 或取消选中某项时触发该事件 。 |
TextEvent | 文本事件, 当文本框、文本域里的文本发生改变时触发该事件。 |
事件监听器
不同的事件需要使用不同的监听器监听,不同的监听器需要实现不同的监听器接口, 当指定事件发生后 , 事件监听器就会调用所包含的事件处理器(实例方法)来处理事件 。
事件类别 | 描述信息 | 监听器接口名 |
---|---|---|
ActionEvent | 激活组件 | ActionListener |
ItemEvent | 选择了某些项目 | ItemListener |
MouseEvent | 鼠标移动 | MouseMotionListener |
MouseEvent | 鼠标点击等 | MouseListener |
KeyEvent | 键盘输入 | KeyListener |
FocusEvent | 组件收到或失去焦点 | FocusListener |
AdjustmentEvent | 移动了滚动条等组件 | AdjustmentListener |
ComponentEvent | 对象移动缩放显示隐藏等 | ComponentListener |
WindowEvent | 窗口收到窗口级事件 | WindowListener |
ContainerEvent | 容器中增加删除了组件 | ContainerListener |
TextEvent | 文本字段或文本区发生改变 | TextListener |
AWT事件类的继承关系
三、事件适配器
事件适配器(Adapter),本质上是一种特殊的类。它是一个或者多个事件监听器接口的实现类,为接口中的每个抽象方法进行了空实现,即在方法体经中没有任何语句。
当某个事件监听器接口中的抽象方法多于一个时,可能只对其中部分抽象方法的实现有需求。但是按照Java 语法规则,非抽象的事件监听器类必须实现接口中的全部方法;不但加大了编程工作量做无用功,而且增加程序的复杂度,降低程序的清晰度。为了解决此类问题,Java 中采用了事件适配器。很容易理解,Java 没有必要为每个事件监听器配备对应的事件适配器,只有抽象方法的数目超过一个的事件监听器才为之提供。
WindowListener、 KeyListener, MouseListener 和 MouseMotionListener 都有一个以上的抽象方法,因此在 java.awt.event 包中提供了相应的事件适配器 WindowAdapter、KeyAdapter、MouseAdapter、MouseMotionAdapter。
由于 Java 提供了事件适配器,事件监听器类可以通过继承事件适配器,按照需要来重写特定的事件处理方法,为编程带来了便利。但是,由于Java的类采用单一继承机制,当事件监听器类已经存在父类,或者需要实现多个事件监听器接口时,就不能再继承事件适配器。
三、示例
代码示例
示例一
完成下图效果,点击确定按钮,在单行文本域内显示 hello world
:
public class EventDemo1 { Frame frame = new Frame("这里测试事件处理");
//事件源 Button button = new Button("确定"); TextField tf = new TextField(30); public void init(){ //注册监听 button.addActionListener(new MyActionListener()); //添加组件到frame中 frame.add(tf); frame.add(button,BorderLayout.SOUTH); //设置frame最佳大小并可见 frame.pack(); frame.setVisible(true); } //自定义事件监听器类 private class MyActionListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { System.out.println("用户点击了确定按钮"); tf.setText("hello world"); } } public static void main(String[] args) { new EventDemo1().init(); }
}
- 通过ContainerListener监听Frame容器添加组件;
- 通过TextListener监听TextFiled内容变化;
- 通过ItemListener监听Choice条目选中状态变化;
示例二
import java.awt.*; import java.awt.event.ContainerAdapter; import java.awt.event.ContainerEvent; import java.awt.event.TextEvent; import java.awt.event.TextListener;
public class ListenerDemo1 {
public static void main(String[] args) { Frame frame = new Frame("这里测试监听器"); //创建一个单行文本域 TextField tf = new TextField(30); //给文本域添加TextListener,监听内容的变化 tf.addTextListener(new TextListener() { @Override public void textValueChanged(TextEvent e) { System.out.println("当前内容:"+tf.getText());; } }); //给frame注册ContainerListener监听器,监听容器中组件的添加 frame.addContainerListener(new ContainerAdapter() { @Override public void componentAdded(ContainerEvent e) { Component child = e.getChild(); System.out.println("容器中添加了新组件:"+child); } }); //添加tf到frame frame.add(tf); //设置frame最佳大小并可见 frame.pack(); frame.setVisible(true); }
}
示例三
给Frame设置WindowListner,监听用户点击 X 的动作,如果用户点击X,则关闭当前窗口
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;public class ListenerDemo2 {
public static void main(String[] args) { Frame frame = new Frame("这里测试WindowListener"); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setBounds(200,200,500,300); frame.setVisible(true); }
}