Java中的MVC和事件监听器

时间:2013-11-29 21:04:06

标签: java swing events model-view-controller listener

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

  1. 我发现GU​​I更容易保持对客户端的引用,反之亦然,而不是触发事件和使用事件侦听器。这通常是一种不好的做法吗?

  2. 现在,如果我们实际使用事件,我会对实现感到困惑。 所以我创建了一些我将要新的事件(drawEvent,connectionEvent等)。然后我实现了ClientListener和具有特定行为的GUIListener。现在,我如何解雇事件?从阅读开始,我明白,为了让GUI能够触发需要调用clientListener.eventHappened(event)的东西,对吧?所以它需要有那个监听器,即客户端和GUI必须共享监听器(似乎更复杂,只是引用)?最后,我如何实际向gui添加GUIListener的实例?从我读到的内容中,我必须创建一个EventListenerList属性,并在那里添加一个GUI监听器的新实例?是吗?我不知道这会如何引发实际聆听。

  3. 抱歉,我只是在学习所有这些东西而且没有完全理解。 谢谢!

1 个答案:

答案 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