public void notifyListeners() {
if (log.isLoggable(PlatformLogger.FINEST)) {
log.finest("notifyListeners");
}
// This method is implemented by making a clone of the set of listeners,
// and then iterating over the clone. This is because during the course
// of responding to a display change, it may be appropriate for a
// DisplayChangedListener to add or remove itself from a SunDisplayChanger.
// If the set itself were iterated over, rather than a clone, it is
// trivial to get a ConcurrentModificationException by having a
// DisplayChangedListener remove itself from its list.
// Because all display change handling is done on the event thread,
// synchronization provides no protection against modifying the listener
// list while in the middle of iterating over it. -bchristi 7/10/2001
HashMap listClone;
Set cloneSet;
synchronized(listeners) {
listClone = new HashMap(listeners);
}
cloneSet = listClone.keySet();
Iterator itr = cloneSet.iterator();
while (itr.hasNext()) {
DisplayChangedListener current =
(DisplayChangedListener) itr.next();
try {
if (log.isLoggable(PlatformLogger.FINEST)) {
log.finest("displayChanged for listener: " + current);
}
current.displayChanged();
} catch (IllegalComponentStateException e) {
// This DisplayChangeListener is no longer valid. Most
// likely, a top-level window was dispose()d, but its
// Java objects have not yet been garbage collected. In any
// case, we no longer need to track this listener, though we
// do need to remove it from the original list, not the clone.
listeners.remove(current);
}
}
}
|