我对如何在模型和控制器之间使用事件监听器感到困惑。我正在开发一个应用程序,在客户端我分为两部分:客户端本身,它与服务器和GUI进行所有通信。客户端从服务器触发有关更新的事件,并且gui触发有关服务器感兴趣的用户操作的事件(该应用程序基本上是一个多用户图形编辑器)。所以我的问题:
我发现GUI更容易保持对客户端的引用,反之亦然,而不是触发事件和使用事件侦听器。这通常是一种不好的做法吗?
现在,如果我们实际使用事件,我会对实现感到困惑。 所以我创建了一些我将要新的事件(drawEvent,connectionEvent等)。然后我实现了ClientListener和具有特定行为的GUIListener。现在,我如何解雇事件?从阅读开始,我明白,为了让GUI能够触发需要调用clientListener.eventHappened(event)的东西,对吧?所以它需要有那个监听器,即客户端和GUI必须共享监听器(似乎更复杂,只是引用)?最后,我如何实际向gui添加GUIListener的实例?从我读到的内容中,我必须创建一个EventListenerList属性,并在那里添加一个GUI监听器的新实例?是吗?我不知道这会如何引发实际聆听。
抱歉,我只是在学习所有这些东西而且没有完全理解。 谢谢!
答案 0 :(得分:3)
不确定您的设计是否最佳,但编写自己的听众/事件相当容易。
例如。首先为侦听器定义接口,为事件定义类
public class MyCustomEvent extends EventObject{
//store all relevant info in your event
}
public interface MyListener{
public void eventHappened( MyCustomEvent event);
}
然后,如果你有一个你想要附加监听器的类,你只需要有方法来添加监听器,并在需要时调用那些监听器上的eventHappened
方法
public class MyClassWhichFiresEvents{
private final List<MyListener> listeners =
new CopyOnWriteArrayList<MyListener>();
public void addListener( MyListener listener ){
listeners.add( listener );
}
public void removeListener( MyListener listener ){
listeners.remove( listener );
}
//call this method whenever you need to fire an event
private void fireEvent( MyCustomEvent event ){
for ( MyListener listener : listeners ){
listener.eventHappened( event );
}
}
}
如果您想知道存储监听器的CopyOnWriteArrayList
。当您遍历侦听器以触发事件时,其中一个侦听器可能会自行删除。因此,典型的解决方案是首先将所有侦听器复制到另一个列表中,然后迭代该列表,或使用CopyOnWriteArrayList