0N/A/*
2362N/A * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.awt;
0N/A
0N/Aimport java.awt.IllegalComponentStateException;
0N/Aimport java.util.Collections;
0N/Aimport java.util.Iterator;
0N/Aimport java.util.Map;
0N/Aimport java.util.Set;
0N/Aimport java.util.HashMap;
0N/Aimport java.util.WeakHashMap;
0N/A
1696N/Aimport sun.util.logging.PlatformLogger;
0N/A
0N/A/**
0N/A * This class is used to aid in keeping track of DisplayChangedListeners and
0N/A * notifying them when a display change has taken place. DisplayChangedListeners
0N/A * are notified when the display's bit depth is changed, or when a top-level
0N/A * window has been dragged onto another screen.
0N/A *
0N/A * It is safe for a DisplayChangedListener to be added while the list is being
0N/A * iterated.
0N/A *
0N/A * The displayChanged() call is propagated after some occurrence (either
0N/A * due to user action or some other application) causes the display mode
0N/A * (e.g., depth or resolution) to change. All heavyweight components need
0N/A * to know when this happens because they need to create new surfaceData
0N/A * objects based on the new depth.
0N/A *
0N/A * displayChanged() is also called on Windows when they are moved from one
0N/A * screen to another on a system equipped with multiple displays.
0N/A */
0N/Apublic class SunDisplayChanger {
1696N/A private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.multiscreen.SunDisplayChanger");
0N/A
0N/A // Create a new synchronizedMap with initial capacity of one listener.
0N/A // It is asserted that the most common case is to have one GraphicsDevice
0N/A // and one top-level Window.
0N/A private Map listeners = Collections.synchronizedMap(new WeakHashMap(1));
0N/A
0N/A public SunDisplayChanger() {}
0N/A
0N/A /*
0N/A * Add a DisplayChangeListener to this SunDisplayChanger so that it is
0N/A * notified when the display is changed.
0N/A */
0N/A public void add(DisplayChangedListener theListener) {
1696N/A if (log.isLoggable(PlatformLogger.FINE)) {
0N/A if (theListener == null) {
1696N/A log.fine("Assertion (theListener != null) failed");
0N/A }
0N/A }
1696N/A if (log.isLoggable(PlatformLogger.FINER)) {
1696N/A log.finer("Adding listener: " + theListener);
0N/A }
0N/A listeners.put(theListener, null);
0N/A }
0N/A
0N/A /*
0N/A * Remove the given DisplayChangeListener from this SunDisplayChanger.
0N/A */
0N/A public void remove(DisplayChangedListener theListener) {
1696N/A if (log.isLoggable(PlatformLogger.FINE)) {
0N/A if (theListener == null) {
1696N/A log.fine("Assertion (theListener != null) failed");
0N/A }
0N/A }
1696N/A if (log.isLoggable(PlatformLogger.FINER)) {
1696N/A log.finer("Removing listener: " + theListener);
0N/A }
0N/A listeners.remove(theListener);
0N/A }
0N/A
0N/A /*
0N/A * Notify our list of DisplayChangedListeners that a display change has
0N/A * taken place by calling their displayChanged() methods.
0N/A */
0N/A public void notifyListeners() {
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) {
1696N/A log.finest("notifyListeners");
0N/A }
0N/A // This method is implemented by making a clone of the set of listeners,
0N/A // and then iterating over the clone. This is because during the course
0N/A // of responding to a display change, it may be appropriate for a
0N/A // DisplayChangedListener to add or remove itself from a SunDisplayChanger.
0N/A // If the set itself were iterated over, rather than a clone, it is
0N/A // trivial to get a ConcurrentModificationException by having a
0N/A // DisplayChangedListener remove itself from its list.
0N/A // Because all display change handling is done on the event thread,
0N/A // synchronization provides no protection against modifying the listener
0N/A // list while in the middle of iterating over it. -bchristi 7/10/2001
0N/A
0N/A HashMap listClone;
0N/A Set cloneSet;
0N/A
0N/A synchronized(listeners) {
0N/A listClone = new HashMap(listeners);
0N/A }
0N/A
0N/A cloneSet = listClone.keySet();
0N/A Iterator itr = cloneSet.iterator();
0N/A while (itr.hasNext()) {
0N/A DisplayChangedListener current =
0N/A (DisplayChangedListener) itr.next();
0N/A try {
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) {
1696N/A log.finest("displayChanged for listener: " + current);
0N/A }
0N/A current.displayChanged();
0N/A } catch (IllegalComponentStateException e) {
0N/A // This DisplayChangeListener is no longer valid. Most
0N/A // likely, a top-level window was dispose()d, but its
0N/A // Java objects have not yet been garbage collected. In any
0N/A // case, we no longer need to track this listener, though we
0N/A // do need to remove it from the original list, not the clone.
0N/A listeners.remove(current);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Notify our list of DisplayChangedListeners that a palette change has
0N/A * taken place by calling their paletteChanged() methods.
0N/A */
0N/A public void notifyPaletteChanged() {
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) {
0N/A log.finest("notifyPaletteChanged");
0N/A }
0N/A // This method is implemented by making a clone of the set of listeners,
0N/A // and then iterating over the clone. This is because during the course
0N/A // of responding to a display change, it may be appropriate for a
0N/A // DisplayChangedListener to add or remove itself from a SunDisplayChanger.
0N/A // If the set itself were iterated over, rather than a clone, it is
0N/A // trivial to get a ConcurrentModificationException by having a
0N/A // DisplayChangedListener remove itself from its list.
0N/A // Because all display change handling is done on the event thread,
0N/A // synchronization provides no protection against modifying the listener
0N/A // list while in the middle of iterating over it. -bchristi 7/10/2001
0N/A
0N/A HashMap listClone;
0N/A Set cloneSet;
0N/A
0N/A synchronized (listeners) {
0N/A listClone = new HashMap(listeners);
0N/A }
0N/A cloneSet = listClone.keySet();
0N/A Iterator itr = cloneSet.iterator();
0N/A while (itr.hasNext()) {
0N/A DisplayChangedListener current =
0N/A (DisplayChangedListener) itr.next();
0N/A try {
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) {
1696N/A log.finest("paletteChanged for listener: " + current);
0N/A }
0N/A current.paletteChanged();
0N/A } catch (IllegalComponentStateException e) {
0N/A // This DisplayChangeListener is no longer valid. Most
0N/A // likely, a top-level window was dispose()d, but its
0N/A // Java objects have not yet been garbage collected. In any
0N/A // case, we no longer need to track this listener, though we
0N/A // do need to remove it from the original list, not the clone.
0N/A listeners.remove(current);
0N/A }
0N/A }
0N/A }
0N/A}