许多开发人员为事件处理创建匿名内部类。对于简单的事件处理,内部类可能成为真正的争论话题.幸运的是,Java1.4 引入了 EventHandler 类,它依赖于监听器的动态生成以方便地处理手头的任务。尽管这个新功能通常是让IDE 厂商使用的,但是在本文中,专栏作者 John Zukowski 还是为您展示了如何用它进行手工编码。

和 Type getXXX() 。关于这些方法没有什么特别之处,并且正如所预期的,它们遵循 JavaBeans 的属性命名规范。我们今天要讨论的是JavaBeans 组件的一个方面,即一对监听器方法 addXXXListener (XXXListener name) 和 removeXXXListener (XXXListener name) 。 XXListener 在这里指的是一个监听器对象,它扩展了 EventListener 接口,等候与监听器关联的组件中的各种事件发生。当事件发生时,所有注册的监听器都会得到事件的通知(没有特定的顺序)。通过魔术般的一个小反射(reflection)和一个新的 java.beans.EventHandler 类,您可以将一个监听器附加到一个 bean 上,而无需直接实现这个监听器接口或者创建那些烦人的小匿名内部类。

以前的方法

在深入到使用新的 EventHandler 类的细节之前,让我们回顾一下不使用这个类时是如何进行工作的。我们举一个对 Swing 框架中的按钮选择做出响应的简单例子。选择一个按钮生成一个 ActionEvent 。要对这个事件做出响应,需要将 ActionListener 附加到这个按钮上,如清单 1 所示:清单 1. 监听标准按钮选择

import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ButtonSelection extends JFrame { public ButtonSelection() { super("Selection"); setDefaultCloseOperation(EXIT_ON_CLOSE); JButton button = new JButton("Pick Me"); Container contentPane = getContentPane(); contentPane.add(button, BorderLayout.CENTER); button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("Hello, World!"); } } ); } public static void main(String args[]) { JFrame frame = new ButtonSelection(); frame.setSize(200, 100); frame.show(); } }

这里没有任何神奇之处,您可能已经熟悉这种代码了。这里, ActionListener 实现是适时定义的,它定义为一个匿名内部类,并直接附加到按钮上。在选择这个按钮时,字符串 Hello, World! 就打印到控制台中。与程序关联的屏幕如图 1 所示:

在 JavaBeans 规范中,没有要求您创建匿名内部类进行事件监听。 IDE 工具常常采用这种行为:您说要一个监听器,它就生成一个 stub,然后您填入细节。完成同样工作的其他方式包括在调用类中提供指定的实现或者实现您自己的接口。

定义了每一个实现类后,就会创建一个单独的.class 文件。所以,在前面的 ButtonSelection 程序中,您会看到编译器生成两个 .class 文件:ButtonSelection.class 和 ButtonSelection$1.class。 $1 是 Sun 编译器命名匿名内部类的方式,计数随着每一个类增加。其他编译器可能有不同的命名方式。

方法,如清单 2 所示:清单 2. EventHandler 的 create() 方法

public static Object create(Class listenerInterface, Object target, String action) public static Object create(Class listenerInterface, Object target, String action, String eventPropertyName) public static Object create(Class listenerInterface, Object target, String action, String eventPropertyName, String listenerMethodName)

让我们更详细地看一下这三种方法。

因为第一种方法的参数最少,所以它最简单。第一个参数是 EventListener 类型,您要实现的就是它的接口,例如,要响应按钮选择,这个参数应该是 ActionListener.class ,以表示这个接口的 Class 对象。虽然 ActionListener 只有接口中的一个方法,但是以这种方式创建接口的一个实现意味着这个接口实现的所有方法都将执行同样的代码。

调用需要转移到一个方法中,这样就可以从处理程序中调用它。清单 3. 展示 create(Class, Object, String)

import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.beans.*; public class ButtonEventHandler extends JFrame { public ButtonEventHandler() { super("Selection"); setDefaultCloseOperation(EXIT_ON_CLOSE); JButton button = new JButton("Pick Me"); Container contentPane = getContentPane(); contentPane.add(button, BorderLayout.CENTER); button.addActionListener( (ActionListener)EventHandler.create( ActionListener.class, this, "print") ); } public void print() { System.out.println("Hello, World!"); } public static void main(String args[]) { JFrame frame = new ButtonEventHandler(); frame.setSize(200, 100); frame.show(); } }

中调用 EventHandler 的代码只是表示“在需要通知按钮所附的 ActionListener 时,调用我们的 print() 方法( this )”。不过有一些副作用。第一个是调用需要强制类型转换,以返回正确的监听器类型,从而满足编译器要求。另一个副作用是由于对 print() 的调用是通过反射间接进行的,所以这个方法必须是公共的(并且不接受参数)。使用 EventHandler 的另一个特点是对于其他版本的 create() 来说,很少出现问题。

下一版本的 create() 添加了第四个参数,并增加了第三个参数的用途。第一个 String 参数现在也可以表示 Object 参数的可写 JavaBeans 属性的名字。所以,对于 JButton ,如果第三个参数是 text ,那么这相当于一个 setText() 调用,该方法所需要的参数是由传递给第四个参数的 String 来表示的。

import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.beans.*; public class TextFieldHandler extends JFrame { public TextFieldHandler() { super("Selection"); setDefaultCloseOperation(EXIT_ON_CLOSE); JTextField text = new JTextField(); JLabel label = new JLabel(); Container contentPane = getContentPane(); contentPane.add(text, BorderLayout.NORTH); contentPane.add(label, BorderLayout.CENTER); text.addActionListener( (ActionListener)EventHandler.create( ActionListener.class, label, "text", "source.text") ); } public static void main(String args[]) { JFrame frame = new TextFieldHandler(); frame.setSize(200, 150); frame.show(); } }

调用,其中 source.text 表明要得到事件源的 text 属性,直接映射到 label.setText((JTextField(event.getSource())).getText()) 代码。

最后一种版本的 create() 是将另外两种方法结合在一起使用,对于在其他调用中没有的参数,则传递 null 。其他版本的 create() 要求您对所有监听器接口方法做同样的事情,这最后一种方法让您可以指定对每一种监听器方法调用不同的操作。所以,对于一个 MouseListener ,您可以为 mousePressed() 调用一种操作,为 mouseReleased() 调用另一种操作、还可以为 mouseClicked() 调用其他的操作。清单 5 展示了最后一种版本的 create() ,它只有用于鼠标按下/释放事件的两种简单的打印方法:清单 5. 展示 create(Class, Object, String, String, String)

import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.beans.*; public class MouseHandler extends JFrame { public MouseHandler() { super("Press and Release Mouse"); setDefaultCloseOperation(EXIT_ON_CLOSE); Container contentPane = getContentPane(); contentPane.addMouseListener( (MouseListener)EventHandler.create( MouseListener.class, this, "pressed", "point", "mousePressed") ); contentPane.addMouseListener( (MouseListener)EventHandler.create( MouseListener.class, this, "released", "point", "mouseReleased") ); } public void pressed(Point p) { System.out.println("Pressed at: " + p); } public void released(Point p) { System.out.println("Released at: " + p); } public static void main(String args[]) { JFrame frame = new MouseHandler(); frame.setSize(400, 400); frame.show(); } }

pressed() 和 released() 方法有一个参数是事件的 Point 。对于不接受参数的方法,在指定 point 的地方需要一个 null 。

结束语

这就是有关使用 EventHandler 全部内容。是否要使用它呢?我个人认为这是一种风格问题。在内部它用到了反射,所以可能会稍微慢一些。它还要求调用方法为公共的。如果 IDE 替我生成了代码,那么我可能就让它保持原样,而不会将编码监听器重新编码为匿名内部类。

eventhandler java_用 EventHandler 进行事件监听相关推荐

  1. js 监听 安卓事件_百行代码实现js事件监听实现跨页面数据传输

    百行代码实现js事件监听实现跨页面数据传输 使用场景 类似消息队列的使用场景,支持同页面和跨页面通信,发送消息和接收消息 技术原理 跨页面通信: 基于事件监听,通过监听 storage事件监听回调机制 ...

  2. 11-flutter事件监听

    事件监听 1 本身支持事件检测,就可以直接使用onpress body:Center(child: RaisedButton(child: Text("Click"),onPres ...

  3. 从jQuery的缓存到事件监听

    很久以前,我还在cnblogs里面逛的时候就提出过一个问题(刚找了半天没找到).不知道大家有没有发现,用jQuery选择器"选择"之后的DOM上会添加jQuery********* ...

  4. java中事件监听_Java中的事件监听机制

    鼠标事件监听机制的三个方面: 1.事件源对象: 事件源对象就是能够产生动作的对象.在Java语言中所有的容器组件和元素组件都是事件监听中的事件源对象.Java中根据事件的动作来区分不同的事件源对象,动 ...

  5. layui监听当前页_事件监听 · layui使用手册 · 看云

    # 事件监听 语法:form.on('event(过滤器值)', callback); form模块在 layui 事件机制中注册了专属事件,所以当你使用layui.onevent()自定义模块事件时 ...

  6. Java中事件监听机制

    Java中事件监听机制 一.事件监听机制的定义 要想了解Java中的事件监听机制,首先就要去了解一下在Java中事件是怎样去定义的呢!在使用Java编写好一个界面后,我们就会对界面进行一些操作,比如, ...

  7. 关于事件监听机制的总结(Listener和Adapter)

    记得以前看过事件监听机制背后也是有一种设计模式的.(设计模式的名字记不清了,只记得背后实现的数据结构是数组.) 附上事件监听机制的分析图: 一个事件源可以承载多个事件(只要这个事件源支持这个事件就可以 ...

  8. Jquery系列:checkbox 获取值、选中、设置值、事件监听等操作

    <div id="divId" class="divTable"><div class="tableBody">&l ...

  9. vue中的v-on事件监听机制

    监听dom事件使用v-on指令: v-on:事件类型="一个函数" 这个事件类型可以自定义 简写: @事件类型="一个函数"⭐ 1.作用:绑定事件监听,表达式可 ...

最新文章

  1. 软件测试2019:第四次作业
  2. PostgreSQL · 实现分析 · PostgreSQL 10.0 并行查询和外部表的结合
  3. php socket 握手,python Socket之客户端和服务端握手详细介绍
  4. LiveVideoStackCon深圳 - 洞察多媒体技术生态趋势与机会
  5. Redis(1)---五种数据结构
  6. idea 检测 重复代码_IDEA关掉重复代码波浪线
  7. VC使用命令行编译很复杂
  8. G120XA与S7-1200的Modubus通信(一)
  9. TCP-IP计算机网络基本概述
  10. 常用的绩效管理系统应该具备哪些功能呢?
  11. DSP28335的eCAP模块
  12. Java身份证校验算法
  13. vuze自动关机插件
  14. PHP设计模式-适配器模式
  15. 卫瓴科技X腾讯企业微信“营销赋能、协同增长”闭门沙龙顺利举行 |深圳
  16. CodeForces_29B
  17. 如何选择靠谱的区块链技术服务商?佰忆科技有秘籍
  18. python gtk页面布局_Python GTK + 3教程 学习笔记 ——(5)布局 与 glade
  19. 在Dreamweaver中运行JSP页面
  20. java实现OpenCV 4.1.0人脸相似度对比

热门文章

  1. Rethinking the trigger of backdoor attack
  2. WebService报错:org.apache.axis2.AxisFault: The given SOAPAction aaa does not match an operation.
  3. 2022-04-19每日刷题打卡
  4. 使用System.currentTimeMillis实现定时任务
  5. Movie Render Queue渲染时相机位置偏离问题
  6. 缓冲(buffer)和缓存(cache)区别
  7. Java缓冲流BufferedStream详解
  8. 全免费建站攻略!freewebhostingarea空间+免费tk域名
  9. 同花顺KDJ抄底逃顶(公式 副图 源码 测试图)
  10. WOW魔兽世界编程API中文版