Module  java.desktop
软件包  java.beans

Class EventHandler

  • All Implemented Interfaces:
    InvocationHandler


    public class EventHandler
    extends Object
    implements InvocationHandler
    EventHandler类提供了动态生成事件侦听器的支持,该侦听器的方法执行一个涉及传入事件对象和目标对象的简单语句。

    EventHandler类旨在由交互式工具(如应用程序构建器)使用,允许开发人员在bean之间建立连接。 通常,连接是从用户界面bean(事件 )到应用程序逻辑bean( 目标 )进行的。 这种最有效的连接将应用程序逻辑与用户界面隔离开来。 例如, EventHandler用于从一个连接JCheckBox到接受布尔值可以处理提取的复选框的状态,并直接将其传递给该方法,使得该方法是从用户界面层分离的方法。

    内部类是从用户界面处理事件的另一种更通用的方式。 EventHandler类只处理内部类可能使用的一个子集。 然而, EventHandler比内部类更好地与长期持久性方案相比。 此外,在大型应用中使用EventHandler ,其中实现了相同的接口多次可以减少应用程序的磁盘和内存占用。

    听众用EventHandler创建的这样一个小小的原因是EventHandler依赖的Proxy类共享相同接口的实现。 例如,如果您使用EventHandler create方法来使所有ActionListener在应用程序中,则所有操作监听器都将是单个类的实例(由Proxy类创建)。 一般来说,基于Proxy类的监听器需要每个监听器类型 (接口)创建一个监听器类,而内部类方法需要为每个监听器 (实现接口的对象)创建一个类。

    您一般不直接处理EventHandler实例。 相反,您可以使用EventHandler create一个来创建实现给定侦听器接口的对象。 此侦听器对象使用EventHandler对象来封装有关事件的信息,发生事件时要发送消息的对象,要发送的消息(方法)以及方法的任何参数。 以下部分将介绍如何使用create方法创建侦听器对象的create

    使用EventHandler的示例

    最简单的使用EventHandler是安装一个侦听器,它调用目标对象上没有参数的方法。 在下面的例子中,我们创建ActionListener调用该toFront上的一个实例方法javax.swing.JFrame
    myButton.addActionListener(
        (ActionListener)EventHandler.create(ActionListener.class, frame, "toFront"));
    
    myButton被按下时,声明frame.toFront()将被执行。 通过定义ActionListener接口的新实现并向其中添加一个实例,可以获得相同的效果,并具有一些额外的编译时类型安全性:
    //Equivalent code using an inner class instead of EventHandler.
    myButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            frame.toFront();
        }
    });
    
    EventHandler的下一个最简单的使用是从侦听器接口(通常是一个事件对象)中的方法的第一个参数中提取一个属性值,并使用它来设置目标对象中的属性的值。 在下面的示例中,我们创建一个ActionListener ,将目标(myButton)对象的nextFocusableComponent属性设置为事件“source”属性的值。
    EventHandler.create(ActionListener.class, myButton, "nextFocusableComponent", "source")
    
    这将对应于以下内部类实现:
    //Equivalent code using an inner class instead of EventHandler.
    new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            myButton.setNextFocusableComponent((Component)e.getSource());
        }
    }
    
    也可以创建一个EventHandler ,将传入的事件对象传递到目标的动作。 如果第四个EventHandler.create参数是一个空字符串,那么事件刚刚传递:
    EventHandler.create(ActionListener.class, target, "doActionEvent", "")
    
    这将对应于以下内部类实现:
    //Equivalent code using an inner class instead of EventHandler.
    new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            target.doActionEvent(e);
        }
    }
    
    EventHandler可能最常见的EventHandler是从事件对象的中提取属性值,并将此值设置为目标对象属性的值。 在以下示例中,我们创建一个ActionListener ,它将目标对象的“label”属性设置为源的“text”属性(“source”属性的值)的值。
    EventHandler.create(ActionListener.class, myButton, "label", "source.text")
    
    这将对应于以下内部类实现:
    //Equivalent code using an inner class instead of EventHandler.
    new ActionListener {
        public void actionPerformed(ActionEvent e) {
            myButton.setLabel(((JTextField)e.getSource()).getText());
        }
    }
    
    事件属性可以是“合格的”,其中包含用“。”分隔的任意数量的属性前缀。 字符。 出现在“。”之前的“合格”名称。 字符被作为应该应用的属性的名称,最左边首先是事件对象。

    例如,以下动作侦听器

    EventHandler.create(ActionListener.class, target, "a", "b.c.d")
    
    可以写成以下内部类(假设所有属性都有规范的getter方法并返回适当的类型):
    //Equivalent code using an inner class instead of EventHandler.
    new ActionListener {
        public void actionPerformed(ActionEvent e) {
            target.setA(e.getB().getC().isD());
        }
    }
    
    目标属性也可以是“合格的”,具有用“。”分隔的任意数量的属性前缀。 字符。 例如,以下动作侦听器:
      EventHandler.create(ActionListener.class, target, "a.b", "c.d") 
    可以写成以下内部类(假设所有属性都有规范的getter方法并返回适当的类型):
      //Equivalent code using an inner class instead of EventHandler.
       new ActionListener {
         public void actionPerformed(ActionEvent e) {
             target.getA().setB(e.getC().isD());
        }
    } 

    由于EventHandler最终依赖反射来调用一种方法,我们建议您针对重载方法。 例如,如果目标是MyTarget类的实例,它被定义为:

      public class MyTarget {
         public void doIt(String);
         public void doIt(Object);
       } 
    然后方法doIt过载。 EventHandler将调用基于源的适当方法。 如果源为null,那么任一方法都是合适的,并且调用的方法是未定义的。 因此,我们建议不要使用重载方法。
    从以下版本开始:
    1.4
    另请参见:
    ProxyEventObject
    • 构造方法摘要

      构造方法  
      Constructor 描述
      EventHandler​(Object target, String action, String eventPropertyName, String listenerMethodName)
      创建一个新的EventHandler对象; 您通常使用create方法之一,而不是直接调用此构造函数。
    • 方法摘要

      所有方法  静态方法  接口方法  具体的方法 
      Modifier and Type 方法 描述
      static <T> T create​(Class<T> listenerInterface, Object target, String action)
      创建一个 listenerInterface的实现,其中监听器界面中的 所有方法将处理程序的 action应用于 target
      static <T> T create​(Class<T> listenerInterface, Object target, String action, String eventPropertyName)
      / **创建的实施 listenerInterface ,其中 所有的方法传递事件表达,的值 eventPropertyName ,到最后方法中的发言, action ,其被施加到 target
      static <T> T create​(Class<T> listenerInterface, Object target, String action, String eventPropertyName, String listenerMethodName)
      创建的实施 listenerInterface其中命名方法 listenerMethodName传递事件表达,的值 eventPropertyName ,在语句中的最终方法, action ,其被施加到 target
      String getAction​()
      返回此事件处理程序将设置的目标的可写属性的名称,或此事件处理程序将在目标上调用的方法的名称。
      String getEventPropertyName​()
      返回在应用于目标的操作中应该使用的事件的属性。
      String getListenerMethodName​()
      返回将触发操作的方法的名称。
      Object getTarget​()
      返回此事件处理程序将发送消息的对象。
      Object invoke​(Object proxy, 方法 method, Object[] arguments)
      从事件中提取适当的属性值,并将其传递 EventHandlerEventHandler相关联的操作。
    • 方法详细信息

      • getAction

        public String getAction​()
        返回此事件处理程序将设置的目标的可写属性的名称,或此事件处理程序将在目标上调用的方法的名称。
        结果
        这个事件处理程序的动作
        另请参见:
        EventHandler(Object, String, String, String)
      • getListenerMethodName

        public String getListenerMethodName​()
        返回将触发操作的方法的名称。 返回值为null表示侦听器接口中的所有方法触发操作。
        结果
        将触发操作的方法的名称
        另请参见:
        EventHandler(Object, String, String, String)
      • invoke

        public Object invoke​(Object proxy,
                             方法 method,
                             Object[] arguments)
        从事件中提取适当的属性值,并将其传递 EventHandlerEventHandler相关联的操作。
        Specified by:
        invoke在接口 InvocationHandler
        参数
        proxy - 代理对象
        method - 监听器界面中的方法
        arguments - 包含代理实例上方法调用中传递的参数值的对象数组,如果接口方法不带参数, null 原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integerjava.lang.Boolean
        结果
        将动作应用于目标的结果
        另请参见:
        EventHandler
      • create

        public static <T> T create​(Class<T> listenerInterface,
                                   Object target,
                                   String action,
                                   String eventPropertyName,
                                   String listenerMethodName)
        创建的实施listenerInterface其中命名方法listenerMethodName传递事件表达,的值eventPropertyName ,在语句中的最终方法, action ,其被施加到target 所有其他侦听器方法什么都不做。

        eventPropertyName字符串用于从传入到目标方法的传入事件对象中提取值。 常见的情况是目标方法没有参数,在这种情况下, eventPropertyName应该使用null值。 或者,如果要将传入的事件对象直接传递到目标方法,则使用空字符串。 eventPropertyName字符串的格式是将每个方法或属性应用于从传入事件对象开始的上一个方法返回的值的一系列方法或属性。 语法是: propertyName{.propertyName}*其中propertyName匹配方法或属性。 例如,提取point从属性MouseEvent ,你可以使用任何"point"或者"getPoint"eventPropertyName 为了提取从“文本”属性MouseEventJLabel源使用下列作为eventPropertyName"source.text""getSource.text" "getSource.getText""source.getText" 如果无法找到方法,或者作为调用方法的一部分生成异常,则将在调度时抛出RuntimeException 例如,如果传入的事件对象为空,并且eventPropertyName为非空且不为空,则将抛出RuntimeException

        action参数与eventPropertyName参数的格式相同,后一个属性名称标识方法名称或可写属性。

        如果listenerMethodNamenull接口中的所有方法触发action要在执行target

        例如,要创建一个MouseListener ,每当按下鼠标按钮时,将目标对象的origin属性设置为传入的MouseEvent的位置(值为mouseEvent.getPoint() ),则可以写入:

        EventHandler.create(MouseListener.class, target, "origin", "point", "mousePressed");
        
        这相当于编写一个MouseListener ,其中除mousePressed之外的所有方法都是no-ops:
        //Equivalent code using an inner class instead of EventHandler.
        new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                target.setOrigin(e.getPoint());
            }
        };
         
        参数类型
        T - 要创建的类型
        参数
        listenerInterface - 创建代理的侦听器接口
        target - 将执行操作的对象
        action - 目标上的(可能合格的)属性或方法的名称
        eventPropertyName - 传入事件的可读属性的(可能限定的)名称
        listenerMethodName - 侦听器界面中触发操作的方法的名称
        结果
        一个实现 listenerInterface的对象
        异常
        NullPointerException - 如果 listenerInterface为空
        NullPointerException - 如果 target为空
        NullPointerException - 如果 action为空
        IllegalArgumentException - 如果创建 IllegalArgumentException的代理因 listenerInterface指定的任何限制 失败
        另请参见:
        EventHandlerProxy.newProxyInstance(java.lang.ClassLoader, java.lang.Class<?>[], java.lang.reflect.InvocationHandler)