KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > util > Observable


1 /*
2  * @(#)Observable.java 1.38 04/01/12
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.util;
9
10 /**
11  * This class represents an observable object, or "data"
12  * in the model-view paradigm. It can be subclassed to represent an
13  * object that the application wants to have observed.
14  * <p>
15  * An observable object can have one or more observers. An observer
16  * may be any object that implements interface <tt>Observer</tt>. After an
17  * observable instance changes, an application calling the
18  * <code>Observable</code>'s <code>notifyObservers</code> method
19  * causes all of its observers to be notified of the change by a call
20  * to their <code>update</code> method.
21  * <p>
22  * The order in which notifications will be delivered is unspecified.
23  * The default implementation provided in the Observable class will
24  * notify Observers in the order in which they registered interest, but
25  * subclasses may change this order, use no guaranteed order, deliver
26  * notifications on separate threads, or may guarantee that their
27  * subclass follows this order, as they choose.
28  * <p>
29  * Note that this notification mechanism is has nothing to do with threads
30  * and is completely separate from the <tt>wait</tt> and <tt>notify</tt>
31  * mechanism of class <tt>Object</tt>.
32  * <p>
33  * When an observable object is newly created, its set of observers is
34  * empty. Two observers are considered the same if and only if the
35  * <tt>equals</tt> method returns true for them.
36  *
37  * @author Chris Warth
38  * @version 1.38, 01/12/04
39  * @see java.util.Observable#notifyObservers()
40  * @see java.util.Observable#notifyObservers(java.lang.Object)
41  * @see java.util.Observer
42  * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
43  * @since JDK1.0
44  */

45 public class Observable {
46     private boolean changed = false;
47     private Vector JavaDoc obs;
48    
49     /** Construct an Observable with zero Observers. */
50
51     public Observable() {
52     obs = new Vector JavaDoc();
53     }
54
55     /**
56      * Adds an observer to the set of observers for this object, provided
57      * that it is not the same as some observer already in the set.
58      * The order in which notifications will be delivered to multiple
59      * observers is not specified. See the class comment.
60      *
61      * @param o an observer to be added.
62      * @throws NullPointerException if the parameter o is null.
63      */

64     public synchronized void addObserver(Observer JavaDoc o) {
65         if (o == null)
66             throw new NullPointerException JavaDoc();
67     if (!obs.contains(o)) {
68         obs.addElement(o);
69     }
70     }
71
72     /**
73      * Deletes an observer from the set of observers of this object.
74      * Passing <CODE>null</CODE> to this method will have no effect.
75      * @param o the observer to be deleted.
76      */

77     public synchronized void deleteObserver(Observer JavaDoc o) {
78         obs.removeElement(o);
79     }
80
81     /**
82      * If this object has changed, as indicated by the
83      * <code>hasChanged</code> method, then notify all of its observers
84      * and then call the <code>clearChanged</code> method to
85      * indicate that this object has no longer changed.
86      * <p>
87      * Each observer has its <code>update</code> method called with two
88      * arguments: this observable object and <code>null</code>. In other
89      * words, this method is equivalent to:
90      * <blockquote><tt>
91      * notifyObservers(null)</tt></blockquote>
92      *
93      * @see java.util.Observable#clearChanged()
94      * @see java.util.Observable#hasChanged()
95      * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
96      */

97     public void notifyObservers() {
98     notifyObservers(null);
99     }
100
101     /**
102      * If this object has changed, as indicated by the
103      * <code>hasChanged</code> method, then notify all of its observers
104      * and then call the <code>clearChanged</code> method to indicate
105      * that this object has no longer changed.
106      * <p>
107      * Each observer has its <code>update</code> method called with two
108      * arguments: this observable object and the <code>arg</code> argument.
109      *
110      * @param arg any object.
111      * @see java.util.Observable#clearChanged()
112      * @see java.util.Observable#hasChanged()
113      * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
114      */

115     public void notifyObservers(Object JavaDoc arg) {
116     /*
117          * a temporary array buffer, used as a snapshot of the state of
118          * current Observers.
119          */

120         Object JavaDoc[] arrLocal;
121
122     synchronized (this) {
123         /* We don't want the Observer doing callbacks into
124          * arbitrary code while holding its own Monitor.
125          * The code where we extract each Observable from
126          * the Vector and store the state of the Observer
127          * needs synchronization, but notifying observers
128          * does not (should not). The worst result of any
129          * potential race-condition here is that:
130          * 1) a newly-added Observer will miss a
131          * notification in progress
132          * 2) a recently unregistered Observer will be
133          * wrongly notified when it doesn't care
134          */

135         if (!changed)
136                 return;
137             arrLocal = obs.toArray();
138             clearChanged();
139         }
140
141         for (int i = arrLocal.length-1; i>=0; i--)
142             ((Observer JavaDoc)arrLocal[i]).update(this, arg);
143     }
144
145     /**
146      * Clears the observer list so that this object no longer has any observers.
147      */

148     public synchronized void deleteObservers() {
149     obs.removeAllElements();
150     }
151
152     /**
153      * Marks this <tt>Observable</tt> object as having been changed; the
154      * <tt>hasChanged</tt> method will now return <tt>true</tt>.
155      */

156     protected synchronized void setChanged() {
157     changed = true;
158     }
159
160     /**
161      * Indicates that this object has no longer changed, or that it has
162      * already notified all of its observers of its most recent change,
163      * so that the <tt>hasChanged</tt> method will now return <tt>false</tt>.
164      * This method is called automatically by the
165      * <code>notifyObservers</code> methods.
166      *
167      * @see java.util.Observable#notifyObservers()
168      * @see java.util.Observable#notifyObservers(java.lang.Object)
169      */

170     protected synchronized void clearChanged() {
171     changed = false;
172     }
173
174     /**
175      * Tests if this object has changed.
176      *
177      * @return <code>true</code> if and only if the <code>setChanged</code>
178      * method has been called more recently than the
179      * <code>clearChanged</code> method on this object;
180      * <code>false</code> otherwise.
181      * @see java.util.Observable#clearChanged()
182      * @see java.util.Observable#setChanged()
183      */

184     public synchronized boolean hasChanged() {
185     return changed;
186     }
187
188     /**
189      * Returns the number of observers of this <tt>Observable</tt> object.
190      *
191      * @return the number of observers of this object.
192      */

193     public synchronized int countObservers() {
194     return obs.size();
195     }
196 }
197
Popular Tags