tags:

views:

52

answers:

3

When I learned how to fire events in Java, I became familiar with EventListenerList. When I create my own listeners, I write the listener so it extends EventListener, I store them in an EventListenerList, and my fire method would go through the event listeners like this:

protected void fireChangeOccurred(Change change) {
    Object[] listeners = listenerList.getListenerList();
    for (int i = listeners.length-2; i>=0; i-=2) {
        if (listeners[i]==ChangeListener.class) {
            ((ChangeListener)listeners[i+1]).changeOccurred(change);
        }
    }
}

Now I'm reviewing code that simply puts listeners into a HashMap (could be any collection), the listener interface does not extend EventListener, and the fire method looks like this:

protected void fireChangeOccurred(Change change) {
    for (ChangeListener listener : listeners) {
        listener.changeOccurred(change);
    }
}

What are the advantages of using EventListenerList instead of just maintaining my own list of listeners? Does it really only matter if the listeners are in a Swing component - does it matter for the Event Dispatch Thread?

A: 

There is no huge advantages this days. Just small optimizations. Here is what JavaDocs says:

main benefits that this class provides are that it is relatively cheap in the case of no listeners, and it provides serialization for event-listener lists in a single place, as well as a degree of MT safety (when used correctly)

With modern JVMs and collections it really doesn't matter. But what you could do with your own implementation is provide the way to fire changes on EDT if you using Swing - that would be beneficial.

eugener
+2  A: 

To me, the major advantage of EventListenerList is if the containing class has (or may have) more than one type of listener. Many Swing components do; the one you're reviewing may not. The second example is shorter, but it has that implicit design limitation.

trashgod
But wouldn't you just keep a separate list of listeners - List<ChangeListener> vs. List<LogListener>, for example?
David
@David: Yes, and so on for each type of listener; `JTable` is up to eight, but still has just one list. The `EventListenerList` array is a legacy; for non-swing events, a collection makes sense. I'd preserve the type-token, though.
trashgod
+2  A: 

EventListenerList has a method specifically for this case (where you are only interested in one event type):

protected void fireChangeOccurred(Change change) {
    for (ChangeListener listener:
         listenerList.getListeners(ChangeListener.class)) {
            listener.stateChanged(new ChangeEvent(this));
    }
}

If you choose to maintain your own collection of listeners, I recommend a CopyOnWriteArrayList.

finnw