001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package java.util;
019:
020: /**
021: * Observable is used to notify a group of Observer objects when a change
022: * occurs.
023: */
024: public class Observable {
025:
026: List<Observer> observers = new ArrayList<Observer>();
027:
028: boolean changed = false;
029:
030: /**
031: * Constructs a new Observable object.
032: */
033: public Observable() {
034: super ();
035: }
036:
037: /**
038: * Adds the specified Observer to the list of observers.
039: *
040: * @param observer
041: * the Observer to add
042: */
043: public void addObserver(Observer observer) {
044: if (observer == null) {
045: throw new NullPointerException();
046: }
047: synchronized (this ) {
048: if (!observers.contains(observer))
049: observers.add(observer);
050: }
051: }
052:
053: /**
054: * Clears the changed flag for this Observable. After calling
055: * <code>clearChanged()</code>, <code>hasChanged()</code> will return
056: * false.
057: */
058: protected void clearChanged() {
059: changed = false;
060: }
061:
062: /**
063: * Answers the number of Observers in the list of observers.
064: *
065: * @return the number of observers
066: */
067: public int countObservers() {
068: return observers.size();
069: }
070:
071: /**
072: * Removes the specified Observer from the list of observers.
073: *
074: * @param observer
075: * the Observer to remove
076: */
077: public synchronized void deleteObserver(Observer observer) {
078: observers.remove(observer);
079: }
080:
081: /**
082: * Removes all Observers from the list of observers.
083: */
084: public synchronized void deleteObservers() {
085: observers.clear();
086: }
087:
088: /**
089: * Answers the changed flag for this Observable.
090: *
091: * @return true when the changed flag for this Observable is set, false
092: * otherwise
093: */
094: public boolean hasChanged() {
095: return changed;
096: }
097:
098: /**
099: * If <code>hasChanged()</code> returns true, calls the
100: * <code>update()</code> method for every Observer in the list of
101: * observers using null as the argument. Afterwards calls
102: * <code>clearChanged()</code>.
103: *
104: * Equivalent to calling <code>notifyObservers(null)</code>
105: */
106: public void notifyObservers() {
107: notifyObservers(null);
108: }
109:
110: /**
111: * If <code>hasChanged()</code> returns true, calls the
112: * <code>update()</code> method for every Observer in the list of
113: * observers using the specified argument. Afterwards calls
114: * <code>clearChanged()</code>.
115: *
116: * @param data
117: * the argument passed to update()
118: */
119: @SuppressWarnings("unchecked")
120: public void notifyObservers(Object data) {
121: int size = 0;
122: Observer[] arrays = null;
123: synchronized (this ) {
124: if (hasChanged()) {
125: clearChanged();
126: size = observers.size();
127: arrays = new Observer[size];
128: observers.toArray(arrays);
129: }
130: }
131: if (arrays != null) {
132: for (Observer observer : arrays) {
133: observer.update(this , data);
134: }
135: }
136: }
137:
138: /**
139: * Sets the changed flag for this Observable. After calling
140: * <code>setChanged()</code>, <code>hasChanged()</code> will return
141: * true.
142: */
143: protected void setChanged() {
144: changed = true;
145: }
146: }
|