Last changed: Nov 22 2004
This page gives an example and a code skeleton of the observer/observable pattern in Java.
The observable class could extend java.util.Observable but due to the multiple inheritance issues it might be preferred to use an aggregated class as in this example.
public class ExampleClass { EventNotifier eventNotifier = new EventNotifier(); // ----------------------------------------------------------------------------------- OBSERVABLE /** * These methods turn the class into an Observable object. * * @see java.util.Observer * @see java.util.Observable */ public void addObserver(java.util.Observer o){ eventNotifier.addObserver(o); } public void deleteObserver(java.util.Observer o){ eventNotifier.deleteObserver(o); } public void notifyObservers(){ eventNotifier.notifyObservers(); } public void notifyObservers( ExampleClassEvent arg){ eventNotifier.notifyObservers(arg); } public void deleteObservers(){ eventNotifier.deleteObservers(); } protected void setChanged(){ eventNotifier.doSetChanged(); } protected void clearChanged(){ eventNotifier.doClearChanged(); } public boolean hasChanged(){ return eventNotifier.hasChanged(); } public int countObservers(){ return eventNotifier.countObservers(); } /** * Empty class needed to allow observers. * Observers must implement Observer interface. */ protected class EventNotifier extends java.util.Observable { void doSetChanged(){ super.setChanged(); } void doClearChanged(){ super.clearChanged(); } }//EventNotifier ExampleClass() { letObserversKnow( "ExampleClass created!", ExampleClassEvent.LOG ); // usage example } void letObserversKnow( String msg, int type ) { setChanged(); notifyObservers( new ExampleClassEvent( type, msg ) ); }// letObserversKnow } // class /** +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * Represents a network event reported to an observer. */ class ExampleClassEvent { /** Type of the event. */ public final int type; public static final int LOG = 0; /** Type-dependent content of the event. */ public Object message; /** * Constructs an event of the type 'type' including a 'message'. * * @param message the object of the event (e.g. that what is received) * @param type the type of the event */ public ExampleClassEvent( Object message, int type ) { this.message = message; this.type = type; }// constr /** * Constructs an event of the type 'type' including a 'message'. * * @param type the type of the event * @param message the object of the event (e.g. that what is received) */ public ExampleClassEvent( int type, Object message ) { this( message, type ); }// constr /** Returns type of the event. * @return type of the event. */ public int getType() {return type; }; /** Returns 'content' of the event, which is type-dependent. *@return 'content' of the event */ public Object getMessage() { return message; }; }// ExampleClassEvent
The observer must implement java.util.Observer and its function update.
class ExampleObserver implements java.util.Observer { /* @param o = sender of the message (arg). The observer may observe more objects. */ public void update(java.util.Observable o, Object arg ) { ExampleClassEvent event = (ExampleClassEvent)arg; int type = event.type; switch(type) { case ExampleClassEvent.LOG: // YOUR CODE COMES HERE System.out.println( (String)(event.getMessage()) ); break; default: // unknown type == an error break; }//switch }//update }