我对如何在模型和控制器之间使用事件侦听器感到有些困惑。我正在开发一个在客户端上分为两个部分的应用程序:客户端本身,它与服务器和GUI进行所有通信。客户端触发有关服务器更新的事件,而gui触发有关服务器感兴趣的用户操作的事件(该应用程序基本上是多用户图形编辑器)。所以我的问题是:


我发现GU​​I保留对客户端的引用比较容易,反之亦然,而不是触发事件和使用事件侦听器。通常是不好的做法吗?
现在,如果我们实际使用事件,那么我会对实现感到困惑。
因此,我创建了一些新的事件类型(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

07-24 09:45
查看更多