Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use EventListenerList instead of a general collection of listeners

Tags:

java

events

swing

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?

like image 674
David Koelle Avatar asked Jul 13 '10 18:07

David Koelle


2 Answers

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.

like image 152
finnw Avatar answered Sep 20 '22 13:09

finnw


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.

like image 26
trashgod Avatar answered Sep 19 '22 13:09

trashgod