Java – When to use EventListenerList instead of a general collection of listeners

eventsjavaswing

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?

Best Answer

EventListenerList has a method, getListeners(Class<T> t), specifically for the case where you are only interested in one event type.

Here's an example of how to use it:

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.