home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1998 February / VPR9802A.ISO / APP_DEMO / VC / MAIN.BIN / Observable.java < prev    next >
Text File  |  1997-10-27  |  7KB  |  203 lines

  1. /*
  2.  * @(#)Observable.java    1.19 97/02/18
  3.  * 
  4.  * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  * CopyrightVersion 1.1_beta
  20.  * 
  21.  */
  22.  
  23. package java.util;
  24.  
  25. /**
  26.  * This class represents an observable object, or "data"
  27.  * in the model-view paradigm. It can be subclassed to represent an 
  28.  * object that the application wants to have observed. 
  29.  * <p>
  30.  * An observable object can have one or more observers. After an 
  31.  * observable instance changes, an application calling the 
  32.  * <code>Observable</code>'s <code>notifyObservers</code> method  
  33.  * causes all of its observers to be notified of the change by a call 
  34.  * to their <code>update</code> method. 
  35.  *
  36.  * @author  Chris Warth
  37.  * @version 1.19, 02/18/97
  38.  * @see     java.util.Observable#notifyObservers()
  39.  * @see     java.util.Observable#notifyObservers(java.lang.Object)
  40.  * @see     java.util.Observer
  41.  * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
  42.  * @since   JDK1.0
  43.  */
  44. public class Observable {
  45.     private boolean changed = false;
  46.     private Vector obs;
  47.     /* a temporary array buffer, used as a snapshot of the state of
  48.      * current Observers.  We do notifications on this snapshot while
  49.      * not under synchronization.
  50.      */
  51.     private Observer[] arr = new Observer[2];
  52.     /** Construct an Observable with zero Observers */
  53.  
  54.     public Observable() {
  55.     obs = new Vector();
  56.     }
  57.  
  58.     /**
  59.      * Adds an observer to the set of observers for this object. 
  60.      *
  61.      * @param   o   an observer to be added.
  62.      * @since   JDK1.0
  63.      */
  64.     public synchronized void addObserver(Observer o) {
  65.     if (!obs.contains(o)) {
  66.         obs.addElement(o);
  67.     }
  68.     }
  69.  
  70.     /**
  71.      * Deletes an observer from the set of observers of this object. 
  72.      *
  73.      * @param   o   the observer to be deleted.
  74.      * @since   JDK1.0
  75.      */
  76.     public synchronized void deleteObserver(Observer o) {
  77.         obs.removeElement(o);
  78.     }
  79.  
  80.     /**
  81.      * If this object has changed, as indicated by the 
  82.      * <code>hasChanged</code> method, then notify all of its observers 
  83.      * and then call the <code>clearChanged</code> method to 
  84.      * indicate that this object has no longer changed. 
  85.      * <p>
  86.      * Each observer has its <code>update</code> method called with two
  87.      * arguments: this observable object and <code>null</code>. 
  88.      *
  89.      * @see     java.util.Observable#clearChanged()
  90.      * @see     java.util.Observable#hasChanged()
  91.      * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
  92.      * @since   JDK1.0
  93.      */
  94.     public void notifyObservers() {
  95.     notifyObservers(null);
  96.     }
  97.  
  98.     /**
  99.      * If this object has changed, as indicated by the 
  100.      * <code>hasChanged</code> method, then notify all of its observers 
  101.      * and then call the <code>clearChanged</code> method to indicate 
  102.      * that this object has no longer changed. 
  103.      * <p>
  104.      * Each observer has its <code>update</code> method called with two
  105.      * arguments: this observable object and the <code>arg</code> argument.
  106.      *
  107.      * @param   arg   any object.
  108.      * @see     java.util.Observable#clearChanged()
  109.      * @see     java.util.Observable#hasChanged()
  110.      * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
  111.      * @since   JDK1.0
  112.      */
  113.     public void notifyObservers(Object arg) {
  114.  
  115.     int size=0;
  116.  
  117.     synchronized (this) {
  118.         /* We don't want the Observer doing callbacks into
  119.          * into arbitrary code while holding its own Monitor.
  120.          * The code where we extract each Observable from 
  121.          * the Vector and store the state of the Observer
  122.          * needs synchronization, but notifying observers
  123.          * does not (should not).  The worst result of any 
  124.          * potential race-condition here is that:
  125.          * 1) a newly-added Observer will miss a
  126.          *   notification in progress
  127.          * 2) a recently unregistered Observer will be
  128.          *   wrongly notified when it doesn't care
  129.          */
  130.         if (!hasChanged())
  131.         return;
  132.         size = obs.size();
  133.         if (size > arr.length) {
  134.         arr = new Observer[size];
  135.         }
  136.         obs.copyInto(arr);
  137.         clearChanged();
  138.     }
  139.  
  140.     for (int i = size -1; i>=0; i--) {
  141.         if (arr[i] != null) {
  142.         arr[i].update(this, arg);
  143.         }
  144.     }
  145.     }
  146.  
  147.     /**
  148.      * Clears the observer list so that this object no longer has any observers.
  149.      *
  150.      * @since   JDK1.0
  151.      */
  152.     public synchronized void deleteObservers() {
  153.     obs.removeAllElements();
  154.     }
  155.  
  156.     /**
  157.      * Indicates that this object has changed. 
  158.      *
  159.      * @since   JDK1.0
  160.      */
  161.     protected synchronized void setChanged() {
  162.     changed = true;
  163.     }
  164.  
  165.     /**
  166.      * Indicates that this object has no longer changed, or that it has 
  167.      * already notified all of its observers of its most recent change. 
  168.      * This method is called automatically by the 
  169.      * <code>notifyObservers</code> methods. 
  170.      *
  171.      * @see     java.util.Observable#notifyObservers()
  172.      * @see     java.util.Observable#notifyObservers(java.lang.Object)
  173.      * @since   JDK1.0
  174.      */
  175.     protected synchronized void clearChanged() {
  176.     changed = false;
  177.     }
  178.  
  179.     /**
  180.      * Tests if this object has changed. 
  181.      *
  182.      * @return  <code>true</code> if the <code>setChanged</code> method
  183.      *          has been called more recently than the <code>clearChanged</code>
  184.      *          method on this object; <code>false</code> otherwise.
  185.      * @see     java.util.Observable#clearChanged()
  186.      * @see     java.util.Observable#setChanged()
  187.      * @since   JDK1.0
  188.      */
  189.     public synchronized boolean hasChanged() {
  190.     return changed;
  191.     }
  192.  
  193.     /**
  194.      * Returns the number of observers of this object.
  195.      *
  196.      * @return  the number of observers of this object.
  197.      * @since   JDK1.0
  198.      */
  199.     public synchronized int countObservers() {
  200.     return obs.size();
  201.     }
  202. }
  203.