home *** CD-ROM | disk | FTP | other *** search
Java Source | 1997-05-20 | 6.6 KB | 203 lines |
- /*
- * @(#)Observable.java 1.19 97/02/18
- *
- * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
- *
- * This software is the confidential and proprietary information of Sun
- * Microsystems, Inc. ("Confidential Information"). You shall not
- * disclose such Confidential Information and shall use it only in
- * accordance with the terms of the license agreement you entered into
- * with Sun.
- *
- * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
- * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
- * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
- * THIS SOFTWARE OR ITS DERIVATIVES.
- *
- * CopyrightVersion 1.1_beta
- *
- */
-
- package java.util;
-
- /**
- * This class represents an observable object, or "data"
- * in the model-view paradigm. It can be subclassed to represent an
- * object that the application wants to have observed.
- * <p>
- * An observable object can have one or more observers. After an
- * observable instance changes, an application calling the
- * <code>Observable</code>'s <code>notifyObservers</code> method
- * causes all of its observers to be notified of the change by a call
- * to their <code>update</code> method.
- *
- * @author Chris Warth
- * @version 1.19, 02/18/97
- * @see java.util.Observable#notifyObservers()
- * @see java.util.Observable#notifyObservers(java.lang.Object)
- * @see java.util.Observer
- * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
- * @since JDK1.0
- */
- public class Observable {
- private boolean changed = false;
- private Vector obs;
- /* a temporary array buffer, used as a snapshot of the state of
- * current Observers. We do notifications on this snapshot while
- * not under synchronization.
- */
- private Observer[] arr = new Observer[2];
- /** Construct an Observable with zero Observers */
-
- public Observable() {
- obs = new Vector();
- }
-
- /**
- * Adds an observer to the set of observers for this object.
- *
- * @param o an observer to be added.
- * @since JDK1.0
- */
- public synchronized void addObserver(Observer o) {
- if (!obs.contains(o)) {
- obs.addElement(o);
- }
- }
-
- /**
- * Deletes an observer from the set of observers of this object.
- *
- * @param o the observer to be deleted.
- * @since JDK1.0
- */
- public synchronized void deleteObserver(Observer o) {
- obs.removeElement(o);
- }
-
- /**
- * If this object has changed, as indicated by the
- * <code>hasChanged</code> method, then notify all of its observers
- * and then call the <code>clearChanged</code> method to
- * indicate that this object has no longer changed.
- * <p>
- * Each observer has its <code>update</code> method called with two
- * arguments: this observable object and <code>null</code>.
- *
- * @see java.util.Observable#clearChanged()
- * @see java.util.Observable#hasChanged()
- * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
- * @since JDK1.0
- */
- public void notifyObservers() {
- notifyObservers(null);
- }
-
- /**
- * If this object has changed, as indicated by the
- * <code>hasChanged</code> method, then notify all of its observers
- * and then call the <code>clearChanged</code> method to indicate
- * that this object has no longer changed.
- * <p>
- * Each observer has its <code>update</code> method called with two
- * arguments: this observable object and the <code>arg</code> argument.
- *
- * @param arg any object.
- * @see java.util.Observable#clearChanged()
- * @see java.util.Observable#hasChanged()
- * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
- * @since JDK1.0
- */
- public void notifyObservers(Object arg) {
-
- int size=0;
-
- synchronized (this) {
- /* We don't want the Observer doing callbacks into
- * into arbitrary code while holding its own Monitor.
- * The code where we extract each Observable from
- * the Vector and store the state of the Observer
- * needs synchronization, but notifying observers
- * does not (should not). The worst result of any
- * potential race-condition here is that:
- * 1) a newly-added Observer will miss a
- * notification in progress
- * 2) a recently unregistered Observer will be
- * wrongly notified when it doesn't care
- */
- if (!hasChanged())
- return;
- size = obs.size();
- if (size > arr.length) {
- arr = new Observer[size];
- }
- obs.copyInto(arr);
- clearChanged();
- }
-
- for (int i = size -1; i>=0; i--) {
- if (arr[i] != null) {
- arr[i].update(this, arg);
- }
- }
- }
-
- /**
- * Clears the observer list so that this object no longer has any observers.
- *
- * @since JDK1.0
- */
- public synchronized void deleteObservers() {
- obs.removeAllElements();
- }
-
- /**
- * Indicates that this object has changed.
- *
- * @since JDK1.0
- */
- protected synchronized void setChanged() {
- changed = true;
- }
-
- /**
- * Indicates that this object has no longer changed, or that it has
- * already notified all of its observers of its most recent change.
- * This method is called automatically by the
- * <code>notifyObservers</code> methods.
- *
- * @see java.util.Observable#notifyObservers()
- * @see java.util.Observable#notifyObservers(java.lang.Object)
- * @since JDK1.0
- */
- protected synchronized void clearChanged() {
- changed = false;
- }
-
- /**
- * Tests if this object has changed.
- *
- * @return <code>true</code> if the <code>setChanged</code> method
- * has been called more recently than the <code>clearChanged</code>
- * method on this object; <code>false</code> otherwise.
- * @see java.util.Observable#clearChanged()
- * @see java.util.Observable#setChanged()
- * @since JDK1.0
- */
- public synchronized boolean hasChanged() {
- return changed;
- }
-
- /**
- * Returns the number of observers of this object.
- *
- * @return the number of observers of this object.
- * @since JDK1.0
- */
- public synchronized int countObservers() {
- return obs.size();
- }
- }
-