|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.awt; |
|
|
|
import java.awt.IllegalComponentStateException; |
|
import java.util.Collections; |
|
import java.util.Iterator; |
|
import java.util.HashMap; |
|
import java.util.HashSet; |
|
import java.util.Map; |
|
import java.util.Set; |
|
import java.util.WeakHashMap; |
|
|
|
import sun.util.logging.PlatformLogger; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public class SunDisplayChanger { |
|
|
|
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.multiscreen.SunDisplayChanger"); |
|
|
|
// Create a new synchronized map with initial capacity of one listener. |
|
// It is asserted that the most common case is to have one GraphicsDevice |
|
|
|
private Map<DisplayChangedListener, Void> listeners = |
|
Collections.synchronizedMap(new WeakHashMap<DisplayChangedListener, Void>(1)); |
|
|
|
public SunDisplayChanger() {} |
|
|
|
|
|
|
|
|
|
*/ |
|
public void add(DisplayChangedListener theListener) { |
|
if (log.isLoggable(PlatformLogger.Level.FINE)) { |
|
if (theListener == null) { |
|
log.fine("Assertion (theListener != null) failed"); |
|
} |
|
} |
|
if (log.isLoggable(PlatformLogger.Level.FINER)) { |
|
log.finer("Adding listener: " + theListener); |
|
} |
|
listeners.put(theListener, null); |
|
} |
|
|
|
|
|
|
|
*/ |
|
public void remove(DisplayChangedListener theListener) { |
|
if (log.isLoggable(PlatformLogger.Level.FINE)) { |
|
if (theListener == null) { |
|
log.fine("Assertion (theListener != null) failed"); |
|
} |
|
} |
|
if (log.isLoggable(PlatformLogger.Level.FINER)) { |
|
log.finer("Removing listener: " + theListener); |
|
} |
|
listeners.remove(theListener); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public void notifyListeners() { |
|
if (log.isLoggable(PlatformLogger.Level.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 |
|
|
|
Set<DisplayChangedListener> cloneSet; |
|
|
|
synchronized(listeners) { |
|
cloneSet = new HashSet<DisplayChangedListener>(listeners.keySet()); |
|
} |
|
|
|
Iterator<DisplayChangedListener> itr = cloneSet.iterator(); |
|
while (itr.hasNext()) { |
|
DisplayChangedListener current = itr.next(); |
|
try { |
|
if (log.isLoggable(PlatformLogger.Level.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 |
|
|
|
listeners.remove(current); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public void notifyPaletteChanged() { |
|
if (log.isLoggable(PlatformLogger.Level.FINEST)) { |
|
log.finest("notifyPaletteChanged"); |
|
} |
|
// 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 |
|
|
|
Set<DisplayChangedListener> cloneSet; |
|
|
|
synchronized (listeners) { |
|
cloneSet = new HashSet<DisplayChangedListener>(listeners.keySet()); |
|
} |
|
Iterator<DisplayChangedListener> itr = cloneSet.iterator(); |
|
while (itr.hasNext()) { |
|
DisplayChangedListener current = itr.next(); |
|
try { |
|
if (log.isLoggable(PlatformLogger.Level.FINEST)) { |
|
log.finest("paletteChanged for listener: " + current); |
|
} |
|
current.paletteChanged(); |
|
} 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 |
|
|
|
listeners.remove(current); |
|
} |
|
} |
|
} |
|
} |