try to fix some minor dropdown bugs
[potlatch2.git] / org / idmedia / as3commons / util / Observable.as
1 /*
2  * Copyright the original author or authors.
3  * 
4  * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.mozilla.org/MPL/MPL-1.1.html
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 ´╗┐package org.idmedia.as3commons.util {
17   import org.idmedia.as3commons.lang.NullPointerException;
18   
19   /**
20    * This class represents an Observable object, or "data"
21    * in the model-view paradigm. It can be subclassed to represent an 
22    * object that the application wants to have observed. 
23    * <p>
24    * An observable object can have one or more observers. An observer 
25    * may be any object that implements interface <tt>Observer</tt>. After an 
26    * Observable instance changes, an application calling the 
27    * <code>Observable</code>'s <code>notifyObservers</code> method  
28    * causes all of its observers to be notified of the change by a call 
29    * to their <code>update</code> method. 
30    * <p>
31    * The order in which notifications will be delivered is unspecified.  
32    * The default implementation provided in the Observable class will
33    * notify Observers in the order in which they registered interest, but 
34    * subclasses may change this order, use no guaranteed order,
35    * or may guarantee that their
36    * subclass follows this order, as they choose.
37    * <p>
38    * When an Observable object is newly created, its set of observers is 
39    * empty. Two observers are considered the same if and only if the 
40    * <tt>equals</tt> method returns true for them.
41    *
42    * @author sleistner
43    */
44   public class Observable {
45     
46     private var observers:List;
47     private var changed:Boolean;
48     
49     /** Construct an Observable with zero Observers. */
50     public function Observable() {
51       observers = new ArrayList();
52       changed = false;
53     }
54     
55     /**
56      * Marks this <tt>Observable</tt> object as having been changed; the 
57      * <tt>hasChanged</tt> method will now return <tt>true</tt>.
58      */
59     public function setChanged():void {
60       changed = true;
61     }
62     
63     /**
64      * Tests if this object has changed. 
65      *
66      * @return  <code>true</code> if and only if the <code>setChanged</code> 
67      *          method has been called more recently than the 
68      *          <code>clearChanged</code> method on this object; 
69      *          <code>false</code> otherwise.
70      * @see     #clearChanged()
71      * @see     #setChanged()
72      */
73     public function hasChanged():Boolean {
74       return changed;
75     }
76     
77     /**
78      * Indicates that this object has no longer changed, or that it has 
79      * already notified all of its observers of its most recent change, 
80      * so that the <tt>hasChanged</tt> method will now return <tt>false</tt>. 
81      * This method is called automatically by the 
82      * <code>notifyObservers</code> methods. 
83      *
84      * @see #notifyObservers()
85      */
86     public function clearChanged():void {
87       changed = false;  
88     }
89     
90     /**
91      * Adds an observer to the set of observers for this object, provided 
92      * that it is not the same as some observer already in the set. 
93      * The order in which notifications will be delivered to multiple 
94      * observers is not specified. See the class comment.
95      *
96      * @param   observer  an observer to be added.
97      * @throws NullPointerException   if the parameter observer is null.
98      */
99     public function addObserver(observer:Observer):void {
100       if(observer == null) {
101         throw new NullPointerException('observer must not be null');
102       }
103       if(!observers.contains(observer)) {
104         observers.add(observer);
105       } 
106     }
107     
108     /**
109      * Deletes an observer from the set of observers of this object. 
110      * Passing <CODE>null</CODE> to this method will have no effect.
111      * @param   observer   the observer to be deleted.
112      */
113     public function deleteObserver(observer:Observer = null):void {
114       observers.remove(observer);       
115     }
116     
117     /**
118      * Clears the observer list so that this object no longer has any observers.
119      */
120     public function deleteObservers():void {
121       observers.clear();        
122     }
123     
124     /**
125      * If this object has changed, as indicated by the 
126      * <code>hasChanged</code> method, then notify all of its observers 
127      * and then call the <code>clearChanged</code> method to indicate 
128      * that this object has no longer changed. 
129      * <p>
130      * Each observer has its <code>update</code> method called with two
131      * arguments: this observable object and the <code>arg</code> argument.
132      *
133      * @param   args   any object.
134      * @see     #clearChanged() #hasChanged()
135      * @see     #hasChanged() #hasChanged()
136      * @see     org.idmedia.as3commons.util.Observer#update() Observer#update()
137      */
138     public function notifyObservers(args:*):void {
139       if(!changed) {
140         return; 
141       }
142                         
143       clearChanged();
144                         
145       var iter:Iterator = observers.iterator();
146       while(iter.hasNext()) {
147         Observer(iter.next()).update(this, args);
148       } 
149     }
150     
151     /**
152      * Returns the number of observers of this <tt>Observable</tt> object.
153      *
154      * @return  the number of observers of this object.
155      */
156     public function countObservers():int {
157       return observers.size();  
158     }
159   }
160 }