我正在使用 SWT 小部件编写 Java 应用程序。我想在某个事件发生时更新某些小部件的状态(例如,更新数据模型的状态)。
Java 中是否有类似于 Cocoa 的 NSNotificationCenter 的东西,我可以在其中注册一个对象以侦听通知事件并响应它们,以及让其他对象“触发”通知?
我正在使用 SWT 小部件编写 Java 应用程序。我想在某个事件发生时更新某些小部件的状态(例如,更新数据模型的状态)。
Java 中是否有类似于 Cocoa 的 NSNotificationCenter 的东西,我可以在其中注册一个对象以侦听通知事件并响应它们,以及让其他对象“触发”通知?
好的,假设例如,您希望在 Loader 开始扫描和完成扫描时通知程序的某些部分(不要担心 Loader 是什么,或者扫描是什么,这些是来自我上一份工作中的一些代码)。您定义一个接口,将其称为“ScanListener”,例如
public interface ScanListener
{
public void scanStarted();
public void scanCompleted();
}
现在 Loader 定义了一个方法让你的其他代码注册回调,比如
public void addScanListener(ScanListener listener)
{
listeners.add(listener);
}
Loader,当它开始扫描时,执行以下代码
for (ScanListener listener : listeners)
{
listener.scanStarted();
}
当它完成时,它对 listener.scanCompleted(); 做同样的事情。
需要通知这些事件的代码实现了该接口(它们自己或在内部类中),并调用“loader.addScanListener(this)”。它的 scanStarted() 和 scanCompleted() 方法在适当的时候被调用。您甚至可以使用带有参数和/或返回结果的回调来做到这一点。全取决于你。
您在寻找什么样的通知?如果你想要的只是一个对象能够告诉其他任何人“嘿,我已经改变了,相应地更新”,最简单的方法是使用现有的 Observer 接口和 Observable 类。或者用一个接口编写你自己的接口,该接口定义你想从改变的那个监听器上调用什么。
没有预先存在的每进程服务在 java 中分派事件,相当于默认的 NSNotificationCenter。在 java 中,事件的类型由事件对象指定为特定类型(这也意味着通知方法取决于该类型)而不是使用字符串。在泛型之前,编写一个也是类型安全的通用事件调度器和接收器是不可能的(见证 AWT 和 Spring 库中 *Event 类和 *EventListener 接口的激增)。
有一些用于事件调度的设施。正如保罗所提到的java.util.Observable
,正如您所指出的,它需要子类化。还有java.beans.PropertyChangeSupport
,根据您的情况,这可能很有用。
你也可以自己写一个。源代码PropertyChangeSupport
可能在 openjdk 中可用,您可以查看废弃的Apache Commons Event项目。根据您的需要,您可能不得不担心线程、序列化、内存泄漏(确保注销或使用弱引用)和并发修改(迭代侦听器列表的副本,因为侦听器可能决定注销自己)响应变化)。
既然 Java 中存在泛型,那么泛型事件调度库将成为可能;但是,我没有遇到任何。任何人?
实际上,Java 中内置了一个功能,可以完全满足您的需求,但这不是您可能考虑过的,而且老实说,对于您想要的东西,它可能有点重量级。
然而,这就是说,它确实存在。
这是JMX。
您创建 MBean,然后其他人可以注册来自这些 MBean 的事件。然后 MBean 可以发送通知。
我个人不会考虑在这种情况下使用它(我只是自己动手),但是该设施就在那里,并且定义明确并记录在案。
不是 Java,但 IPython 项目在这里有一个用 Python 编写的通知中心,您可以将其用作 Java 版本的模板。
在 Java 中,这将是提供者向其侦听器发出通知。但是 Java 不提供通过 Cocoa 的 NSNotification 获得的松散耦合,因为在 Java 中,提供者和订阅者必须相互引用。比较“为 Java 开发人员学习 Objective-C”中的第 18 章。
在Java
中有一个IOS NSNotificationCenter的实现。
您可以在以下位置找到源代码:
This Github project