public class EventHandler extends Object implements InvocationHandler
EventHandler
类提供了动态生成事件侦听器的支持,该侦听器的方法执行涉及传入事件对象和目标对象的简单语句。
EventHandler
类旨在由交互式工具(如应用程序构建器)使用,允许开发人员在bean之间建立连接。 通常,连接是从用户界面bean(事件源 )到应用程序逻辑bean( 目标 )进行的。 这种最有效的连接将应用程序逻辑与用户界面隔离开来。 例如, EventHandler
用于从JCheckBox
到接受布尔值的方法的连接可以处理提取复选框的状态并将其直接传递给该方法,以使该方法与用户界面层隔离。
内部类是从用户界面处理事件的另一种更通用的方式。 EventHandler
类只处理内部类可能使用的一个子集。 然而EventHandler
比内部类更好地与长期持久性方案相比。 此外,在大型应用EventHandler
中使用EventHandler
,其中实现了相同的接口多次可以减少应用程序的磁盘和内存占用。
与创建的听众的原因EventHandler
具有这样的小尺寸是, Proxy
类,在其上EventHandler
依赖,共享的相同的接口实现。 例如,如果您使用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接口的新实现ActionListener
其中添加一个实例,可以获得相同的效果,还有一些额外的编译时类型安全性:
//Equivalent code using an inner class instead of EventHandler. myButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { frame.toFront(); } });
EventHandler
的下一个最简单的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
可能最常见的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()); } }
例如,以下动作侦听器
可以写成以下内部类(假设所有属性都有规范的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将调用基于源的适当方法。
如果源为null,那么任一方法都是合适的,并且调用的方法是未定义的。
因此,我们建议不要使用重载方法。
Proxy
, EventObject
Constructor and Description |
---|
EventHandler(Object target, String action, String eventPropertyName, String listenerMethodName)
创建一个新的 EventHandler 对象;
你通常使用create 方法之一,而不是直接调用这个构造函数。
|
Modifier and Type | Method and Description |
---|---|
static <T> T |
create(类<T> listenerInterface, Object target, String action)
创建一个listenerInterface的
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 。
|
@ConstructorProperties(value={"target","action","eventPropertyName","listenerMethodName"}) public EventHandler(Object target, String action, String eventPropertyName, String listenerMethodName)
EventHandler
对象;
你通常使用create
方法之一,而不是直接调用这个构造函数。
请参阅the general version of create
的完整描述eventPropertyName
和listenerMethodName
参数。
target
- 将执行该操作的对象
action
- 目标上的(可能有资格的)属性或方法的名称
eventPropertyName
- 传入事件的可读属性的(可能限定的)名称
listenerMethodName
- 侦听器界面中应触发操作的方法的名称
NullPointerException
- 如果
target
为空
NullPointerException
- 如果
action
为空
EventHandler
, create(Class, Object, String, String, String)
, getTarget()
, getAction()
, getEventPropertyName()
, getListenerMethodName()
public Object getTarget()
EventHandler(Object, String, String, String)
public String getAction()
EventHandler(Object, String, String, String)
public String getEventPropertyName()
EventHandler(Object, String, String, String)
public String getListenerMethodName()
null
意味着侦听器接口中的所有方法触发动作。
EventHandler(Object, String, String, String)
public Object invoke(Object proxy, 方法 method, Object[] arguments)
EventHandler
的操作。
invoke
在界面
InvocationHandler
proxy
- 代理对象
method
- 监听器界面中的方法
arguments
-包含的方法调用传递代理实例的参数值的对象的阵列,或null
如果接口方法没有参数。
原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer
或java.lang.Boolean
。
EventHandler
public static <T> T create(类<T> listenerInterface, Object target, String action)
listenerInterface
,其中监听器界面中的所有方法将处理程序的action
应用于target
。
这种方法是通过调用create
方法的另一个更一般的create
方法实现的, eventPropertyName
和listenerMethodName
的值为null
。
请参阅the general version of create
的完整描述action
参数。
要创建一个ActionListener
,显示JDialog
与dialog.show()
,可以写:
EventHandler.create(ActionListener.class, dialog, "show")
T
- 要创建的类型
listenerInterface
- 创建代理的侦听器界面
target
- 将执行操作的对象
action
- 目标上的(可能合格的)属性或方法的名称
listenerInterface
的对象
NullPointerException
- 如果
listenerInterface
为空
NullPointerException
- 如果
target
为空
NullPointerException
- 如果
action
为空
create(Class, Object, String, String)
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
为空
create(Class, Object, String, String, String)
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
异常, RuntimeException
将在调度时抛出RuntimeException
。 例如,如果传入的事件对象为空,并且eventPropertyName
为非空且不为空,则将抛出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
为空
EventHandler