我对如何在模型和控制器之间使用事件侦听器感到有些困惑。我正在开发一个在客户端上分为两个部分的应用程序:客户端本身,它与服务器和GUI进行所有通信。客户端触发有关服务器更新的事件,而gui触发有关服务器感兴趣的用户操作的事件(该应用程序基本上是多用户图形编辑器)。所以我的问题是:
我发现GUI保留对客户端的引用比较容易,反之亦然,而不是触发事件和使用事件侦听器。通常是不好的做法吗?
现在,如果我们实际使用事件,那么我会对实现感到困惑。
因此,我创建了一些新的事件类型(drawEvent,connectionEvent等)。然后,我实现了具有特定行为的ClientListener和GUIListener。现在,我该如何触发事件?通过阅读,我了解到,要使GUI触发某些操作,需要调用clientListener.eventHappened(event),对吗?因此,它需要具有该侦听器,即客户端和GUI必须共享侦听器(似乎比引用更复杂)?最后,如何实际将GUIListener实例添加到gui?再次从我阅读的内容中,我必须创建一个EventListenerList属性,并在那里添加一个GUI侦听器的新实例?是吗我看不出这将如何触发实际的收听。
抱歉,我只是在学习所有这些东西,还没有完全了解。
谢谢!
最佳答案
不确定是否设计最好,但是编写自己的侦听器/事件相当容易。
例如。您首先为侦听器定义一个接口,为事件定义一个类
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