4

在 Java 中,每次我想创建一个新的自定义事件时,我通常通过添加 3 个方法来完成,即:

addDogEventListener(EventListener listener); 
removeDogEventListener(EventListener listener);
dispatchDogEventListener(DogEvent event);

然后现在如果我想调度另一个事件,比如 CatEvent,我将不得不再次创建所有这 3 个方法:

addCatEventListener(EventListener listener); 
removeCatEventListener(EventListener listener);
dispatchCatEventListener(CatEvent event);

那么如果我只想管理一种 CatEvent 事件,比如 Meow,我必须再次复制并粘贴所有这 3 个方法?!像 addCatMeowEventListener();... 等?

通常,我需要调度不止一种事件。让整个班级充满如此多的方法来传输和处理事件将是非常不整洁的。不仅如此,这些函数的代码也非常相似,比如循环 EventListenerList、向列表中添加事件等。

这是我应该如何在 Java 中进行事件调度吗?

有没有办法像我可以这样做:

mainApp.addEventListener(CatEvent.MEOW, new EventHandler() { meowHandler(Event e) { });
mainApp.addEventListener(CatEvent.EAT, new EventHandler() { eatHandler(Event e) { });
myCat.addEventListener(DogEvent.BARK, new EventHandler() { barkHandler(Event e) { myCat.run() });

这样,我可以在不同的eventHandler类和函数中处理不同类型的CatEvent,而不必为不同的事件不断创建不同的事件监听器方法?

也许我错过了关于 Java 事件处理的一些东西,但是有没有一种更简洁的方法,我不必保留复制和粘贴这 3 种方法,并为我想要调度的每种不同类型的方法创建这么多不同类型的事件对象?

谢谢!

4

2 回答 2

4

我拥有的事件处理策略是按可能适合您的类型发布。

我有一个代理可以检查侦听器的注释,该注释将方法标记为侦听事件。使用这种方法,您只需要在要处理特定类别的事件时添加方法。

interface Subscriber { // marker interface for OSGi
}

@interface SubscriberCallback { // marker annotation
}

class Broker {
    // uses reflections to find methods marked with @SubscriberCallback
    public void addSubscriber(Subscriber subscriber); 
    public void removeSubscriber(Subscriber subscriber);
    public <T> void publish(T... events);
}

class MyListener implements Subscriber {

@SubscriberCallback
public void onDogEvent(DogEvent... dogEvents) {
    // called for one or more dog events
}

@SubscriberCallback
public void onCatEvent(CatEvent catEvent) {
    // called for each CatEvent including subsclass of CatEvent.
}
}
于 2011-05-28T08:43:09.550 回答
0

然后,如果我只想管理一种 CatEvent 事件,比如 Meow,(和 EAT)

事件(MEOW 或 EAT)的“动作”应该是 CatEvent 中定义的数据。然后您的事件侦听代码将检查操作类型并进行适当的处​​理。

也许看看 TableModelEvent 看看这是如何完成的。它使用相同的事件处理“插入”、“删除”和“更新”事件。

您也可以基于 PropertyChangeListener 对通用事件侦听器进行建模。当 Swing 组件上的各种属性发生变化时,PropertyChangeListener 用于处理事件。例如,当您调用 setForeground() 或 setBackground() 或 setFont() 或 setText() 或 setIcon 时。PropertyChangeListener 使用 getName() 方法来确定已更改的属性。因此,对于上述方法,名称将是“前景”、“背景”、“字体”、“文本”、“图标”。有关这可能如何工作的示例,请参阅如何使用属性更改侦听器。

在您的情况下,名称将是“猫”和“狗”。仅当您创建的 GeneralEvent 可以包含与您的每个事件相关的信息(即“喵”和“吠”)时,此方法才有效。

于 2011-05-28T15:21:20.600 回答