许多开发人员为事件处理创建匿名内部类。对于简单的事件处理,内部类可能成为真正的争论话题.幸运的是,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. CV02-FCN笔记
  2. unity3d版本控制的设置方法(SVN)
  3. mysql5.7 修改密码
  4. 人工神经网络心得体会_卷积神经网络学习心得
  5. 第四十九期:大牛总结的MySQL锁优化,写得太好了!
  6. 02.改善深层神经网络:超参数调试、正则化以及优化 W1.深度学习的实践层面
  7. 小鹏汽车回应“非法收集人脸数据被罚10万”:误购第三方设备 数据已删除
  8. B00014 C++实现的AC自动机
  9. 基于单片机智能药盒控制系统设计(含论文)
  10. Codeforces 450A. Jzzhu and Children
  11. 职场:因抢一个月饼,惨遭阿里开除,如今他把生活过成这样
  12. 前端三剑客---HTML
  13. maven简介及使用help插件
  14. DayDayUp:20190908易建联27分中国男篮负无缘直通奥运—回顾2008年奥运中国男篮— 易建联加油!中国男篮加油!
  15. Vivo应用商店上架最全最细流程
  16. android程序毕业答辩ppt,软件毕业答辩PPT范例
  17. 给一段下雪的代码。。。
  18. Python开发一个炸金花小游戏,注意别玩上瘾了
  19. 数字化转型与智能创新100个案例
  20. 再来一篇,看jdk源码大师亲自操刀编写的集合源码

热门文章

  1. 云开发智能家居客户案例详解(内附拓扑图)
  2. 连夜干出来一个自动处理【微信消费者投诉管理系统】,支持多商户
  3. DM8:Linux下实现disql命令上下翻动
  4. 【整理】MSbuild
  5. “ 总有个人会捡起 七零八落的你 “
  6. jfreechart实现动态图表
  7. 《测试开发方法论》导读
  8. 腾讯云服务器标准型SA1和SA2区别_腾讯云AMD服务器两款机型哪个更好
  9. FAE新手上路(五)
  10. 【C语言】反弹球消砖块游戏