- 所有已实现的接口:
InvocationHandler
EventHandler
类支持动态生成事件监听器,其方法执行涉及传入事件对象和目标对象的简单语句。
EventHandler
类旨在供交互式工具(例如应用程序构建器)使用,这些工具允许开发人员在 bean 之间建立连接。通常,连接是从用户接口 bean(事件 source)到应用程序逻辑 bean(target)。这种最有效的连接将应用程序逻辑与用户接口隔离开来。例如,从 JCheckBox
到接受boolean的方法的连接的 EventHandler
可以处理提取复选框的状态并将其直接传递给方法,以便该方法与用户接口层隔离。
内部类是另一种更通用的处理用户接口事件的方法。 EventHandler
类仅处理使用内部类可能的子集。但是,EventHandler
比内部类更适合长期持久化方案。此外,在多次实现相同接口的大型应用程序中使用 EventHandler
可以减少应用程序的磁盘和内存占用。
使用 EventHandler
创建的监听器占用空间如此之小的原因是 EventHandler
所依赖的 Proxy
类共享相同接口的实现。例如,如果您使用 EventHandler create
方法在应用程序中生成所有 ActionListener
,则所有动作监听器都将是单个类(由 Proxy
类创建)的实例。通常,基于 Proxy
类的监听器需要为每个 listener type(接口)创建一个监听器类,而内部类方法需要为每个 listener(实现该接口的对象)创建一个类。
您通常不会直接处理 EventHandler
实例。相反,您使用 EventHandler
create
方法之一来创建实现给定监听器接口的对象。此监听器对象在幕后使用 EventHandler
对象来封装有关事件的信息、事件发生时要发送消息的对象、要发送的消息(方法)以及方法的任何参数。以下部分提供了如何使用 create
方法创建监听器对象的示例。
使用 EventHandler 的示例
EventHandler
的最简单用途是安装一个监听器,该监听器在不带参数的情况下调用目标对象上的方法。在下面的示例中,我们创建了一个 ActionListener
,它在 javax.swing.JFrame
的实例上调用 toFront
方法。
当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
属性设置为事件的“源”属性的值。
这将对应于以下内部类实现: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
最常见的用途可能是从事件对象的 source 中提取属性值,并将此值设置为目标对象的属性值。在下面的示例中,我们创建了一个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()); } }
例如下面的动作监听
可以写成下面的内部类(假设所有属性都有规范的 getter 方法并返回适当的类型):EventHandler.create(ActionListener.class, target, "a", "b.c.d")
目标属性也可以使用任意数量的以“.”分隔的属性前缀来“限定”。特点。例如,下面的动作监听器://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 将根据源调用适当的方法。如果源为空,则任一方法都适用,调用的方法未定义。出于这个原因,我们建议不要针对重载方法。
- 自从:
- 1.4
- 参见:
-
构造方法总结
构造方法构造方法描述EventHandler
(Object target, String action, String eventPropertyName, String listenerMethodName) 创建一个新的EventHandler
对象;您通常使用create
方法之一而不是直接调用此构造函数。 -
方法总结
修饰符和类型方法描述static <T> T
创建listenerInterface
的实现,其中监听器接口中的 all 方法将处理程序的action
应用到target
。static <T> T
/** 创建listenerInterface
的实现,其中 all 方法将事件表达式eventPropertyName
的值传递给语句中的最终方法action
,该方法应用于target
。static <T> T
create
(Class<T> listenerInterface, Object target, String action, String eventPropertyName, String listenerMethodName) 创建listenerInterface
的实现,其中名为listenerMethodName
的方法将事件表达式eventPropertyName
的值传递给语句中的最终方法action
,该方法应用于target
。返回此事件处理程序将设置的目标的可写属性的名称,或此事件处理程序将在目标上调用的方法的名称。返回应该在应用于目标的操作中使用的事件的属性。返回将触发操作的方法的名称。返回此事件处理程序将向其发送消息的对象。从事件中提取适当的属性值并将其传递给与此EventHandler
关联的操作。
-
构造方法详细信息
-
EventHandler
@ConstructorProperties ({"target","action","eventPropertyName","listenerMethodName"}) public EventHandler(Object target, String action, String eventPropertyName, String listenerMethodName) 创建一个新的EventHandler
对象;您通常使用create
方法之一而不是直接调用此构造函数。有关eventPropertyName
和listenerMethodName
参数的完整说明,请参阅the general version of create
。- 参数:
target
- 将执行操作的对象action
- 目标上的(可能限定的)属性或方法的名称eventPropertyName
- 传入事件的可读属性的(可能是合格的)名称listenerMethodName
- 应触发操作的监听器接口中的方法名称- 抛出:
NullPointerException
- 如果target
为空NullPointerException
- 如果action
为空- 参见:
-
-
方法详情
-
getTarget
返回此事件处理程序将向其发送消息的对象。- 返回:
- 此事件处理程序的目标
- 参见:
-
getAction
返回此事件处理程序将设置的目标的可写属性的名称,或此事件处理程序将在目标上调用的方法的名称。- 返回:
- 此事件处理程序的操作
- 参见:
-
getEventPropertyName
返回应该在应用于目标的操作中使用的事件的属性。- 返回:
- 事件的属性
- 参见:
-
getListenerMethodName
返回将触发操作的方法的名称。null
的返回值表示监听器接口中的所有方法都会触发该操作。- 返回:
- 将触发操作的方法的名称
- 参见:
-
invoke
从事件中提取适当的属性值并将其传递给与此EventHandler
关联的操作。- 指定者:
invoke
在接口InvocationHandler
中- 参数:
proxy
- 代理对象method
- 监听器接口中的方法arguments
- 包含在代理实例的方法调用中传递的参数值的对象数组,或者null
如果接口方法不带参数。原始类型的参数包装在适当的原始包装类的实例中,例如java.lang.Integer
或java.lang.Boolean
。- 返回:
- 将操作应用于目标的结果
- 参见:
-
create
创建listenerInterface
的实现,其中监听器接口中的 all 方法将处理程序的action
应用到target
。此方法是通过调用create
方法的另一个更通用的实现来实现的,其中eventPropertyName
和listenerMethodName
都取值null
。有关action
参数的完整说明,请参阅the general version of create
。要创建一个显示
JDialog
和dialog.show()
的ActionListener
,可以这样写:EventHandler.create(ActionListener.class, dialog, "show")
- 类型参数:
T
- 要创建的类型- 参数:
listenerInterface
- 为其创建代理的监听器接口target
- 将执行操作的对象action
- 目标上的(可能限定的)属性或方法的名称- 返回:
-
实现
listenerInterface
的对象 - 抛出:
NullPointerException
- 如果listenerInterface
为空NullPointerException
- 如果target
为空NullPointerException
- 如果action
为空IllegalArgumentException
- 如果为listenerInterface
创建代理因Proxy.newProxyInstance(java.lang.ClassLoader, java.lang.Class<?>[], java.lang.reflect.InvocationHandler)
指定的任何限制而失败- 参见:
-
create
public static <T> T create(Class <T> listenerInterface, Object target, String action, String eventPropertyName) /** 创建listenerInterface
的实现,其中 all 方法将事件表达式eventPropertyName
的值传递给语句中的最终方法action
,该方法应用于target
。此方法是通过调用更通用的create
方法实现的,其中listenerMethodName
取值null
。有关action
和eventPropertyName
参数的完整说明,请参阅the general version of create
。要创建将
JLabel
的文本设置为传入事件的JTextField
源的文本值的ActionListener
,您可以使用以下代码: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
创建代理因Proxy.newProxyInstance(java.lang.ClassLoader, java.lang.Class<?>[], java.lang.reflect.InvocationHandler)
指定的任何限制而失败- 参见:
-
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
匹配方法或属性。例如,要从MouseEvent
中提取point
属性,您可以使用"point"
或"getPoint"
作为eventPropertyName
。要从带有JLabel
源的MouseEvent
中提取“文本”属性,请使用以下任何一个作为eventPropertyName
:"source.text"
、"getSource.text" "getSource.getText"
或"source.getText"
。如果找不到方法,或者在调用方法的过程中产生异常,将在调度时抛出RuntimeException
。例如,如果传入事件对象为 null,并且eventPropertyName
非空且不为空,则将抛出RuntimeException
。action
参数与eventPropertyName
参数的格式相同,其中最后一个属性名称标识方法名称或可写属性。如果
listenerMethodName
是null
all 接口中的方法触发action
在target
上执行。例如,要创建一个
MouseListener
,它在每次按下鼠标按钮时将目标对象的origin
属性设置为传入的MouseEvent
的位置(即mouseEvent.getPoint()
的值),可以这样写:EventHandler.create(MouseListener.class, target, "origin", "point", "mousePressed");
MouseListener
,其中除了mousePressed
之外的所有方法都是空操作://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
创建代理因Proxy.newProxyInstance(java.lang.ClassLoader, java.lang.Class<?>[], java.lang.reflect.InvocationHandler)
指定的任何限制而失败- 参见:
-