/* * GeoSetBroadcaster.java * * Created on January 15, 2007, 6:08 PM * */ package ika.geo; import java.io.IOException; import java.io.ObjectInputStream; import java.util.Vector; /** * Extends the GeoSet class with event handling. A MapEventListener can be * registered for change events in the tree. * @author Bernhard Jenny, Institute of Cartography, ETH Zurich. */ public class GeoSetBroadcaster extends GeoSet { private static final long serialVersionUID = -632850350013391825L; /** * A set of registered MapEventListeners. */ transient private Vector<MapEventListener> mapEventListeners; /** * Remember whether sending events is temporarily suspended. */ transient private boolean eventsSuspended; /** * Remember whether informMapEventListeners() is currently informing all * listeners. This makes sure that an event handler is not called again if * it changes any GeoObject in the tree. */ transient private boolean informingListeners; /** * Creates a new instance of GeoSetBroadcaster */ public GeoSetBroadcaster() { this.init(); } /** * Transient attributes need customized deserialization. */ private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { // read this object stream.defaultReadObject(); this.init(); } /** * Initialize the transient attributes. */ private void init() { this.mapEventListeners = new Vector<MapEventListener>(); this.eventsSuspended = false; this.informingListeners = false; } /** * Register a MapEventListener. * * @param listener The MapEventListener to register. */ public final synchronized void addMapEventListener(MapEventListener listener) { if (listener != null) { this.mapEventListeners.add(listener); } } /** * Static method to register a MapEventListener. * * @param listener The MapEventListener to register. * @param geoObject Any GeoObject in the tree. The toplevel parent must be * a GeoSetBroadcaster. */ static public void addMapEventListener(MapEventListener listener, GeoObject geoObject) { GeoSetBroadcaster root = geoObject.getRoot(); if (root == null) { throw new IllegalArgumentException("GeoObject is not in tree with GeoTreeRoot root."); } root.addMapEventListener(listener); } /** * Unregister a MapEventListener. */ public final synchronized void removeMapEventListener(MapEventListener listener) { this.mapEventListeners.remove(listener); } /** * Remove every registered MapEventListener. */ public final synchronized void removeAllMapEventListeners() { this.mapEventListeners.clear(); } /** * Temporarily suspend event distribution to MapEventListener. */ public final synchronized void suspendMapEventListeners() { this.eventsSuspended = true; } /** * Activate distribution of events again. */ public final synchronized void activateMapEventListeners() { this.eventsSuspended = false; } /** * Returns whether distribution of events is currently suspended. */ public final synchronized boolean mapEventListenersSuspended() { return this.eventsSuspended; } /** * Inform each registered MapEventListener about a change. */ public final void informMapEventListeners(final MapEvent evt) { synchronized (this) { if (this.eventsSuspended || this.informingListeners) { return; } evt.setRootGeoSet(this); } /* ika.utils.SwingThreadUtils.invokeAndWait(new Runnable() { public void run() { */ try { informingListeners = true; for (int i = mapEventListeners.size() - 1; i >= 0; i--) { mapEventListeners.get(i).mapEvent(evt); } } finally { informingListeners = false; } } // }); // } }