diff options
Diffstat (limited to 'libjava/classpath/java/util/Observable.java')
-rw-r--r-- | libjava/classpath/java/util/Observable.java | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/libjava/classpath/java/util/Observable.java b/libjava/classpath/java/util/Observable.java new file mode 100644 index 00000000000..4c2cddb5496 --- /dev/null +++ b/libjava/classpath/java/util/Observable.java @@ -0,0 +1,180 @@ +/* Observable.java -- an object to be observed + Copyright (C) 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * This class represents an object which is observable. Other objects may + * register their intent to be notified when this object changes; and when + * this object does change, it will trigger the <code>update</code> method + * of each observer. + * + * Note that the <code>notifyObservers()</code> method of this class is + * unrelated to the <code>notify()</code> of Object. + * + * @author Warren Levy (warrenl@cygnus.com) + * @author Eric Blake (ebb9@email.byu.edu) + * @see Observer + * @status updated to 1.4 + */ +public class Observable +{ + /** Tracks whether this object has changed. */ + private boolean changed; + + /* List of the Observers registered as interested in this Observable. */ + private LinkedHashSet observers; + + /** + * Constructs an Observable with zero Observers. + */ + public Observable() + { + observers = new LinkedHashSet(); + } + + /** + * Adds an Observer. If the observer was already added this method does + * nothing. + * + * @param observer Observer to add + * @throws NullPointerException if observer is null + */ + public synchronized void addObserver(Observer observer) + { + observers.add(observer); + } + + /** + * Reset this Observable's state to unchanged. This is called automatically + * by <code>notifyObservers</code> once all observers have been notified. + * + * @see #notifyObservers() + */ + protected synchronized void clearChanged() + { + changed = false; + } + + /** + * Returns the number of observers for this object. + * + * @return number of Observers for this + */ + public synchronized int countObservers() + { + return observers.size(); + } + + /** + * Deletes an Observer of this Observable. + * + * @param victim Observer to delete + */ + public synchronized void deleteObserver(Observer victim) + { + observers.remove(victim); + } + + /** + * Deletes all Observers of this Observable. + */ + public synchronized void deleteObservers() + { + observers.clear(); + } + + /** + * True if <code>setChanged</code> has been called more recently than + * <code>clearChanged</code>. + * + * @return whether or not this Observable has changed + */ + public synchronized boolean hasChanged() + { + return changed; + } + + /** + * If the Observable has actually changed then tell all Observers about it, + * then reset state to unchanged. + * + * @see #notifyObservers(Object) + * @see Observer#update(Observable, Object) + */ + public void notifyObservers() + { + notifyObservers(null); + } + + /** + * If the Observable has actually changed then tell all Observers about it, + * then reset state to unchanged. Note that though the order of + * notification is unspecified in subclasses, in Observable it is in the + * order of registration. + * + * @param obj argument to Observer's update method + * @see Observer#update(Observable, Object) + */ + public void notifyObservers(Object obj) + { + if (! hasChanged()) + return; + // Create clone inside monitor, as that is relatively fast and still + // important to keep threadsafe, but update observers outside of the + // lock since update() can call arbitrary code. + Set s; + synchronized (this) + { + s = (Set) observers.clone(); + } + int i = s.size(); + Iterator iter = s.iterator(); + while (--i >= 0) + ((Observer) iter.next()).update(this, obj); + clearChanged(); + } + + /** + * Marks this Observable as having changed. + */ + protected synchronized void setChanged() + { + changed = true; + } +} |