时间:2021-05-19
由于项目需求,需要为Java提供一套支持事件驱动机制的类库,可以实现类似于C#中的event和delegate机制。众所周知,Java语言本身以及其标准库中并没有提供事件驱动机制的相关接口,虽然Swing(我且认为其不属于标准库,因为一般没人用:)中存在相关的类支持该机制以实现组件的事件处理,但它毕竟是与GUI相耦合的,而在其它类型的应用程序中使用起来显得就有些别扭,缺乏通用性。因此有必要实现一套通用的Java事件驱动机制类库,然后将其应用于通用的Java应用程序当中,虽然这并不是什么难事:)
让我们先考察一下C#的事件驱动机制编写方法。C#中提供的event关键字可以很容易的用来定义一个事件,然后通过向事件中添加事件处理函数(在C#中一般用委托(delegate)来引用一个函数),触发事件就可以调用相关的处理函数,也即是事件驱动的过程。例如:
//定义事件和对应的委托public event MyDelegate Click;public delegate void MyDelegate();//定义委托void OnClick(){ console.writeline("you just clicked me!");}//将委托与事件关联Click += OnClick;//触发事件Click();上面的代码就是用C#实现的事件驱动机制的一个简单的例子,可见是非常简单的,这都源于C#在语言层面(其实是CLR)提供的便利。遗憾的是Java并不提供这样的便利,需要人为去实现。下面本文将提供两种实现事件驱动机制的方法,仅供参考。
观察者模式
观察者模式是一种常用的设计模式,观察者(Observer)先通过订阅被观察对象(Subject),这样一旦被观察者(Subject)发生某种变化,就会将变化通知观察者(Observer)。
这种设计模式刚好可以用于事件驱动机制,事件(event)相当于被观察对象(Subject),一旦事件被触发,就会调用事件处理函数,可见事件处理函数(C#中的委托)可以看作是观察者。因此可以像如下这样实现上文中的功能。
public Event { //与事件相关的事件处理函数 public ArrayList<Callback> callbackList; //事件触发函数 public void emit(){ for(Callback cb : callbackList){ cb.run(); } } //注册事件处理函数 public registerCallback(Callback cb){ callbackList.add(cb); }}public interface Callback { void run();}public OnClick implements Callback { //函数 public void run(){ System.out.println("you just clicked me!"); } Event e = new Event(); //将OnClick事件处理函数注册到事件中e.registerCallback(new OnClick()); //触发事件e.emit();上面的Java代码实现了一种简单的事件驱动机制,原理很简单,是一种典型的观察者模式的应用案例。
利用反射
Java语言提供强大的反射功能,可以在运行时获取类的各个组成部分(比如类名、类成员函数、类属性等等)并对其进行操作。下面使用反射来实现简单的事件驱动机制。
public class EventHandler { //事件源 private Object sender; //事件处理函数名称(用于反射) private String callback; public EventHandler(Object sender, String callback){ this.sender = sender; this.callback = callback; } //事件触发 public void emit(){ Class senderType = this.sender.getClass(); try { //获取并调用事件源sender的事件处理函数 Method method = senderType.getMethod(this.callback); method.invoke(this.sender); } catch (Exception e2) { e2.printStackTrace(); } }}public class Button(){ private String name; ... //事件处理函数 public void onClick(){ System.out.println("you just clicked me!"); }} Button b = new Button();if(){ EventHandler e = new EventHandler(b, "onClick"); e.emit();}上述代码展示了利用反射实现的事件驱动机制,利用反射机制的好处是其具有强大的扩展性,比如我的事件处理函数中可以引入一个EventArgs的形参,从而可以让事件本身带有参数,这样就可以让事件携带更多的信息,改写后的事件处理函数如下方的代码所示:
public class EventArgs { //参数 String p1; Integer p2; ... }//onClick事件处理函数改写public void onClick(Object sender, EventArgs e){ //参数e提供更多的信息 System.out.println("Hello, you clicked me! " + e.p1 + e.p2);}//触发函数emit改写public void emit(EventArgs e){Class senderType = this.sender.getClass();try { //获取并调用事件源sender的事件处理函数 Method method = senderType.getMethod(this.callback, this.getClass(), e.getClass()); method.invoke(this.sender, this.sender, e); } catch (Exception e2) { e2.printStackTrace(); }}是不是似曾相识?没错,和用C#写Winform窗体时,Visual studio为你自动生成的事件处理函数(代码中的onClick函数)几乎具有完全相同的形式,但此时我们是用Java实现的。
当然,除了以上提到的两种方法可以实现Java的事件驱动机制以外,还有一些其它的方法,比如可以利用Java的内部类来实现,笔者也曾写过一些示例代码,这里就不再冗言了,留待以后再讲。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了wxPython的事件驱动机制,分享给大家供大家参考。具体方法如下:先来看看如下代码:#!/usr/bin/python#moveevent.py
Java语言中反射动态代理接口的解释与演示Java在JDK1.3的时候引入了动态代理机制、可以运用在框架编程与平台编程时候捕获事件、审核数据、日志等功能实现,首
做了一个不到200行的事件驱动库,基于c++11标准,header-only,跨平台。支持自定义事件,通过wake_up函数异步唤醒。写这个库的动机是想为之前自
本文实例讲述了Android基于广播事件机制实现简单定时提醒功能代码。分享给大家供大家参考,具体如下:1.Android广播事件机制Android的广播事件处理
事件驱动模型现在我们来看看nodejs中的事件驱动和异步I/O是如何实现的.nodejs是单线程(singlethread)运行的,通过一个事件循环(event