Java has support through various event handling implementations - the simple Observer/Observable in java.util, PropertyChangeEvents in java.beans, and GUI events which inherit from AWTEvent.
An Observable object has a list of observers which implement the Observer interface, and mechanisms for adding and removing observers. If o.notifyObservers(x)
is called on the observable, update(o,x)
will be called on each observer. This mechanism is somewhat old fashioned and rarely used in new code - it dates from Java 1.0 before EventObject was added in Java 1.1 and better event handling added for AWT and beans.
Beans and GUI events propagate an object which extends java.util.EventObject to listeners which implement a sub-interface of EventListener. Usually if you're using an existing API you will only care about the events and listeners for that API, but if you're defining an API the events and listeners should follow that convention.
It's also the convention in Java APIs to call the handlers for events "listeners" rather than handlers, and all listener interface names end with Listener
. The names of the methods don't start with 'on' but should be past tense -mouseMoved
or handshakeCompleted
rather than onMouseMove
or handleMouseMove
.
The PropertyChangeSupport class provides an implementation of the mechanism for adding and removing listeners from a bean, and is also used for properties of Swing widgets.
If you write your own listener handling, it's conventional to allow listeners to remove themselves by calling source.removeXXXListener(this)
from within their event handling method. Just iterating over a simple collection of listeners and calling their handling methods would give a ConcurrentModificationException
with in these cases - you need to copy the collection of listeners or use a concurrently modifiable collection.