简体   繁体   中英

MVC and event listeners in Java

I'm a bit confused on how to use event listeners between the model and controller. I'm working on an application that on the client side I split in two parts: the Client itself which does all the communication with the server and GUI. Client fires events about updates from server and gui fires events about users actions that server is interested in (the app is basically a multiuser graphic editor). So my questions:

  1. I found it easier to for GUI to keep a reference to the Client and vice-versa instead of firing events and using event listeners. Is it generally a bad practice?

  2. Now, if we actually use events, I got confused with the implementation. So I created a few types of events I'll new (drawEvent, connectionEvent, etc..). Then I implemented a ClientListener and a GUIListener with specific behavior. Now, how do I fire events? From reading, I understood, that in order for GUI to fire something it needs to call clientListener.eventHappened(event), right? So it needs to have that listener, ie Client and GUI have to share the listeners (seems to be more complicated that just references)? And finally, how do I actually add an instance of GUIListener to the gui? Again from what I read, I have to make a EventListenerList attribute and just add a new instance of a GUI listener there? Is that it? I don't see how this would trigger actual listening.

Sorry, I'm just learning all this stuff and don't have a full understanding. Thanks!

Not really sure whether you design is the best, but writing your own listeners/events is rather easy.

For example. you first define an interface for the listener and a class for the event

public class MyCustomEvent extends EventObject{
  //store all relevant info in your event
}

public interface MyListener{
  public void eventHappened( MyCustomEvent event);
}

Then, if you have a class to which you want to attach listeners, you just need to have methods to add the listeners, and call the eventHappened method on those listeners when needed

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 );
    }
  }
}

If you are wondering about the CopyOnWriteArrayList to store the listeners. When you are iterating over your listeners to fire the event, there is possibility that one of those listeners removes itself. So the typical solution is to first copy all the listeners into another list, and iterate over that list, or use a CopyOnWriteArrayList

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM