模块  java.desktop
软件包  java.beans

Class EventHandler

  • 实现的所有接口
    InvocationHandler

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

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

    内部类是处理来自用户界面的事件的另一种更通用的方法。 EventHandler类仅处理使用内部类可能的子集。 但是, EventHandler对于长期持久性方案比内部类更好。 此外,在大型应用程序中使用EventHandler ,其中多次实现相同的接口可以减少应用程序的磁盘和内存占用。

    使用EventHandler创建的侦听EventHandler具有如此小的占用空间的原因是EventHandler依赖的Proxy类共享相同接口的实现。 例如,如果使用EventHandler create方法在应用程序中生成所有ActionListener ,则所有动作侦听器都将是单个类的实例(一个由Proxy类创建)。 通常,基于Proxy类的侦听器需要为每个侦听器类型 (接口)创建一个侦听器类,而内部类方法需要为每个侦听器 (实现接口的对象)创建一个类。

    您通常不直接处理EventHandler实例。 而是使用EventHandler create方法之一来创建实现给定侦听器接口的对象。 此侦听器对象在EventHandler使用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 , nextFocusableComponent目标(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最常见的用法可能是从事件对象的源中提取属性值,并将此值设置为目标对象的属性值。 在下面的示例中,我们创建了一个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
    另请参见:
    Proxy , EventObject
    • 构造方法摘要

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

      所有方法  静态方法  实例方法 具体的方法 
      变量和类型 方法 描述
      static <T> T create​(类<T> listenerInterface, Object target, String action)
      创建 listenerInterface的实现,其中侦听器接口中的 所有方法都将处理程序的 action应用于 target 。
      static <T> T create​(类<T> listenerInterface, Object target, String action, String eventPropertyName)
      / **创建 listenerInterface的实现,其中 所有方法都将事件表达式的值 eventPropertyName给语句 action的最终方法,该方法应用于 target 。
      static <T> T create​(类<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)
      从事件中提取适当的属性值,并将其传递 EventHandler此 EventHandler关联的操作。
    • 方法详细信息

      • 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)
        从事件中提取适当的属性值,并将其传递 EventHandler此 EventHandler关联的操作。
        Specified by:
        invoke在界面 InvocationHandler
        参数
        proxy - 代理对象
        method - 侦听器接口中的方法
        arguments - 包含代理实例上方法调用中传递的参数值的对象数组,如果接口方法不带参数, null 。 原始类型的参数包含在适当的原始包装类的实例中,例如java.lang.Integer或java.lang.Boolean 。
        结果
        将操作应用于目标的结果
        另请参见:
        EventHandler
      • create

        public static <T> T create​(类<T> listenerInterface,
                                   Object target,
                                   String action,
                                   String eventPropertyName)
        / **创建listenerInterface的实现,其中所有方法都将事件表达式的值eventPropertyName给语句action的最终方法,该方法应用于target 。 这种方法是通过调用更普遍,贯彻实施create方法与listenerMethodName ,取值为null 。 请参阅the general version of create的完整描述action个eventPropertyName参数。

        要创建一个ActionListener ,设置一个的文本JLabel到的文本值JTextField输入事件的源,你可以使用下面的代码:

        EventHandler.create(ActionListener.class, label, "text", "source.text");
        
        这相当于以下代码:
        //Equivalent code using an inner class instead of EventHandler.
        new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                label.setText(((JTextField)(event.getSource())).getText());
             }
        };
        
        参数类型
        T - 要创建的类型
        参数
        listenerInterface - 为其创建代理的侦听器接口
        target - 将执行操作的对象
        action - 目标上的(可能是合格的)属性或方法的名称
        eventPropertyName - 传入事件的可读属性的(可能是合格的)名称
        结果
        实现 listenerInterface的对象
        异常
        NullPointerException - 如果 listenerInterface为空
        NullPointerException - 如果 target为空
        NullPointerException - 如果 action为空
        IllegalArgumentException - 如果为 listenerInterface创建代理服务器因 listenerInterface指定的任何限制而 失败
        另请参见:
        create(Class, Object, String, String, String) , Proxy.newProxyInstance(java.lang.ClassLoader, java.lang.Class<?>[], java.lang.reflect.InvocationHandler)
      • create

        public static <T> T create​(类<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 。 为了提取从“文本”属性MouseEvent带有JLabel源使用下列作为eventPropertyName : "source.text" , "getSource.text" "getSource.getText"或"source.getText" 。 如果找不到方法,或者在调用方法时生成异常,则会在调度时抛出RuntimeException 。 例如,如果传入的事件对象为null,并且eventPropertyName为非null且不为空,则将抛出RuntimeException 。

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

        如果listenerMethodName是null ,则界面中的所有方法都会触发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 - 如果为 listenerInterface创建代理服务器因 listenerInterface指定的任何限制而 失败
        另请参见:
        EventHandler , Proxy.newProxyInstance(java.lang.ClassLoader, java.lang.Class<?>[], java.lang.reflect.InvocationHandler)