我正在编写一个使用SWT小部件的Java应用程序。我想在特定事件发生时更新某些小部件的状态(例如,更新数据模型的状态)。
在Java中是否有类似于Cocoa的NSNotificationCenter的东西,我可以在其中注册一个对象以侦听通知事件并对其进行响应,以及让其他对象“触发”通知?
我正在编写一个使用SWT小部件的Java应用程序。我想在特定事件发生时更新某些小部件的状态(例如,更新数据模型的状态)。
在Java中是否有类似于Cocoa的NSNotificationCenter的东西,我可以在其中注册一个对象以侦听通知事件并对其进行响应,以及让其他对象“触发”通知?
好的,假设您想要程序的某些部分在加载程序开始扫描和完成扫描时得到通知(不用担心加载器是什么或扫描是什么,这些是我上一个工作中代码的示例)。您可以定义一个接口,命名为“ScanListener”。
public interface ScanListener
{
public void scanStarted();
public void scanCompleted();
}
现在,装载器定义了一个方法供您的其他代码注册回调,比如
public void addScanListener(ScanListener listener)
{
listeners.add(listener);
}
装载器开始扫描时,执行以下代码。
for (ScanListener listener : listeners)
{
listener.scanStarted();
}
当它完成时,它会执行listener.scanCompleted()相同的操作。
需要被通知这些事件的代码实现了该接口(要么是它们自己实现,要么是在内部类中实现),并调用“loader.addScanListener(this)”。在适当的时候调用它的scanStarted()和scanCompleted()方法。甚至可以使用带有参数和/或返回结果的回调实现此功能。它完全取决于你。
你在寻找什么类型的通知? 如果你只想让一个对象告诉任何其他对象“嘿,我已经改变了,请相应地更新”,最简单的方法是使用现有的Observer接口和Observable类。或者编写自己的界面,该界面定义了你希望在被更改的监听器上调用什么。
没有现成的每个进程服务在Java中分发事件与默认的NSNotificationCenter相等。 在Java中,事件类型是通过事件对象是特定类型来指定的(这也意味着通知方法取决于该类型),而不是使用字符串。 在泛型出现之前,编写既能够通用分发事件又能够类型安全的接收器实际上是不可能的(可以看到AWT和Spring库中* Event类和* EventListener接口的增加)。
有一些事件调度的设施。正如Paul提到的那样,有java.util.Observable
,正如你所指出的,需要继承。还有java.beans.PropertyChangeSupport
,根据你的情况可能会有用。
你也可以自己编写一个。 PropertyChangeSupport
的源代码可能可在 openjdk 中找到,你可以查看已废弃的 Apache Commons Event 项目。根据您的需求,您可能需要关注诸如线程、序列化、内存泄漏(确保取消注册或使用弱引用)和并发修改(在监听器列表的副本上迭代,因为监听器可能决定在响应更改时取消注册)等问题。
既然Java中存在泛型,那么就有可能出现通用事件分派库;但是,我还没有遇到过。有人知道吗?
实际上,Java中已经有一个内置的工具可以完全满足您的要求,但您可能没有考虑过这一点,且说实话,它可能有点过于复杂。
然而,它确实存在。
这是JMX。
您可以创建MBeans,然后其他人可以注册以接收这些MBeans的事件。然后MBean可以发送Notification。
个人而言,我不会考虑在这种情况下使用它(我会亲自制作),但是这方面的设施已经存在,而且定义和文档化得非常好。
不是Java,而是IPython项目有一个用Python编写的通知中心 在这里,你可以将其用作Java版本的模板。
在Java中,这将是一个提供者向其监听器发出通知。但是Java没有提供Cocoa的NSNotification所提供的松耦合,因为在Java中,提供者和订阅者必须彼此引用。在“为Java开发人员学习Objective-C”的第18章中进行比较。
There is an implementation of IOS NSNotificationCenter in Java.
You can find sources code in :
This Github project