在本章中,我们将会详细了解使用Swing组件的一个方面:事件处理。当使用Swing组件集合时,我们可以使用基于委托的事件处理机制,但是我们也可以使用其他的方法来响应用户的动作。在本章中,我们将会探索所有这些事件处理响应机制。我们同时也会了解到Swing是如何管理输入焦点以及控制输入焦点处理的相关技术。
当我们探索事件处理功能时,我们将会开始了解一些实际的Swing组件。在本章中,我们将会以最简单的方式来使用Swing组件。我们可以先阅读本书后面章节中所探讨的组件,然后再回到本章探讨事件处理。本书的后面章节中也包含每一个组件特定的事件处理的详细内容。
2.1 基于委托的事件处理
Sun在JDK.1.1及JavaBean的Java库中引入了基于委托的事件处理机制。尽管Java 1.0库中包含了遵循观察者行为设计模式的对象观察者对,但这并不是用户界面编程的长久解决方案。
2.1.1 事件委托模型
基于委托的事件处理机制是观察者设计模式的一种特殊形式。当一个观察者希望希望一个被监视的对象状态何时发生变化以及状态变化是什么时可以使用观察者模式。在基于委托的事件处理机制中,观察者并不监听状态改变,而是监听事件发生。
图2-1显示了在Java库中与事件处理的特定类相关的修改后的观察者模式结构。模式中的通用Subject管理一个用于Subject可以生成的事件的通用观察者对象列表。列表中的观察者对象必须提供一个特定的接口,通过这个接口Subject参与者可以通知他们。当观察者对象所感兴趣的事件在Subject参与者中发生时,所有已注册的观察者对象都会被通知到。在Java世界中,观察者对象要实现的接口必须扩展java.util.EventListener接口。Subject参与者必须创建的事件需要扩展java.util.EventObject类。
为了使得讨论更为清晰,下面我们由非设计模式的角度来了解基于委托的事件处理机制。GUI组件(JavaBean)管理一个监听器列表,每一个监听器会有用于监听器类型的一对方法:addXXXListener()与removeXXXListener()。当组件中有事件发生时,组件会通知所有注册的事件监听器。任何对该事件感兴趣的观察者类需要向组件注册一个相应接口的实现器。当事件发生时,所有的实现都被通知。图2-2尝过了这个过程。
2.1.2 作为观察者的事件监听器
使用事件监听器来处理事件分为三步:
- 定义一个类来实现相应的监听器接口(这包括为所有的接口方法提供实现)。
- 创建这个监听器的一个实例。
- 将监听器注册到我们所感兴趣的的事件的组件上。
下面我们通过创建一个简单的通过输出消息来响应选择的按钮来了解一下这三个特定步骤。
定义监听器
要为了一个可选择的按钮设置事件处理,我们需要创建一个ActionListener,因为JButton在被选中时会生成ActionEvent对象。
-
class AnActionListener implements ActionListener { public void actionPerformed(ActionEvent actionEvent) { System.out.println("I was selected."); } }
创建监听器实例
接下来我们简单的创建一个我们所定义的监听器的实例。
-
ActionListener actionListener = new AnActionListener();
如果我们为事件监听器使用匿名内联类,我们就可以组合步骤1与2:
-
ActionListener actionListener = new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { System.out.println("I was selected."); } };
向组件注册监听器
一旦我们创建了监听器,我们就可以将其与相应的组件相关联。假定我们已经创建JButton,并将其引用存入在变量button中,我们可以通过调用按钮的addActionListener()方法来实现:
-
button.addActionListener(actionListener);
如果我们当前所定义的类就是实现监听器接口的类,那么我们就不需要创建一个单独的监听器实例。我们只需要将作为监听器的类与组件相关联。如下面的示例代码所示:
-
public class YourClass implements ActionListener { ... // Other code for your class public void actionPerformed(ActionEvent actionEvent) { System.out.println("I was selected."); } // Code within some method JButton button = new JButton(...); button.addActionListener(this); // More code within some method }
以如上所示创建监听器并将其与组件相关联的方法使用事件处理器是响应Swing组件事件的基本方法。哪一个监听器与哪一个组件配合使用将会在后面的章节中描述相应的组件时进行讨论。在下面的内容中,我们将会了解到响应事件的一些其他方法。