FileDocCategorySizeDatePackage
ChangeMonitor.javaAPI DocExample2475Sat Feb 01 07:43:02 GMT 1997imaginary.gui

ChangeMonitor.java

/**
 * This class manages a queue of ChangeObserver objects.  Each time
 * a change occurs to a Persistent object, the Persistent calls
 * update() in all observers.  Because RMI blocks during remote method
 * calls, you need to do any display changes in a new thread.  So
 * update() calls ChangeMonitor.postChange() which adds the object
 * to the stack.  A separate thread then periodically checks the stack
 * and calls observeChange() in each of the ChangeObserver instances
 * on the stack.
 */
package imaginary.gui;

import java.util.Enumeration;
import java.util.Vector;

public class ChangeMonitor extends Thread {
    // the monitor is a single thread that monitors the change queue
    static private ChangeMonitor monitor = new ChangeMonitor();

    /**
     * Adds a ChangeObserver object onto the queue.
     * @param observer the observer to add to the stack
     */
    static public void postChange(ChangeObserver observer) {
        ChangeMonitor.monitor.post(observer);
    }

    // The queue of ChangeObserver instances
    private Vector queue = new Vector();

    /**
     * Constructs a new monitor thread that maintains the queue.
     */
    public ChangeMonitor() {
        super();
        setDaemon(true);
        start();
    }

    // Actually sticks the observer into the queue.
    private void post(ChangeObserver observer) {
        synchronized(queue) {
            queue.addElement(observer);
        }
    }

    /**
     * Grabs the entire queue in an enumeration and calls observeChange()
     * in each one.
     * @see imaginary.gui.ChangeObserver#observeChange
     */
    public void run() {
        while( true ) {
            Enumeration elems;

            // Grab a queue enumeration quickly and release
            // the synchronization.
            synchronized(queue) {
                if( !queue.isEmpty() ) {
                    elems = queue.elements();
                    queue = new Vector();
                }
                else {
                    elems = null;
                }
            }
            if( elems != null ) {
                while( elems.hasMoreElements() ) {
                    ChangeObserver o = (ChangeObserver)elems.nextElement();

                    o.observeChange();
                }
            }
            try { Thread.sleep(500); }
            catch( InterruptedException e ) { }
        }
    }
}