事件、侦听器和适配器类

在发生活动(如按下按钮或关闭窗口)时会标注 Java™ bean 事件。Java 可视编辑器在 Java bean 视图中显示事件,您可以使用该视图来添加和除去事件。

Java bean 的已定义事件列表在其 BeanInfo 类中描述,该列表还控制常用或首选事件。

如果希望生成 Java bean 时发生某个事件(例如,按某个按钮时进行数据库更新),那么可向 Java bean 添加事件。引起事件的 Java bean 是源代码,在事件发生时回调的对象被称为侦听器。 每个 Java bean 都有一个接口,通过该接口它可以通知每个事件的侦听器,以及用于添加和除去侦听器的方法。

通常,如果源代码 Java bean 具有方法 XXX,那么会有侦听器接口 XXXListener 和两个方法。XXXListener 将扩展 java.util.EventListener,这一点很重要。如果没有扩展,那么除非提供了特定的 BeanInfo,否则无法发现事件。

XXXListener 接口本身的方法取决于事件的语义,但是它们的签名均为 void <eventOccurenceMethodName>(<EventStateObjectType> evt); 是约定的。XXXListener 将扩展 java.util.EventObject,这一点很重要。 如果没有扩展,那么除非提供了特定的 BeanInfo,否则无法发现事件。

事件的示例为 Java bean java.awt.Component,当鼠标移过它时,它会引起事件的发生。侦听器接口 java.awt.event.MouseMotionListener 将实现以下两种方法:

要添加鼠标侦听器,java.awt.Component 具有以下两种方法:

事件的第二种样式在属性值更改时由 Java bean 生成。此情况的一个示例为 javax.swing.JButton 上的“已启用”属性。 事件的值更改时触发该事件的属性被称为绑定属性。并非每个绑定属性都有一个独立的侦听器接口,而是存在一个通用侦听器接口 java.beans.PropertyChangeListener,该接口具有单个回调方法 void propertyCanged(PropertyChangeEvent evt);,参数 PropertyChangeEvent 具有该方法的接收器可以查询的三种方法:

String getPropertyName() 在 Java bean 上更改的导致事件触发的属性名称
Object getNewValue() 属性的新值
Object getOldValue() 更改前属性的值

有两种方法可用于表示对 Java bean 的属性更改感兴趣:void addPropertyChangeListener(PropertyChangeListener listener);void addPropertyChangeListener(String propertyName, PropertyChangeListener listener);

这些方法的第一个总是出现在具有绑定属性的 Java bean 上。但是,第二个方法是可选方法,它取决于 Java bean 的作者使用的事件注册样式。例如,AWT 组件使用属性更改注册的第一个样式,而 Swing 组件使用这两种样式。

存在三个可以使用事件的对象:

  1. 引起事件发生的 Java bean(源代码)
  2. 从源代码接收通知的类(侦听器)
  3. 实现回调侦听器时发生的逻辑的类。

通常将后两个对象组合在一起,以便执行逻辑的类会直接实现侦听器接口或使用内部类。Java 可视编辑器识别且生成的代码样式包含在“事件代码生成”上的部分内。

适配器类

许多侦听器接口有多个回调方法。此情况的一个示例为 java.awt.FocusListener,它有两种方法:focusGained(java.awt.FocusEvent event) 和 focusLost(java.awt.FocusEvent event)。创建实现接口的侦听器类时,Java 编译器将坚持实现所有的接口方法,通常这样做的结果是会创建多个空方法以满足其需求,而实际上仅有一个或几个方法包含代码。以下语句显示在 Java bean 获取焦点时,用于执行某个逻辑的 FocusListener。但是,必须提供空的 focusLost 方法。

Java bean.addFocusListener(new java.awt.event.FocusListener() {     
    public void focusGained(java.awt.event.FocusEvent e) {          
        doFocusGainedCode();      
     }          
        public void focusLost(java.awt.event.FocusEvent e) {      
     }  
});

为避免许多侦听器具有许多空侦听器方法,提供了适配器类。这些适配器类将实现侦听器接口并提供其方法的空(无操作)实现。这样做的优点是侦听器可以扩展这些方法,且仅对所选的方法进行特殊化处理,而无需对其余方法(继承自适配器)提供缺省实现。

Java bean.addFocusListener(new java.awt.event.FocusAdapter() {     
     public void focusGained(java.awt.event.FocusEvent e) {          
         doFocusGainedCode();      
         }  
   });

反馈