58 |
private boolean changed; |
private boolean changed; |
59 |
|
|
60 |
/* List of the Observers registered as interested in this Observable. */ |
/* List of the Observers registered as interested in this Observable. */ |
61 |
private Vector observers; |
private LinkedHashSet observers; |
|
|
|
|
/* TBD: This might be better implemented as an Observer[] |
|
|
* but that would mean writing more code rather than making use of |
|
|
* the existing Vector class (this also implies a larger text code |
|
|
* space in resulting executables). The tradeoff is one of speed |
|
|
* (manipulating the Observer[] directly) vs. size/reuse. In the future, |
|
|
* we may decide to make the tradeoff and reimplement with an Observer[]. |
|
|
*/ |
|
62 |
|
|
63 |
/** |
/** |
64 |
* Constructs an Observable with zero Observers. |
* Constructs an Observable with zero Observers. |
65 |
*/ |
*/ |
66 |
public Observable() |
public Observable() |
67 |
{ |
{ |
68 |
changed = false; |
observers = new LinkedHashSet(); |
|
observers = new Vector(); |
|
69 |
} |
} |
70 |
|
|
71 |
/** |
/** |
77 |
*/ |
*/ |
78 |
public synchronized void addObserver(Observer observer) |
public synchronized void addObserver(Observer observer) |
79 |
{ |
{ |
80 |
if (! observers.contains(observer)) |
observers.add(observer); |
|
observers.addElement(observer); |
|
81 |
} |
} |
82 |
|
|
83 |
/** |
/** |
108 |
*/ |
*/ |
109 |
public synchronized void deleteObserver(Observer victim) |
public synchronized void deleteObserver(Observer victim) |
110 |
{ |
{ |
111 |
observers.removeElement(victim); |
observers.remove(victim); |
112 |
} |
} |
113 |
|
|
114 |
/** |
/** |
116 |
*/ |
*/ |
117 |
public synchronized void deleteObservers() |
public synchronized void deleteObservers() |
118 |
{ |
{ |
119 |
observers.removeAllElements(); |
observers.clear(); |
120 |
} |
} |
121 |
|
|
122 |
/** |
/** |
155 |
{ |
{ |
156 |
if (! hasChanged()) |
if (! hasChanged()) |
157 |
return; |
return; |
158 |
Vector ob1 = (Vector) observers.clone(); |
// Create clone inside monitor, as that is relatively fast and still |
159 |
|
// important to keep threadsafe, but update observers outside of the |
160 |
for (int i = 0; i < ob1.size(); i++) |
// lock since update() can call arbitrary code. |
161 |
((Observer) ob1.elementAt(i)).update(this, obj); |
Set s; |
162 |
|
synchronized (this) |
163 |
|
{ |
164 |
|
s = (Set) observers.clone(); |
165 |
|
} |
166 |
|
int i = s.size(); |
167 |
|
Iterator iter = s.iterator(); |
168 |
|
while (--i >= 0) |
169 |
|
((Observer) iter.next()).update(this, obj); |
170 |
clearChanged(); |
clearChanged(); |
171 |
} |
} |
172 |
|
|