我正在Java之上实现一种脚本语言。使用反射,我能够动态地创建Java助手对象,访问它们的字段并调用它们的方法。但是,我现在已经对特定的事件类型进行了硬编码处理。例如: JScrollBar addAdjustmentListener()使用可调接口,JFrame windowClosing()使用WindowAdapter接口,JButton addActionListener使用ActionListener接口。在脚本语言中的事件接收端,使用带有任意类型的0、1或2个参数的事件数据调用匿名函数。我的问题是: Java中是否有一种(反射式)处理任意事件的方法?一般说来,处理所有JComponent子类事件也是一个好的开始。
发布于 2020-04-28 11:01:56
以下代码可以作为起点:
public static void main(String[] args) {
JFrame f = new JFrame("example");
listenToAllEvents(f, System.out, "println");
JButton b = new JButton("click me");
listenToAllEvents(b, System.out, "println");
f.getContentPane().add(b, BorderLayout.PAGE_START);
f.pack();
f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
f.addWindowListener(
EventHandler.create(WindowListener.class, f, "dispose", null, "windowClosing"));
f.setVisible(true);
}
static void listenToAllEvents(Object component, Object listener, String method) {
BeanInfo bi;
try {
bi = Introspector.getBeanInfo(component.getClass());
} catch (IntrospectionException ex) {
LOGGER.log(Level.SEVERE, null, ex);
return;
}
for(EventSetDescriptor esd: bi.getEventSetDescriptors()) try {
esd.getAddListenerMethod().invoke(component,
EventHandler.create(esd.getListenerType(), listener, method, ""));
} catch(ReflectiveOperationException ex) {
LOGGER.log(Level.SEVERE, null, ex);
}
}要点是
Introspector.getBeanInfo(…)返回的BeanInfo允许您动态地发现组件支持哪些事件,即它声明了哪些方法与事件源模式匹配。EventHandler类允许生成侦听器,当事件发生时调用特定的目标方法。它还允许将调用事件上的方法的结果作为参数传递给目标方法。此外,如windowCloing→dispose示例所示,支持no-arg方法和指定特定的侦听器方法。EventHandler是基于Proxy工具的,它允许通过通用InvocationHandler实现任意接口,这对于脚本语言中的其他目的可能很有用,除非您想要走生成字节码的路线。请注意,打印所有事件的示例代码会使UI非常慢。当您使用其他操作或限制正在侦听的事件时,不会发生这种情况。
https://stackoverflow.com/questions/61459204
复制相似问题