0001: /*
0002: * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: */
0025: package java.awt;
0026:
0027: import java.applet.Applet;
0028: import java.awt.event.*;
0029: import java.awt.im.InputContext;
0030: import java.awt.image.BufferStrategy;
0031: import java.awt.peer.ComponentPeer;
0032: import java.awt.peer.WindowPeer;
0033: import java.beans.PropertyChangeListener;
0034: import java.io.IOException;
0035: import java.io.ObjectInputStream;
0036: import java.io.ObjectOutputStream;
0037: import java.io.OptionalDataException;
0038: import java.io.Serializable;
0039: import java.lang.ref.WeakReference;
0040: import java.lang.reflect.InvocationTargetException;
0041: import java.security.AccessController;
0042: import java.util.ArrayList;
0043: import java.util.Arrays;
0044: import java.util.EventListener;
0045: import java.util.Locale;
0046: import java.util.ResourceBundle;
0047: import java.util.Set;
0048: import java.util.Vector;
0049: import java.util.logging.Level;
0050: import java.util.logging.Logger;
0051: import java.util.concurrent.atomic.AtomicBoolean;
0052: import javax.accessibility.*;
0053: import sun.awt.AppContext;
0054: import sun.awt.CausedFocusEvent;
0055: import sun.awt.SunToolkit;
0056: import sun.awt.util.IdentityArrayList;
0057: import sun.security.action.GetPropertyAction;
0058: import sun.security.util.SecurityConstants;
0059:
0060: /**
0061: * A <code>Window</code> object is a top-level window with no borders and no
0062: * menubar.
0063: * The default layout for a window is <code>BorderLayout</code>.
0064: * <p>
0065: * A window must have either a frame, dialog, or another window defined as its
0066: * owner when it's constructed.
0067: * <p>
0068: * In a multi-screen environment, you can create a <code>Window</code>
0069: * on a different screen device by constructing the <code>Window</code>
0070: * with {@link #Window(Window, GraphicsConfiguration)}. The
0071: * <code>GraphicsConfiguration</code> object is one of the
0072: * <code>GraphicsConfiguration</code> objects of the target screen device.
0073: * <p>
0074: * In a virtual device multi-screen environment in which the desktop
0075: * area could span multiple physical screen devices, the bounds of all
0076: * configurations are relative to the virtual device coordinate system.
0077: * The origin of the virtual-coordinate system is at the upper left-hand
0078: * corner of the primary physical screen. Depending on the location of
0079: * the primary screen in the virtual device, negative coordinates are
0080: * possible, as shown in the following figure.
0081: * <p>
0082: * <img src="doc-files/MultiScreen.gif"
0083: * alt="Diagram shows virtual device containing 4 physical screens. Primary physical screen shows coords (0,0), other screen shows (-80,-100)."
0084: * ALIGN=center HSPACE=10 VSPACE=7>
0085: * <p>
0086: * In such an environment, when calling <code>setLocation</code>,
0087: * you must pass a virtual coordinate to this method. Similarly,
0088: * calling <code>getLocationOnScreen</code> on a <code>Window</code> returns
0089: * virtual device coordinates. Call the <code>getBounds</code> method
0090: * of a <code>GraphicsConfiguration</code> to find its origin in the virtual
0091: * coordinate system.
0092: * <p>
0093: * The following code sets the location of a <code>Window</code>
0094: * at (10, 10) relative to the origin of the physical screen
0095: * of the corresponding <code>GraphicsConfiguration</code>. If the
0096: * bounds of the <code>GraphicsConfiguration</code> is not taken
0097: * into account, the <code>Window</code> location would be set
0098: * at (10, 10) relative to the virtual-coordinate system and would appear
0099: * on the primary physical screen, which might be different from the
0100: * physical screen of the specified <code>GraphicsConfiguration</code>.
0101: *
0102: * <pre>
0103: * Window w = new Window(Window owner, GraphicsConfiguration gc);
0104: * Rectangle bounds = gc.getBounds();
0105: * w.setLocation(10 + bounds.x, 10 + bounds.y);
0106: * </pre>
0107: *
0108: * <p>
0109: * Note: the location and size of top-level windows (including
0110: * <code>Window</code>s, <code>Frame</code>s, and <code>Dialog</code>s)
0111: * are under the control of the desktop's window management system.
0112: * Calls to <code>setLocation</code>, <code>setSize</code>, and
0113: * <code>setBounds</code> are requests (not directives) which are
0114: * forwarded to the window management system. Every effort will be
0115: * made to honor such requests. However, in some cases the window
0116: * management system may ignore such requests, or modify the requested
0117: * geometry in order to place and size the <code>Window</code> in a way
0118: * that more closely matches the desktop settings.
0119: * <p>
0120: * Due to the asynchronous nature of native event handling, the results
0121: * returned by <code>getBounds</code>, <code>getLocation</code>,
0122: * <code>getLocationOnScreen</code>, and <code>getSize</code> might not
0123: * reflect the actual geometry of the Window on screen until the last
0124: * request has been processed. During the processing of subsequent
0125: * requests these values might change accordingly while the window
0126: * management system fulfills the requests.
0127: * <p>
0128: * An application may set the size and location of an invisible
0129: * {@code Window} arbitrarily, but the window management system may
0130: * subsequently change its size and/or location when the
0131: * {@code Window} is made visible. One or more {@code ComponentEvent}s
0132: * will be generated to indicate the new geometry.
0133: * <p>
0134: * Windows are capable of generating the following WindowEvents:
0135: * WindowOpened, WindowClosed, WindowGainedFocus, WindowLostFocus.
0136: *
0137: * @version @(#)Window.java 1.266 07/06/05
0138: * @author Sami Shaio
0139: * @author Arthur van Hoff
0140: * @see WindowEvent
0141: * @see #addWindowListener
0142: * @see java.awt.BorderLayout
0143: * @since JDK1.0
0144: */
0145: public class Window extends Container implements Accessible {
0146:
0147: /**
0148: * This represents the warning message that is
0149: * to be displayed in a non secure window. ie :
0150: * a window that has a security manager installed for
0151: * which calling SecurityManager.checkTopLevelWindow()
0152: * is false. This message can be displayed anywhere in
0153: * the window.
0154: *
0155: * @serial
0156: * @see #getWarningString
0157: */
0158: String warningString;
0159:
0160: /**
0161: * {@code icons} is the graphical way we can
0162: * represent the frames and dialogs.
0163: * {@code Window} can't display icon but it's
0164: * being inherited by owned {@code Dialog}s.
0165: *
0166: * @serial
0167: * @see #getIconImages
0168: * @see #setIconImages(List<? extends Image>)
0169: */
0170: transient java.util.List<Image> icons;
0171:
0172: /**
0173: * Holds the reference to the component which last had focus in this window
0174: * before it lost focus.
0175: */
0176: private transient Component temporaryLostComponent;
0177:
0178: static boolean systemSyncLWRequests = false;
0179: boolean syncLWRequests = false;
0180: transient boolean beforeFirstShow = true;
0181:
0182: static final int OPENED = 0x01;
0183:
0184: /**
0185: * An Integer value representing the Window State.
0186: *
0187: * @serial
0188: * @since 1.2
0189: * @see #show
0190: */
0191: int state;
0192:
0193: /**
0194: * A boolean value representing Window always-on-top state
0195: * @since 1.5
0196: * @serial
0197: * @see #setAlwaysOnTop
0198: * @see #isAlwaysOnTop
0199: */
0200: private boolean alwaysOnTop;
0201:
0202: /**
0203: * Contains all the windows that have a peer object associated,
0204: * i. e. between addNotify() and removeNotify() calls. The list
0205: * of all Window instances can be obtained from AppContext object.
0206: *
0207: * @since 1.6
0208: */
0209: private static final IdentityArrayList<Window> allWindows = new IdentityArrayList<Window>();
0210:
0211: /**
0212: * A vector containing all the windows this
0213: * window currently owns.
0214: * @since 1.2
0215: * @see #getOwnedWindows
0216: */
0217: transient Vector<WeakReference<Window>> ownedWindowList = new Vector<WeakReference<Window>>();
0218:
0219: /*
0220: * We insert a weak reference into the Vector of all Windows in AppContext
0221: * instead of 'this' so that garbage collection can still take place
0222: * correctly.
0223: */
0224: private transient WeakReference<Window> weakThis;
0225:
0226: transient boolean showWithParent;
0227:
0228: /**
0229: * Contains the modal dialog that blocks this window, or null
0230: * if the window is unblocked.
0231: *
0232: * @since 1.6
0233: */
0234: transient Dialog modalBlocker;
0235:
0236: /**
0237: * @serial
0238: *
0239: * @see java.awt.Dialog.ModalExclusionType
0240: * @see #getModalExclusionType
0241: * @see #setModalExclusionType
0242: *
0243: * @since 1.6
0244: */
0245: Dialog.ModalExclusionType modalExclusionType;
0246:
0247: transient WindowListener windowListener;
0248: transient WindowStateListener windowStateListener;
0249: transient WindowFocusListener windowFocusListener;
0250:
0251: transient InputContext inputContext;
0252: private transient Object inputContextLock = new Object();
0253:
0254: /**
0255: * Unused. Maintained for serialization backward-compatibility.
0256: *
0257: * @serial
0258: * @since 1.2
0259: */
0260: private FocusManager focusMgr;
0261:
0262: /**
0263: * Indicates whether this Window can become the focused Window.
0264: *
0265: * @serial
0266: * @see #getFocusableWindowState
0267: * @see #setFocusableWindowState
0268: * @since 1.4
0269: */
0270: private boolean focusableWindowState = true;
0271:
0272: /**
0273: * Indicates whether this window should receive focus on
0274: * subsequently being shown (with a call to {@code setVisible(true)}), or
0275: * being moved to the front (with a call to {@code toFront()}).
0276: *
0277: * @serial
0278: * @see #setAutoRequestFocus
0279: * @see #isAutoRequestFocus
0280: * @since 1.7
0281: */
0282: private volatile boolean autoRequestFocus = true;
0283:
0284: /*
0285: * Indicates that this window is being shown. This flag is set to true at
0286: * the beginning of show() and to false at the end of show().
0287: *
0288: * @see #show()
0289: * @see Dialog#shouldBlock
0290: */
0291: transient boolean isInShow = false;
0292:
0293: private static final String base = "win";
0294: private static int nameCounter = 0;
0295:
0296: /*
0297: * JDK 1.1 serialVersionUID
0298: */
0299: private static final long serialVersionUID = 4497834738069338734L;
0300:
0301: private static final Logger log = Logger
0302: .getLogger("java.awt.Window");
0303:
0304: private static final boolean locationByPlatformProp;
0305:
0306: transient boolean isTrayIconWindow = false;
0307:
0308: static {
0309: /* ensure that the necessary native libraries are loaded */
0310: Toolkit.loadLibraries();
0311: if (!GraphicsEnvironment.isHeadless()) {
0312: initIDs();
0313: }
0314:
0315: String s = (String) java.security.AccessController
0316: .doPrivileged(new GetPropertyAction(
0317: "java.awt.syncLWRequests"));
0318: systemSyncLWRequests = (s != null && s.equals("true"));
0319: s = (String) java.security.AccessController
0320: .doPrivileged(new GetPropertyAction(
0321: "java.awt.Window.locationByPlatform"));
0322: locationByPlatformProp = (s != null && s.equals("true"));
0323: }
0324:
0325: /**
0326: * Initialize JNI field and method IDs for fields that may be
0327: accessed from C.
0328: */
0329: private static native void initIDs();
0330:
0331: /**
0332: * Constructs a new, initially invisible window in default size with the
0333: * specified <code>GraphicsConfiguration</code>.
0334: * <p>
0335: * If there is a security manager, this method first calls
0336: * the security manager's <code>checkTopLevelWindow</code>
0337: * method with <code>this</code>
0338: * as its argument to determine whether or not the window
0339: * must be displayed with a warning banner.
0340: *
0341: * @param gc the <code>GraphicsConfiguration</code> of the target screen
0342: * device. If <code>gc</code> is <code>null</code>, the system default
0343: * <code>GraphicsConfiguration</code> is assumed
0344: * @exception IllegalArgumentException if <code>gc</code>
0345: * is not from a screen device
0346: * @exception HeadlessException when
0347: * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0348: *
0349: * @see java.awt.GraphicsEnvironment#isHeadless
0350: * @see java.lang.SecurityManager#checkTopLevelWindow
0351: */
0352: Window(GraphicsConfiguration gc) {
0353: init(gc);
0354: }
0355:
0356: transient Object anchor = new Object();
0357:
0358: static class WindowDisposerRecord implements
0359: sun.java2d.DisposerRecord {
0360: final WeakReference<Window> owner;
0361: final WeakReference weakThis;
0362: final AppContext context;
0363:
0364: WindowDisposerRecord(AppContext context, Window victim) {
0365: owner = new WeakReference<Window>(victim.getOwner());
0366: weakThis = victim.weakThis;
0367: this .context = context;
0368: }
0369:
0370: public void dispose() {
0371: Window parent = owner.get();
0372: if (parent != null) {
0373: parent.removeOwnedWindow(weakThis);
0374: }
0375: Window.removeFromWindowList(context, weakThis);
0376: }
0377: }
0378:
0379: private void init(GraphicsConfiguration gc) {
0380: GraphicsEnvironment.checkHeadless();
0381:
0382: syncLWRequests = systemSyncLWRequests;
0383:
0384: weakThis = new WeakReference<Window>(this );
0385: addToWindowList();
0386:
0387: setWarningString();
0388: this .cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
0389: this .visible = false;
0390: if (gc == null) {
0391: this .graphicsConfig = GraphicsEnvironment
0392: .getLocalGraphicsEnvironment()
0393: .getDefaultScreenDevice().getDefaultConfiguration();
0394: } else {
0395: this .graphicsConfig = gc;
0396: }
0397: if (graphicsConfig.getDevice().getType() != GraphicsDevice.TYPE_RASTER_SCREEN) {
0398: throw new IllegalArgumentException("not a screen device");
0399: }
0400: setLayout(new BorderLayout());
0401:
0402: /* offset the initial location with the original of the screen */
0403: /* and any insets */
0404: Rectangle screenBounds = graphicsConfig.getBounds();
0405: Insets screenInsets = getToolkit().getScreenInsets(
0406: graphicsConfig);
0407: int x = getX() + screenBounds.x + screenInsets.left;
0408: int y = getY() + screenBounds.y + screenInsets.top;
0409: if (x != this .x || y != this .y) {
0410: setLocation(x, y);
0411: /* reset after setLocation */
0412: setLocationByPlatform(locationByPlatformProp);
0413: }
0414:
0415: modalExclusionType = Dialog.ModalExclusionType.NO_EXCLUDE;
0416:
0417: sun.java2d.Disposer.addRecord(anchor, new WindowDisposerRecord(
0418: appContext, this ));
0419: }
0420:
0421: /**
0422: * Constructs a new, initially invisible window in the default size.
0423: *
0424: * <p>First, if there is a security manager, its
0425: * <code>checkTopLevelWindow</code>
0426: * method is called with <code>this</code>
0427: * as its argument
0428: * to see if it's ok to display the window without a warning banner.
0429: * If the default implementation of <code>checkTopLevelWindow</code>
0430: * is used (that is, that method is not overriden), then this results in
0431: * a call to the security manager's <code>checkPermission</code> method
0432: * with an <code>AWTPermission("showWindowWithoutWarningBanner")</code>
0433: * permission. It that method raises a SecurityException,
0434: * <code>checkTopLevelWindow</code> returns false, otherwise it
0435: * returns true. If it returns false, a warning banner is created.
0436: *
0437: * @exception HeadlessException when
0438: * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0439: *
0440: * @see java.awt.GraphicsEnvironment#isHeadless
0441: * @see java.lang.SecurityManager#checkTopLevelWindow
0442: */
0443: Window() throws HeadlessException {
0444: GraphicsEnvironment.checkHeadless();
0445: init((GraphicsConfiguration) null);
0446: }
0447:
0448: /**
0449: * Constructs a new, initially invisible window with the specified
0450: * <code>Frame</code> as its owner. The window will not be focusable
0451: * unless its owner is showing on the screen.
0452: * <p>
0453: * If there is a security manager, this method first calls
0454: * the security manager's <code>checkTopLevelWindow</code>
0455: * method with <code>this</code>
0456: * as its argument to determine whether or not the window
0457: * must be displayed with a warning banner.
0458: *
0459: * @param owner the <code>Frame</code> to act as owner or <code>null</code>
0460: * if this window has no owner
0461: * @exception IllegalArgumentException if the <code>owner</code>'s
0462: * <code>GraphicsConfiguration</code> is not from a screen device
0463: * @exception HeadlessException when
0464: * <code>GraphicsEnvironment.isHeadless</code> returns <code>true</code>
0465: *
0466: * @see java.awt.GraphicsEnvironment#isHeadless
0467: * @see java.lang.SecurityManager#checkTopLevelWindow
0468: * @see #isShowing
0469: */
0470: public Window(Frame owner) {
0471: this (owner == null ? (GraphicsConfiguration) null : owner
0472: .getGraphicsConfiguration());
0473: ownedInit(owner);
0474: }
0475:
0476: /**
0477: * Constructs a new, initially invisible window with the specified
0478: * <code>Window</code> as its owner. This window will not be focusable
0479: * unless its nearest owning <code>Frame</code> or <code>Dialog</code>
0480: * is showing on the screen.
0481: * <p>
0482: * If there is a security manager, this method first calls
0483: * the security manager's <code>checkTopLevelWindow</code>
0484: * method with <code>this</code>
0485: * as its argument to determine whether or not the window
0486: * must be displayed with a warning banner.
0487: *
0488: * @param owner the <code>Window</code> to act as owner or
0489: * <code>null</code> if this window has no owner
0490: * @exception IllegalArgumentException if the <code>owner</code>'s
0491: * <code>GraphicsConfiguration</code> is not from a screen device
0492: * @exception HeadlessException when
0493: * <code>GraphicsEnvironment.isHeadless()</code> returns
0494: * <code>true</code>
0495: *
0496: * @see java.awt.GraphicsEnvironment#isHeadless
0497: * @see java.lang.SecurityManager#checkTopLevelWindow
0498: * @see #isShowing
0499: *
0500: * @since 1.2
0501: */
0502: public Window(Window owner) {
0503: this (owner == null ? (GraphicsConfiguration) null : owner
0504: .getGraphicsConfiguration());
0505: ownedInit(owner);
0506: }
0507:
0508: /**
0509: * Constructs a new, initially invisible window with the specified owner
0510: * <code>Window</code> and a <code>GraphicsConfiguration</code>
0511: * of a screen device. The Window will not be focusable unless
0512: * its nearest owning <code>Frame</code> or <code>Dialog</code>
0513: * is showing on the screen.
0514: * <p>
0515: * If there is a security manager, this method first calls
0516: * the security manager's <code>checkTopLevelWindow</code>
0517: * method with <code>this</code>
0518: * as its argument to determine whether or not the window
0519: * must be displayed with a warning banner.
0520: *
0521: * @param owner the window to act as owner or <code>null</code>
0522: * if this window has no owner
0523: * @param gc the <code>GraphicsConfiguration</code> of the target
0524: * screen device; if <code>gc</code> is <code>null</code>,
0525: * the system default <code>GraphicsConfiguration</code> is assumed
0526: * @exception IllegalArgumentException if <code>gc</code>
0527: * is not from a screen device
0528: * @exception HeadlessException when
0529: * <code>GraphicsEnvironment.isHeadless()</code> returns
0530: * <code>true</code>
0531: *
0532: * @see java.awt.GraphicsEnvironment#isHeadless
0533: * @see java.lang.SecurityManager#checkTopLevelWindow
0534: * @see GraphicsConfiguration#getBounds
0535: * @see #isShowing
0536: * @since 1.3
0537: */
0538: public Window(Window owner, GraphicsConfiguration gc) {
0539: this (gc);
0540: ownedInit(owner);
0541: }
0542:
0543: private void ownedInit(Window owner) {
0544: this .parent = owner;
0545: if (owner != null) {
0546: owner.addOwnedWindow(weakThis);
0547: }
0548: }
0549:
0550: /**
0551: * Construct a name for this component. Called by getName() when the
0552: * name is null.
0553: */
0554: String constructComponentName() {
0555: synchronized (Window.class) {
0556: return base + nameCounter++;
0557: }
0558: }
0559:
0560: /**
0561: * Returns the sequence of images to be displayed as the icon for this window.
0562: * <p>
0563: * This method returns a copy of the internally stored list, so all operations
0564: * on the returned object will not affect the window's behavior.
0565: *
0566: * @return the copy of icon images' list for this window, or
0567: * empty list if this window doesn't have icon images.
0568: * @see #setIconImages
0569: * @see #setIconImage(Image)
0570: * @since 1.6
0571: */
0572: public java.util.List<Image> getIconImages() {
0573: java.util.List<Image> icons = this .icons;
0574: if (icons == null || icons.size() == 0) {
0575: return new ArrayList<Image>();
0576: }
0577: return new ArrayList<Image>(icons);
0578: }
0579:
0580: /**
0581: * Sets the sequence of images to be displayed as the icon
0582: * for this window. Subsequent calls to {@code getIconImages} will
0583: * always return a copy of the {@code icons} list.
0584: * <p>
0585: * Depending on the platform capabilities one or several images
0586: * of different dimensions will be used as the window's icon.
0587: * <p>
0588: * The {@code icons} list is scanned for the images of most
0589: * appropriate dimensions from the beginning. If the list contains
0590: * several images of the same size, the first will be used.
0591: * <p>
0592: * Ownerless windows with no icon specified use platfrom-default icon.
0593: * The icon of an owned window may be inherited from the owner
0594: * unless explicitly overridden.
0595: * Setting the icon to {@code null} or empty list restores
0596: * the default behavior.
0597: * <p>
0598: * Note : Native windowing systems may use different images of differing
0599: * dimensions to represent a window, depending on the context (e.g.
0600: * window decoration, window list, taskbar, etc.). They could also use
0601: * just a single image for all contexts or no image at all.
0602: *
0603: * @param icons the list of icon images to be displayed.
0604: * @see #getIconImages()
0605: * @see #setIconImage(Image)
0606: * @since 1.6
0607: */
0608: public synchronized void setIconImages(
0609: java.util.List<? extends Image> icons) {
0610: this .icons = (icons == null) ? new ArrayList<Image>()
0611: : new ArrayList<Image>(icons);
0612: WindowPeer peer = (WindowPeer) this .peer;
0613: if (peer != null) {
0614: peer.updateIconImages();
0615: }
0616: // Always send a property change event
0617: firePropertyChange("iconImage", null, null);
0618: }
0619:
0620: /**
0621: * Sets the image to be displayed as the icon for this window.
0622: * <p>
0623: * This method can be used instead of {@link #setIconImages setIconImages()}
0624: * to specify a single image as a window's icon.
0625: * <p>
0626: * The following statement:
0627: * <pre>
0628: * setIconImage(image);
0629: * </pre>
0630: * is equivalent to:
0631: * <pre>
0632: * ArrayList<Image> imageList = new ArrayList<Image>();
0633: * imageList.add(image);
0634: * setIconImages(imageList);
0635: * </pre>
0636: * <p>
0637: * Note : Native windowing systems may use different images of differing
0638: * dimensions to represent a window, depending on the context (e.g.
0639: * window decoration, window list, taskbar, etc.). They could also use
0640: * just a single image for all contexts or no image at all.
0641: *
0642: * @param image the icon image to be displayed.
0643: * @see #setIconImages
0644: * @see #getIconImages()
0645: * @since 1.6
0646: */
0647: public void setIconImage(Image image) {
0648: ArrayList<Image> imageList = new ArrayList<Image>();
0649: if (image != null) {
0650: imageList.add(image);
0651: }
0652: setIconImages(imageList);
0653: }
0654:
0655: /**
0656: * Makes this Window displayable by creating the connection to its
0657: * native screen resource.
0658: * This method is called internally by the toolkit and should
0659: * not be called directly by programs.
0660: * @see Component#isDisplayable
0661: * @see Container#removeNotify
0662: * @since JDK1.0
0663: */
0664: public void addNotify() {
0665: synchronized (getTreeLock()) {
0666: Container parent = this .parent;
0667: if (parent != null && parent.getPeer() == null) {
0668: parent.addNotify();
0669: }
0670: if (peer == null) {
0671: peer = getToolkit().createWindow(this );
0672: }
0673: synchronized (allWindows) {
0674: allWindows.add(this );
0675: }
0676: super .addNotify();
0677: }
0678: }
0679:
0680: /**
0681: * {@inheritDoc}
0682: */
0683: public void removeNotify() {
0684: synchronized (getTreeLock()) {
0685: synchronized (allWindows) {
0686: allWindows.remove(this );
0687: }
0688: super .removeNotify();
0689: }
0690: }
0691:
0692: /**
0693: * Causes this Window to be sized to fit the preferred size
0694: * and layouts of its subcomponents. The resulting width and
0695: * height of the window are automatically enlarged if either
0696: * of dimensions is less than the minimum size as specified
0697: * by the previous call to the {@code setMinimumSize} method.
0698: * <p>
0699: * If the window and/or its owner are not displayable yet,
0700: * both of them are made displayable before calculating
0701: * the preferred size. The Window is validated after its
0702: * size is being calculated.
0703: *
0704: * @see Component#isDisplayable
0705: * @see #setMinimumSize
0706: */
0707: public void pack() {
0708: Container parent = this .parent;
0709: if (parent != null && parent.getPeer() == null) {
0710: parent.addNotify();
0711: }
0712: if (peer == null) {
0713: addNotify();
0714: }
0715: Dimension newSize = getPreferredSize();
0716: if (peer != null) {
0717: setClientSize(newSize.width, newSize.height);
0718: }
0719:
0720: if (beforeFirstShow) {
0721: isPacked = true;
0722: }
0723:
0724: validate();
0725: }
0726:
0727: /**
0728: * Sets the minimum size of this window to a constant
0729: * value. Subsequent calls to {@code getMinimumSize}
0730: * will always return this value. If current window's
0731: * size is less than {@code minimumSize} the size of the
0732: * window is automatically enlarged to honor the minimum size.
0733: * <p>
0734: * If the {@code setSize} or {@code setBounds} methods
0735: * are called afterwards with a width or height less than
0736: * that was specified by the {@code setMinimumSize} method
0737: * the window is automatically enlarged to meet
0738: * the {@code minimumSize} value. The {@code minimumSize}
0739: * value also affects the behaviour of the {@code pack} method.
0740: * <p>
0741: * The default behavior is restored by setting the minimum size
0742: * parameter to the {@code null} value.
0743: * <p>
0744: * Resizing operation may be restricted if the user tries
0745: * to resize window below the {@code minimumSize} value.
0746: * This behaviour is platform-dependent.
0747: *
0748: * @param minimumSize the new minimum size of this window
0749: * @see Component#setMinimumSize
0750: * @see #getMinimumSize
0751: * @see #isMinimumSizeSet
0752: * @see #setSize(Dimension)
0753: * @see #pack
0754: * @since 1.6
0755: */
0756: public void setMinimumSize(Dimension minimumSize) {
0757: synchronized (getTreeLock()) {
0758: super .setMinimumSize(minimumSize);
0759: Dimension size = getSize();
0760: if (isMinimumSizeSet()) {
0761: if (size.width < minimumSize.width
0762: || size.height < minimumSize.height) {
0763: int nw = Math.max(width, minimumSize.width);
0764: int nh = Math.max(height, minimumSize.height);
0765: setSize(nw, nh);
0766: }
0767: }
0768: if (peer != null) {
0769: ((WindowPeer) peer).updateMinimumSize();
0770: }
0771: }
0772: }
0773:
0774: /**
0775: * {@inheritDoc}
0776: * <p>
0777: * The {@code d.width} and {@code d.height} values
0778: * are automatically enlarged if either is less than
0779: * the minimum size as specified by previous call to
0780: * {@code setMinimumSize}.
0781: *
0782: * @see #getSize
0783: * @see #setBounds
0784: * @see #setMinimumSize
0785: * @since 1.6
0786: */
0787: public void setSize(Dimension d) {
0788: super .setSize(d);
0789: }
0790:
0791: /**
0792: * {@inheritDoc}
0793: * <p>
0794: * The {@code width} and {@code height} values
0795: * are automatically enlarged if either is less than
0796: * the minimum size as specified by previous call to
0797: * {@code setMinimumSize}.
0798: *
0799: * @see #getSize
0800: * @see #setBounds
0801: * @see #setMinimumSize
0802: * @since 1.6
0803: */
0804: public void setSize(int width, int height) {
0805: super .setSize(width, height);
0806: }
0807:
0808: /**
0809: * @deprecated As of JDK version 1.1,
0810: * replaced by <code>setBounds(int, int, int, int)</code>.
0811: */
0812: @Deprecated
0813: public void reshape(int x, int y, int width, int height) {
0814: if (isMinimumSizeSet()) {
0815: Dimension minSize = getMinimumSize();
0816: if (width < minSize.width) {
0817: width = minSize.width;
0818: }
0819: if (height < minSize.height) {
0820: height = minSize.height;
0821: }
0822: }
0823: super .reshape(x, y, width, height);
0824: }
0825:
0826: void setClientSize(int w, int h) {
0827: synchronized (getTreeLock()) {
0828: setBoundsOp(ComponentPeer.SET_CLIENT_SIZE);
0829: setBounds(x, y, w, h);
0830: }
0831: }
0832:
0833: static private final AtomicBoolean beforeFirstWindowShown = new AtomicBoolean(
0834: true);
0835:
0836: static final void closeSplashScreen() {
0837: if (beforeFirstWindowShown.getAndSet(false)) {
0838: SunToolkit.closeSplashScreen();
0839: }
0840: }
0841:
0842: /**
0843: * Shows or hides this {@code Window} depending on the value of parameter
0844: * {@code b}.
0845: * <p>
0846: * If the method shows the window then the window is also made
0847: * focused under the following conditions:
0848: * <ul>
0849: * <li> The {@code Window} meets the requirements outlined in the
0850: * {@link #isFocusableWindow} method.
0851: * <li> The {@code Window}'s {@code autoRequestFocus} property is of the {@code true} value.
0852: * <li> Native windowing system allows the {@code Window} to get focused.
0853: * </ul>
0854: * There is an exception for the second condition (the value of the
0855: * {@code autoRequestFocus} property). The property is not taken into account if the
0856: * window is a modal dialog, which blocks the currently focused window.
0857: * <p>
0858: * Developers must never assume that the window is the focused or active window
0859: * until it receives a WINDOW_GAINED_FOCUS or WINDOW_ACTIVATED event.
0860: * @param b if {@code true}, makes the {@code Window} visible,
0861: * otherwise hides the {@code Window}.
0862: * If the {@code Window} and/or its owner
0863: * are not yet displayable, both are made displayable. The
0864: * {@code Window} will be validated prior to being made visible.
0865: * If the {@code Window} is already visible, this will bring the
0866: * {@code Window} to the front.<p>
0867: * If {@code false}, hides this {@code Window}, its subcomponents, and all
0868: * of its owned children.
0869: * The {@code Window} and its subcomponents can be made visible again
0870: * with a call to {@code #setVisible(true)}.
0871: * @see java.awt.Component#isDisplayable
0872: * @see java.awt.Component#setVisible
0873: * @see java.awt.Window#toFront
0874: * @see java.awt.Window#dispose
0875: * @see java.awt.Window#setAutoRequestFocus
0876: * @see java.awt.Window#isFocusableWindow
0877: */
0878: public void setVisible(boolean b) {
0879: super .setVisible(b);
0880: }
0881:
0882: /**
0883: * Makes the Window visible. If the Window and/or its owner
0884: * are not yet displayable, both are made displayable. The
0885: * Window will be validated prior to being made visible.
0886: * If the Window is already visible, this will bring the Window
0887: * to the front.
0888: * @see Component#isDisplayable
0889: * @see #toFront
0890: * @deprecated As of JDK version 1.5, replaced by
0891: * {@link #setVisible(boolean)}.
0892: */
0893: @Deprecated
0894: public void show() {
0895: if (peer == null) {
0896: addNotify();
0897: }
0898: validate();
0899:
0900: isInShow = true;
0901: if (visible) {
0902: toFront();
0903: } else {
0904: beforeFirstShow = false;
0905: closeSplashScreen();
0906: Dialog.checkShouldBeBlocked(this );
0907: super .show();
0908: locationByPlatform = false;
0909: for (int i = 0; i < ownedWindowList.size(); i++) {
0910: Window child = ownedWindowList.elementAt(i).get();
0911: if ((child != null) && child.showWithParent) {
0912: child.show();
0913: child.showWithParent = false;
0914: } // endif
0915: } // endfor
0916: if (!isModalBlocked()) {
0917: updateChildrenBlocking();
0918: } else {
0919: // fix for 6532736: after this window is shown, its blocker
0920: // should be raised to front
0921: modalBlocker.toFront_NoClientCode();
0922: }
0923: if (this instanceof Frame || this instanceof Dialog) {
0924: updateChildFocusableWindowState(this );
0925: }
0926: }
0927: isInShow = false;
0928:
0929: // If first time shown, generate WindowOpened event
0930: if ((state & OPENED) == 0) {
0931: postWindowEvent(WindowEvent.WINDOW_OPENED);
0932: state |= OPENED;
0933: }
0934: }
0935:
0936: static void updateChildFocusableWindowState(Window w) {
0937: if (w.getPeer() != null && w.isShowing()) {
0938: ((WindowPeer) w.getPeer()).updateFocusableWindowState();
0939: }
0940: for (int i = 0; i < w.ownedWindowList.size(); i++) {
0941: Window child = w.ownedWindowList.elementAt(i).get();
0942: if (child != null) {
0943: updateChildFocusableWindowState(child);
0944: }
0945: }
0946: }
0947:
0948: synchronized void postWindowEvent(int id) {
0949: if (windowListener != null
0950: || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0
0951: || Toolkit.enabledOnToolkit(AWTEvent.WINDOW_EVENT_MASK)) {
0952: WindowEvent e = new WindowEvent(this , id);
0953: Toolkit.getEventQueue().postEvent(e);
0954: }
0955: }
0956:
0957: /**
0958: * Hide this Window, its subcomponents, and all of its owned children.
0959: * The Window and its subcomponents can be made visible again
0960: * with a call to {@code show}.
0961: * </p>
0962: * @see #show
0963: * @see #dispose
0964: * @deprecated As of JDK version 1.5, replaced by
0965: * {@link #setVisible(boolean)}.
0966: */
0967: @Deprecated
0968: public void hide() {
0969: synchronized (ownedWindowList) {
0970: for (int i = 0; i < ownedWindowList.size(); i++) {
0971: Window child = ownedWindowList.elementAt(i).get();
0972: if ((child != null) && child.visible) {
0973: child.hide();
0974: child.showWithParent = true;
0975: }
0976: }
0977: }
0978: if (isModalBlocked()) {
0979: modalBlocker.unblockWindow(this );
0980: }
0981: super .hide();
0982: }
0983:
0984: final void clearMostRecentFocusOwnerOnHide() {
0985: /* do nothing */
0986: }
0987:
0988: /**
0989: * Releases all of the native screen resources used by this
0990: * <code>Window</code>, its subcomponents, and all of its owned
0991: * children. That is, the resources for these <code>Component</code>s
0992: * will be destroyed, any memory they consume will be returned to the
0993: * OS, and they will be marked as undisplayable.
0994: * <p>
0995: * The <code>Window</code> and its subcomponents can be made displayable
0996: * again by rebuilding the native resources with a subsequent call to
0997: * <code>pack</code> or <code>show</code>. The states of the recreated
0998: * <code>Window</code> and its subcomponents will be identical to the
0999: * states of these objects at the point where the <code>Window</code>
1000: * was disposed (not accounting for additional modifications between
1001: * those actions).
1002: * <p>
1003: * <b>Note</b>: When the last displayable window
1004: * within the Java virtual machine (VM) is disposed of, the VM may
1005: * terminate. See <a href="doc-files/AWTThreadIssues.html#Autoshutdown">
1006: * AWT Threading Issues</a> for more information.
1007: * @see Component#isDisplayable
1008: * @see #pack
1009: * @see #show
1010: */
1011: public void dispose() {
1012: doDispose();
1013: }
1014:
1015: /*
1016: * Fix for 4872170.
1017: * If dispose() is called on parent then its children have to be disposed as well
1018: * as reported in javadoc. So we need to implement this functionality even if a
1019: * child overrides dispose() in a wrong way without calling super.dispose().
1020: */
1021: void disposeImpl() {
1022: dispose();
1023: if (getPeer() != null) {
1024: doDispose();
1025: }
1026: }
1027:
1028: void doDispose() {
1029: class DisposeAction implements Runnable {
1030: public void run() {
1031: // Check if this window is the fullscreen window for the
1032: // device. Exit the fullscreen mode prior to disposing
1033: // of the window if that's the case.
1034: GraphicsDevice gd = getGraphicsConfiguration()
1035: .getDevice();
1036: if (gd.getFullScreenWindow() == Window.this ) {
1037: gd.setFullScreenWindow(null);
1038: }
1039:
1040: Object[] ownedWindowArray;
1041: synchronized (ownedWindowList) {
1042: ownedWindowArray = new Object[ownedWindowList
1043: .size()];
1044: ownedWindowList.copyInto(ownedWindowArray);
1045: }
1046: for (int i = 0; i < ownedWindowArray.length; i++) {
1047: Window child = (Window) (((WeakReference) (ownedWindowArray[i]))
1048: .get());
1049: if (child != null) {
1050: child.disposeImpl();
1051: }
1052: }
1053: hide();
1054: beforeFirstShow = true;
1055: removeNotify();
1056: synchronized (inputContextLock) {
1057: if (inputContext != null) {
1058: inputContext.dispose();
1059: inputContext = null;
1060: }
1061: }
1062: clearCurrentFocusCycleRootOnHide();
1063: }
1064: }
1065: DisposeAction action = new DisposeAction();
1066: if (EventQueue.isDispatchThread()) {
1067: action.run();
1068: } else {
1069: try {
1070: EventQueue.invokeAndWait(action);
1071: } catch (InterruptedException e) {
1072: System.err.println("Disposal was interrupted:");
1073: e.printStackTrace();
1074: } catch (InvocationTargetException e) {
1075: System.err.println("Exception during disposal:");
1076: e.printStackTrace();
1077: }
1078: }
1079: // Execute outside the Runnable because postWindowEvent is
1080: // synchronized on (this). We don't need to synchronize the call
1081: // on the EventQueue anyways.
1082: postWindowEvent(WindowEvent.WINDOW_CLOSED);
1083: }
1084:
1085: /*
1086: * Should only be called while holding the tree lock.
1087: * It's overridden here because parent == owner in Window,
1088: * and we shouldn't adjust counter on owner
1089: */
1090: void adjustListeningChildrenOnParent(long mask, int num) {
1091: }
1092:
1093: // Should only be called while holding tree lock
1094: void adjustDecendantsOnParent(int num) {
1095: // do nothing since parent == owner and we shouldn't
1096: // ajust counter on owner
1097: }
1098:
1099: /**
1100: * If this Window is visible, brings this Window to the front and may make
1101: * it the focused Window.
1102: * <p>
1103: * Places this Window at the top of the stacking order and shows it in
1104: * front of any other Windows in this VM. No action will take place if this
1105: * Window is not visible. Some platforms do not allow Windows which own
1106: * other Windows to appear on top of those owned Windows. Some platforms
1107: * may not permit this VM to place its Windows above windows of native
1108: * applications, or Windows of other VMs. This permission may depend on
1109: * whether a Window in this VM is already focused. Every attempt will be
1110: * made to move this Window as high as possible in the stacking order;
1111: * however, developers should not assume that this method will move this
1112: * Window above all other windows in every situation.
1113: * <p>
1114: * Developers must never assume that this Window is the focused or active
1115: * Window until this Window receives a WINDOW_GAINED_FOCUS or WINDOW_ACTIVATED
1116: * event. On platforms where the top-most window is the focused window, this
1117: * method will <b>probably</b> focus this Window (if it is not already focused)
1118: * under the following conditions:
1119: * <ul>
1120: * <li> The window meets the requirements outlined in the
1121: * {@link #isFocusableWindow} method.
1122: * <li> The window's property {@code autoRequestFocus} is of the
1123: * {@code true} value.
1124: * <li> Native windowing system allows the window to get focused.
1125: * </ul>
1126: * On platforms where the stacking order does not typically affect the focused
1127: * window, this method will <b>probably</b> leave the focused and active
1128: * Windows unchanged.
1129: * <p>
1130: * If this method causes this Window to be focused, and this Window is a
1131: * Frame or a Dialog, it will also become activated. If this Window is
1132: * focused, but it is not a Frame or a Dialog, then the first Frame or
1133: * Dialog that is an owner of this Window will be activated.
1134: * <p>
1135: * If this window is blocked by modal dialog, then the blocking dialog
1136: * is brought to the front and remains above the blocked window.
1137: *
1138: * @see #toBack
1139: * @see #setAutoRequestFocus
1140: * @see #isFocusableWindow
1141: */
1142: public void toFront() {
1143: toFront_NoClientCode();
1144: }
1145:
1146: // This functionality is implemented in a final package-private method
1147: // to insure that it cannot be overridden by client subclasses.
1148: final void toFront_NoClientCode() {
1149: if (visible) {
1150: WindowPeer peer = (WindowPeer) this .peer;
1151: if (peer != null) {
1152: peer.toFront();
1153: }
1154: if (isModalBlocked()) {
1155: modalBlocker.toFront_NoClientCode();
1156: }
1157: }
1158: }
1159:
1160: /**
1161: * If this Window is visible, sends this Window to the back and may cause
1162: * it to lose focus or activation if it is the focused or active Window.
1163: * <p>
1164: * Places this Window at the bottom of the stacking order and shows it
1165: * behind any other Windows in this VM. No action will take place is this
1166: * Window is not visible. Some platforms do not allow Windows which are
1167: * owned by other Windows to appear below their owners. Every attempt will
1168: * be made to move this Window as low as possible in the stacking order;
1169: * however, developers should not assume that this method will move this
1170: * Window below all other windows in every situation.
1171: * <p>
1172: * Because of variations in native windowing systems, no guarantees about
1173: * changes to the focused and active Windows can be made. Developers must
1174: * never assume that this Window is no longer the focused or active Window
1175: * until this Window receives a WINDOW_LOST_FOCUS or WINDOW_DEACTIVATED
1176: * event. On platforms where the top-most window is the focused window,
1177: * this method will <b>probably</b> cause this Window to lose focus. In
1178: * that case, the next highest, focusable Window in this VM will receive
1179: * focus. On platforms where the stacking order does not typically affect
1180: * the focused window, this method will <b>probably</b> leave the focused
1181: * and active Windows unchanged.
1182: *
1183: * @see #toFront
1184: */
1185: public void toBack() {
1186: toBack_NoClientCode();
1187: }
1188:
1189: // This functionality is implemented in a final package-private method
1190: // to insure that it cannot be overridden by client subclasses.
1191: final void toBack_NoClientCode() {
1192: if (isAlwaysOnTop()) {
1193: try {
1194: setAlwaysOnTop(false);
1195: } catch (SecurityException e) {
1196: }
1197: }
1198: if (visible) {
1199: WindowPeer peer = (WindowPeer) this .peer;
1200: if (peer != null) {
1201: peer.toBack();
1202: }
1203: }
1204: }
1205:
1206: /**
1207: * Returns the toolkit of this frame.
1208: * @return the toolkit of this window.
1209: * @see Toolkit
1210: * @see Toolkit#getDefaultToolkit
1211: * @see Component#getToolkit
1212: */
1213: public Toolkit getToolkit() {
1214: return Toolkit.getDefaultToolkit();
1215: }
1216:
1217: /**
1218: * Gets the warning string that is displayed with this window.
1219: * If this window is insecure, the warning string is displayed
1220: * somewhere in the visible area of the window. A window is
1221: * insecure if there is a security manager, and the security
1222: * manager's <code>checkTopLevelWindow</code> method returns
1223: * <code>false</code> when this window is passed to it as an
1224: * argument.
1225: * <p>
1226: * If the window is secure, then <code>getWarningString</code>
1227: * returns <code>null</code>. If the window is insecure, this
1228: * method checks for the system property
1229: * <code>awt.appletWarning</code>
1230: * and returns the string value of that property.
1231: * @return the warning string for this window.
1232: * @see java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object)
1233: */
1234: public final String getWarningString() {
1235: return warningString;
1236: }
1237:
1238: private void setWarningString() {
1239: warningString = null;
1240: SecurityManager sm = System.getSecurityManager();
1241: if (sm != null) {
1242: if (!sm.checkTopLevelWindow(this )) {
1243: // make sure the privileged action is only
1244: // for getting the property! We don't want the
1245: // above checkTopLevelWindow call to always succeed!
1246: warningString = (String) AccessController
1247: .doPrivileged(new GetPropertyAction(
1248: "awt.appletWarning",
1249: "Java Applet Window"));
1250: }
1251: }
1252: }
1253:
1254: /**
1255: * Gets the <code>Locale</code> object that is associated
1256: * with this window, if the locale has been set.
1257: * If no locale has been set, then the default locale
1258: * is returned.
1259: * @return the locale that is set for this window.
1260: * @see java.util.Locale
1261: * @since JDK1.1
1262: */
1263: public Locale getLocale() {
1264: if (this .locale == null) {
1265: return Locale.getDefault();
1266: }
1267: return this .locale;
1268: }
1269:
1270: /**
1271: * Gets the input context for this window. A window always has an input context,
1272: * which is shared by subcomponents unless they create and set their own.
1273: * @see Component#getInputContext
1274: * @since 1.2
1275: */
1276: public InputContext getInputContext() {
1277: synchronized (inputContextLock) {
1278: if (inputContext == null) {
1279: inputContext = InputContext.getInstance();
1280: }
1281: }
1282: return inputContext;
1283: }
1284:
1285: /**
1286: * Set the cursor image to a specified cursor.
1287: * <p>
1288: * The method may have no visual effect if the Java platform
1289: * implementation and/or the native system do not support
1290: * changing the mouse cursor shape.
1291: * @param cursor One of the constants defined
1292: * by the <code>Cursor</code> class. If this parameter is null
1293: * then the cursor for this window will be set to the type
1294: * Cursor.DEFAULT_CURSOR.
1295: * @see Component#getCursor
1296: * @see Cursor
1297: * @since JDK1.1
1298: */
1299: public void setCursor(Cursor cursor) {
1300: if (cursor == null) {
1301: cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
1302: }
1303: super .setCursor(cursor);
1304: }
1305:
1306: /**
1307: * Returns the owner of this window.
1308: * @since 1.2
1309: */
1310: public Window getOwner() {
1311: return getOwner_NoClientCode();
1312: }
1313:
1314: final Window getOwner_NoClientCode() {
1315: return (Window) parent;
1316: }
1317:
1318: /**
1319: * Return an array containing all the windows this
1320: * window currently owns.
1321: * @since 1.2
1322: */
1323: public Window[] getOwnedWindows() {
1324: return getOwnedWindows_NoClientCode();
1325: }
1326:
1327: final Window[] getOwnedWindows_NoClientCode() {
1328: Window realCopy[];
1329:
1330: synchronized (ownedWindowList) {
1331: // Recall that ownedWindowList is actually a Vector of
1332: // WeakReferences and calling get() on one of these references
1333: // may return null. Make two arrays-- one the size of the
1334: // Vector (fullCopy with size fullSize), and one the size of
1335: // all non-null get()s (realCopy with size realSize).
1336: int fullSize = ownedWindowList.size();
1337: int realSize = 0;
1338: Window fullCopy[] = new Window[fullSize];
1339:
1340: for (int i = 0; i < fullSize; i++) {
1341: fullCopy[realSize] = ownedWindowList.elementAt(i).get();
1342:
1343: if (fullCopy[realSize] != null) {
1344: realSize++;
1345: }
1346: }
1347:
1348: if (fullSize != realSize) {
1349: realCopy = Arrays.copyOf(fullCopy, realSize);
1350: } else {
1351: realCopy = fullCopy;
1352: }
1353: }
1354:
1355: return realCopy;
1356: }
1357:
1358: boolean isModalBlocked() {
1359: return modalBlocker != null;
1360: }
1361:
1362: void setModalBlocked(Dialog blocker, boolean blocked,
1363: boolean peerCall) {
1364: this .modalBlocker = blocked ? blocker : null;
1365: if (peerCall) {
1366: WindowPeer peer = (WindowPeer) this .peer;
1367: if (peer != null) {
1368: peer.setModalBlocked(blocker, blocked);
1369: }
1370: }
1371: }
1372:
1373: Dialog getModalBlocker() {
1374: return modalBlocker;
1375: }
1376:
1377: /*
1378: * Returns a list of all displayable Windows, i. e. all the
1379: * Windows which peer is not null.
1380: *
1381: * @see #addNotify
1382: * @see #removeNotify
1383: */
1384: static IdentityArrayList<Window> getAllWindows() {
1385: synchronized (allWindows) {
1386: IdentityArrayList<Window> v = new IdentityArrayList<Window>();
1387: v.addAll(allWindows);
1388: return v;
1389: }
1390: }
1391:
1392: static IdentityArrayList<Window> getAllUnblockedWindows() {
1393: synchronized (allWindows) {
1394: IdentityArrayList<Window> unblocked = new IdentityArrayList<Window>();
1395: for (int i = 0; i < allWindows.size(); i++) {
1396: Window w = allWindows.get(i);
1397: if (!w.isModalBlocked()) {
1398: unblocked.add(w);
1399: }
1400: }
1401: return unblocked;
1402: }
1403: }
1404:
1405: private static Window[] getWindows(AppContext appContext) {
1406: synchronized (Window.class) {
1407: Window realCopy[];
1408: Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>) appContext
1409: .get(Window.class);
1410: if (windowList != null) {
1411: int fullSize = windowList.size();
1412: int realSize = 0;
1413: Window fullCopy[] = new Window[fullSize];
1414: for (int i = 0; i < fullSize; i++) {
1415: Window w = windowList.get(i).get();
1416: if (w != null) {
1417: fullCopy[realSize++] = w;
1418: }
1419: }
1420: if (fullSize != realSize) {
1421: realCopy = Arrays.copyOf(fullCopy, realSize);
1422: } else {
1423: realCopy = fullCopy;
1424: }
1425: } else {
1426: realCopy = new Window[0];
1427: }
1428: return realCopy;
1429: }
1430: }
1431:
1432: /**
1433: * Returns an array of all {@code Window}s, both owned and ownerless,
1434: * created by this application.
1435: * If called from an applet, the array includes only the {@code Window}s
1436: * accessible by that applet.
1437: * <p>
1438: * <b>Warning:</b> this method may return system created windows, such
1439: * as a print dialog. Applications should not assume the existence of
1440: * these dialogs, nor should an application assume anything about these
1441: * dialogs such as component positions, <code>LayoutManager</code>s
1442: * or serialization.
1443: *
1444: * @see Frame#getFrames
1445: * @see Window#getOwnerlessWindows
1446: *
1447: * @since 1.6
1448: */
1449: public static Window[] getWindows() {
1450: return getWindows(AppContext.getAppContext());
1451: }
1452:
1453: /**
1454: * Returns an array of all {@code Window}s created by this application
1455: * that have no owner. They include {@code Frame}s and ownerless
1456: * {@code Dialog}s and {@code Window}s.
1457: * If called from an applet, the array includes only the {@code Window}s
1458: * accessible by that applet.
1459: * <p>
1460: * <b>Warning:</b> this method may return system created windows, such
1461: * as a print dialog. Applications should not assume the existence of
1462: * these dialogs, nor should an application assume anything about these
1463: * dialogs such as component positions, <code>LayoutManager</code>s
1464: * or serialization.
1465: *
1466: * @see Frame#getFrames
1467: * @see Window#getWindows()
1468: *
1469: * @since 1.6
1470: */
1471: public static Window[] getOwnerlessWindows() {
1472: Window[] allWindows = Window.getWindows();
1473:
1474: int ownerlessCount = 0;
1475: for (Window w : allWindows) {
1476: if (w.getOwner() == null) {
1477: ownerlessCount++;
1478: }
1479: }
1480:
1481: Window[] ownerless = new Window[ownerlessCount];
1482: int c = 0;
1483: for (Window w : allWindows) {
1484: if (w.getOwner() == null) {
1485: ownerless[c++] = w;
1486: }
1487: }
1488:
1489: return ownerless;
1490: }
1491:
1492: Window getDocumentRoot() {
1493: synchronized (getTreeLock()) {
1494: Window w = this ;
1495: while (w.getOwner() != null) {
1496: w = w.getOwner();
1497: }
1498: return w;
1499: }
1500: }
1501:
1502: /**
1503: * Specifies the modal exclusion type for this window. If a window is modal
1504: * excluded, it is not blocked by some modal dialogs. See {@link
1505: * java.awt.Dialog.ModalExclusionType Dialog.ModalExclusionType} for
1506: * possible modal exclusion types.
1507: * <p>
1508: * If the given type is not supported, <code>NO_EXCLUDE</code> is used.
1509: * <p>
1510: * Note: changing the modal exclusion type for a visible window may have no
1511: * effect until it is hidden and then shown again.
1512: *
1513: * @param exclusionType the modal exclusion type for this window; a <code>null</code>
1514: * value is equivivalent to {@link Dialog.ModalExclusionType#NO_EXCLUDE
1515: * NO_EXCLUDE}
1516: * @throws SecurityException if the calling thread does not have permission
1517: * to set the modal exclusion property to the window with the given
1518: * <code>exclusionType</code>
1519: * @see java.awt.Dialog.ModalExclusionType
1520: * @see java.awt.Window#getModalExclusionType
1521: * @see java.awt.Toolkit#isModalExclusionTypeSupported
1522: *
1523: * @since 1.6
1524: */
1525: public void setModalExclusionType(
1526: Dialog.ModalExclusionType exclusionType) {
1527: if (exclusionType == null) {
1528: exclusionType = Dialog.ModalExclusionType.NO_EXCLUDE;
1529: }
1530: if (!Toolkit.getDefaultToolkit().isModalExclusionTypeSupported(
1531: exclusionType)) {
1532: exclusionType = Dialog.ModalExclusionType.NO_EXCLUDE;
1533: }
1534: if (modalExclusionType == exclusionType) {
1535: return;
1536: }
1537: if (exclusionType == Dialog.ModalExclusionType.TOOLKIT_EXCLUDE) {
1538: SecurityManager sm = System.getSecurityManager();
1539: if (sm != null) {
1540: sm
1541: .checkPermission(SecurityConstants.TOOLKIT_MODALITY_PERMISSION);
1542: }
1543: }
1544: modalExclusionType = exclusionType;
1545:
1546: // if we want on-fly changes, we need to uncomment the lines below
1547: // and override the method in Dialog to use modalShow() instead
1548: // of updateChildrenBlocking()
1549: /*
1550: if (isModalBlocked()) {
1551: modalBlocker.unblockWindow(this);
1552: }
1553: Dialog.checkShouldBeBlocked(this);
1554: updateChildrenBlocking();
1555: */
1556: }
1557:
1558: /**
1559: * Returns the modal exclusion type of this window.
1560: *
1561: * @return the modal exclusion type of this window
1562: *
1563: * @see java.awt.Dialog.ModalExclusionType
1564: * @see java.awt.Window#setModalExclusionType
1565: *
1566: * @since 1.6
1567: */
1568: public Dialog.ModalExclusionType getModalExclusionType() {
1569: return modalExclusionType;
1570: }
1571:
1572: boolean isModalExcluded(Dialog.ModalExclusionType exclusionType) {
1573: if ((modalExclusionType != null)
1574: && modalExclusionType.compareTo(exclusionType) >= 0) {
1575: return true;
1576: }
1577: Window owner = getOwner_NoClientCode();
1578: return (owner != null) && owner.isModalExcluded(exclusionType);
1579: }
1580:
1581: void updateChildrenBlocking() {
1582: Vector<Window> childHierarchy = new Vector<Window>();
1583: Window[] ownedWindows = getOwnedWindows();
1584: for (int i = 0; i < ownedWindows.length; i++) {
1585: childHierarchy.add(ownedWindows[i]);
1586: }
1587: int k = 0;
1588: while (k < childHierarchy.size()) {
1589: Window w = childHierarchy.get(k);
1590: if (w.isVisible()) {
1591: if (w.isModalBlocked()) {
1592: Dialog blocker = w.getModalBlocker();
1593: blocker.unblockWindow(w);
1594: }
1595: Dialog.checkShouldBeBlocked(w);
1596: Window[] wOwned = w.getOwnedWindows();
1597: for (int j = 0; j < wOwned.length; j++) {
1598: childHierarchy.add(wOwned[j]);
1599: }
1600: }
1601: k++;
1602: }
1603: }
1604:
1605: /**
1606: * Adds the specified window listener to receive window events from
1607: * this window.
1608: * If l is null, no exception is thrown and no action is performed.
1609: * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1610: * >AWT Threading Issues</a> for details on AWT's threading model.
1611: *
1612: * @param l the window listener
1613: * @see #removeWindowListener
1614: * @see #getWindowListeners
1615: */
1616: public synchronized void addWindowListener(WindowListener l) {
1617: if (l == null) {
1618: return;
1619: }
1620: newEventsOnly = true;
1621: windowListener = AWTEventMulticaster.add(windowListener, l);
1622: }
1623:
1624: /**
1625: * Adds the specified window state listener to receive window
1626: * events from this window. If <code>l</code> is <code>null</code>,
1627: * no exception is thrown and no action is performed.
1628: * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1629: * >AWT Threading Issues</a> for details on AWT's threading model.
1630: *
1631: * @param l the window state listener
1632: * @see #removeWindowStateListener
1633: * @see #getWindowStateListeners
1634: * @since 1.4
1635: */
1636: public synchronized void addWindowStateListener(
1637: WindowStateListener l) {
1638: if (l == null) {
1639: return;
1640: }
1641: windowStateListener = AWTEventMulticaster.add(
1642: windowStateListener, l);
1643: newEventsOnly = true;
1644: }
1645:
1646: /**
1647: * Adds the specified window focus listener to receive window events
1648: * from this window.
1649: * If l is null, no exception is thrown and no action is performed.
1650: * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1651: * >AWT Threading Issues</a> for details on AWT's threading model.
1652: *
1653: * @param l the window focus listener
1654: * @see #removeWindowFocusListener
1655: * @see #getWindowFocusListeners
1656: * @since 1.4
1657: */
1658: public synchronized void addWindowFocusListener(
1659: WindowFocusListener l) {
1660: if (l == null) {
1661: return;
1662: }
1663: windowFocusListener = AWTEventMulticaster.add(
1664: windowFocusListener, l);
1665: newEventsOnly = true;
1666: }
1667:
1668: /**
1669: * Removes the specified window listener so that it no longer
1670: * receives window events from this window.
1671: * If l is null, no exception is thrown and no action is performed.
1672: * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1673: * >AWT Threading Issues</a> for details on AWT's threading model.
1674: *
1675: * @param l the window listener
1676: * @see #addWindowListener
1677: * @see #getWindowListeners
1678: */
1679: public synchronized void removeWindowListener(WindowListener l) {
1680: if (l == null) {
1681: return;
1682: }
1683: windowListener = AWTEventMulticaster.remove(windowListener, l);
1684: }
1685:
1686: /**
1687: * Removes the specified window state listener so that it no
1688: * longer receives window events from this window. If
1689: * <code>l</code> is <code>null</code>, no exception is thrown and
1690: * no action is performed.
1691: * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1692: * >AWT Threading Issues</a> for details on AWT's threading model.
1693: *
1694: * @param l the window state listener
1695: * @see #addWindowStateListener
1696: * @see #getWindowStateListeners
1697: * @since 1.4
1698: */
1699: public synchronized void removeWindowStateListener(
1700: WindowStateListener l) {
1701: if (l == null) {
1702: return;
1703: }
1704: windowStateListener = AWTEventMulticaster.remove(
1705: windowStateListener, l);
1706: }
1707:
1708: /**
1709: * Removes the specified window focus listener so that it no longer
1710: * receives window events from this window.
1711: * If l is null, no exception is thrown and no action is performed.
1712: * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1713: * >AWT Threading Issues</a> for details on AWT's threading model.
1714: *
1715: * @param l the window focus listener
1716: * @see #addWindowFocusListener
1717: * @see #getWindowFocusListeners
1718: * @since 1.4
1719: */
1720: public synchronized void removeWindowFocusListener(
1721: WindowFocusListener l) {
1722: if (l == null) {
1723: return;
1724: }
1725: windowFocusListener = AWTEventMulticaster.remove(
1726: windowFocusListener, l);
1727: }
1728:
1729: /**
1730: * Returns an array of all the window listeners
1731: * registered on this window.
1732: *
1733: * @return all of this window's <code>WindowListener</code>s
1734: * or an empty array if no window
1735: * listeners are currently registered
1736: *
1737: * @see #addWindowListener
1738: * @see #removeWindowListener
1739: * @since 1.4
1740: */
1741: public synchronized WindowListener[] getWindowListeners() {
1742: return (WindowListener[]) (getListeners(WindowListener.class));
1743: }
1744:
1745: /**
1746: * Returns an array of all the window focus listeners
1747: * registered on this window.
1748: *
1749: * @return all of this window's <code>WindowFocusListener</code>s
1750: * or an empty array if no window focus
1751: * listeners are currently registered
1752: *
1753: * @see #addWindowFocusListener
1754: * @see #removeWindowFocusListener
1755: * @since 1.4
1756: */
1757: public synchronized WindowFocusListener[] getWindowFocusListeners() {
1758: return (WindowFocusListener[]) (getListeners(WindowFocusListener.class));
1759: }
1760:
1761: /**
1762: * Returns an array of all the window state listeners
1763: * registered on this window.
1764: *
1765: * @return all of this window's <code>WindowStateListener</code>s
1766: * or an empty array if no window state
1767: * listeners are currently registered
1768: *
1769: * @see #addWindowStateListener
1770: * @see #removeWindowStateListener
1771: * @since 1.4
1772: */
1773: public synchronized WindowStateListener[] getWindowStateListeners() {
1774: return (WindowStateListener[]) (getListeners(WindowStateListener.class));
1775: }
1776:
1777: /**
1778: * Returns an array of all the objects currently registered
1779: * as <code><em>Foo</em>Listener</code>s
1780: * upon this <code>Window</code>.
1781: * <code><em>Foo</em>Listener</code>s are registered using the
1782: * <code>add<em>Foo</em>Listener</code> method.
1783: *
1784: * <p>
1785: *
1786: * You can specify the <code>listenerType</code> argument
1787: * with a class literal, such as
1788: * <code><em>Foo</em>Listener.class</code>.
1789: * For example, you can query a
1790: * <code>Window</code> <code>w</code>
1791: * for its window listeners with the following code:
1792: *
1793: * <pre>WindowListener[] wls = (WindowListener[])(w.getListeners(WindowListener.class));</pre>
1794: *
1795: * If no such listeners exist, this method returns an empty array.
1796: *
1797: * @param listenerType the type of listeners requested; this parameter
1798: * should specify an interface that descends from
1799: * <code>java.util.EventListener</code>
1800: * @return an array of all objects registered as
1801: * <code><em>Foo</em>Listener</code>s on this window,
1802: * or an empty array if no such
1803: * listeners have been added
1804: * @exception ClassCastException if <code>listenerType</code>
1805: * doesn't specify a class or interface that implements
1806: * <code>java.util.EventListener</code>
1807: *
1808: * @see #getWindowListeners
1809: * @since 1.3
1810: */
1811: public <T extends EventListener> T[] getListeners(
1812: Class<T> listenerType) {
1813: EventListener l = null;
1814: if (listenerType == WindowFocusListener.class) {
1815: l = windowFocusListener;
1816: } else if (listenerType == WindowStateListener.class) {
1817: l = windowStateListener;
1818: } else if (listenerType == WindowListener.class) {
1819: l = windowListener;
1820: } else {
1821: return super .getListeners(listenerType);
1822: }
1823: return AWTEventMulticaster.getListeners(l, listenerType);
1824: }
1825:
1826: // REMIND: remove when filtering is handled at lower level
1827: boolean eventEnabled(AWTEvent e) {
1828: switch (e.id) {
1829: case WindowEvent.WINDOW_OPENED:
1830: case WindowEvent.WINDOW_CLOSING:
1831: case WindowEvent.WINDOW_CLOSED:
1832: case WindowEvent.WINDOW_ICONIFIED:
1833: case WindowEvent.WINDOW_DEICONIFIED:
1834: case WindowEvent.WINDOW_ACTIVATED:
1835: case WindowEvent.WINDOW_DEACTIVATED:
1836: if ((eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0
1837: || windowListener != null) {
1838: return true;
1839: }
1840: return false;
1841: case WindowEvent.WINDOW_GAINED_FOCUS:
1842: case WindowEvent.WINDOW_LOST_FOCUS:
1843: if ((eventMask & AWTEvent.WINDOW_FOCUS_EVENT_MASK) != 0
1844: || windowFocusListener != null) {
1845: return true;
1846: }
1847: return false;
1848: case WindowEvent.WINDOW_STATE_CHANGED:
1849: if ((eventMask & AWTEvent.WINDOW_STATE_EVENT_MASK) != 0
1850: || windowStateListener != null) {
1851: return true;
1852: }
1853: return false;
1854: default:
1855: break;
1856: }
1857: return super .eventEnabled(e);
1858: }
1859:
1860: /**
1861: * Processes events on this window. If the event is an
1862: * <code>WindowEvent</code>, it invokes the
1863: * <code>processWindowEvent</code> method, else it invokes its
1864: * superclass's <code>processEvent</code>.
1865: * <p>Note that if the event parameter is <code>null</code>
1866: * the behavior is unspecified and may result in an
1867: * exception.
1868: *
1869: * @param e the event
1870: */
1871: protected void processEvent(AWTEvent e) {
1872: if (e instanceof WindowEvent) {
1873: switch (e.getID()) {
1874: case WindowEvent.WINDOW_OPENED:
1875: case WindowEvent.WINDOW_CLOSING:
1876: case WindowEvent.WINDOW_CLOSED:
1877: case WindowEvent.WINDOW_ICONIFIED:
1878: case WindowEvent.WINDOW_DEICONIFIED:
1879: case WindowEvent.WINDOW_ACTIVATED:
1880: case WindowEvent.WINDOW_DEACTIVATED:
1881: processWindowEvent((WindowEvent) e);
1882: break;
1883: case WindowEvent.WINDOW_GAINED_FOCUS:
1884: case WindowEvent.WINDOW_LOST_FOCUS:
1885: processWindowFocusEvent((WindowEvent) e);
1886: break;
1887: case WindowEvent.WINDOW_STATE_CHANGED:
1888: processWindowStateEvent((WindowEvent) e);
1889: default:
1890: break;
1891: }
1892: return;
1893: }
1894: super .processEvent(e);
1895: }
1896:
1897: /**
1898: * Processes window events occurring on this window by
1899: * dispatching them to any registered WindowListener objects.
1900: * NOTE: This method will not be called unless window events
1901: * are enabled for this component; this happens when one of the
1902: * following occurs:
1903: * <ul>
1904: * <li>A WindowListener object is registered via
1905: * <code>addWindowListener</code>
1906: * <li>Window events are enabled via <code>enableEvents</code>
1907: * </ul>
1908: * <p>Note that if the event parameter is <code>null</code>
1909: * the behavior is unspecified and may result in an
1910: * exception.
1911: *
1912: * @param e the window event
1913: * @see Component#enableEvents
1914: */
1915: protected void processWindowEvent(WindowEvent e) {
1916: WindowListener listener = windowListener;
1917: if (listener != null) {
1918: switch (e.getID()) {
1919: case WindowEvent.WINDOW_OPENED:
1920: listener.windowOpened(e);
1921: break;
1922: case WindowEvent.WINDOW_CLOSING:
1923: listener.windowClosing(e);
1924: break;
1925: case WindowEvent.WINDOW_CLOSED:
1926: listener.windowClosed(e);
1927: break;
1928: case WindowEvent.WINDOW_ICONIFIED:
1929: listener.windowIconified(e);
1930: break;
1931: case WindowEvent.WINDOW_DEICONIFIED:
1932: listener.windowDeiconified(e);
1933: break;
1934: case WindowEvent.WINDOW_ACTIVATED:
1935: listener.windowActivated(e);
1936: break;
1937: case WindowEvent.WINDOW_DEACTIVATED:
1938: listener.windowDeactivated(e);
1939: break;
1940: default:
1941: break;
1942: }
1943: }
1944: }
1945:
1946: /**
1947: * Processes window focus event occuring on this window by
1948: * dispatching them to any registered WindowFocusListener objects.
1949: * NOTE: this method will not be called unless window focus events
1950: * are enabled for this window. This happens when one of the
1951: * following occurs:
1952: * <ul>
1953: * <li>a WindowFocusListener is registered via
1954: * <code>addWindowFocusListener</code>
1955: * <li>Window focus events are enabled via <code>enableEvents</code>
1956: * </ul>
1957: * <p>Note that if the event parameter is <code>null</code>
1958: * the behavior is unspecified and may result in an
1959: * exception.
1960: *
1961: * @param e the window focus event
1962: * @see Component#enableEvents
1963: * @since 1.4
1964: */
1965: protected void processWindowFocusEvent(WindowEvent e) {
1966: WindowFocusListener listener = windowFocusListener;
1967: if (listener != null) {
1968: switch (e.getID()) {
1969: case WindowEvent.WINDOW_GAINED_FOCUS:
1970: listener.windowGainedFocus(e);
1971: break;
1972: case WindowEvent.WINDOW_LOST_FOCUS:
1973: listener.windowLostFocus(e);
1974: break;
1975: default:
1976: break;
1977: }
1978: }
1979: }
1980:
1981: /**
1982: * Processes window state event occuring on this window by
1983: * dispatching them to any registered <code>WindowStateListener</code>
1984: * objects.
1985: * NOTE: this method will not be called unless window state events
1986: * are enabled for this window. This happens when one of the
1987: * following occurs:
1988: * <ul>
1989: * <li>a <code>WindowStateListener</code> is registered via
1990: * <code>addWindowStateListener</code>
1991: * <li>window state events are enabled via <code>enableEvents</code>
1992: * </ul>
1993: * <p>Note that if the event parameter is <code>null</code>
1994: * the behavior is unspecified and may result in an
1995: * exception.
1996: *
1997: * @param e the window state event
1998: * @see java.awt.Component#enableEvents
1999: * @since 1.4
2000: */
2001: protected void processWindowStateEvent(WindowEvent e) {
2002: WindowStateListener listener = windowStateListener;
2003: if (listener != null) {
2004: switch (e.getID()) {
2005: case WindowEvent.WINDOW_STATE_CHANGED:
2006: listener.windowStateChanged(e);
2007: break;
2008: default:
2009: break;
2010: }
2011: }
2012: }
2013:
2014: /**
2015: * Implements a debugging hook -- checks to see if
2016: * the user has typed <i>control-shift-F1</i>. If so,
2017: * the list of child windows is dumped to <code>System.out</code>.
2018: * @param e the keyboard event
2019: */
2020: void preProcessKeyEvent(KeyEvent e) {
2021: // Dump the list of child windows to System.out.
2022: if (e.isActionKey() && e.getKeyCode() == KeyEvent.VK_F1
2023: && e.isControlDown() && e.isShiftDown()
2024: && e.getID() == KeyEvent.KEY_PRESSED) {
2025: list(System.out, 0);
2026: }
2027: }
2028:
2029: void postProcessKeyEvent(KeyEvent e) {
2030: // Do nothing
2031: }
2032:
2033: /**
2034: * Sets whether this window should always be above other windows. If
2035: * there are multiple always-on-top windows, their relative order is
2036: * unspecified and platform dependent.
2037: * <p>
2038: * If some other window is already always-on-top then the
2039: * relative order between these windows is unspecified (depends on
2040: * platform). No window can be brought to be over the always-on-top
2041: * window except maybe another always-on-top window.
2042: * <p>
2043: * All windows owned by an always-on-top window inherit this state and
2044: * automatically become always-on-top. If a window ceases to be
2045: * always-on-top, the windows that it owns will no longer be
2046: * always-on-top. When an always-on-top window is sent {@link #toBack
2047: * toBack}, its always-on-top state is set to <code>false</code>.
2048: *
2049: * <p> When this method is called on a window with a value of
2050: * <code>true</code>, and the window is visible and the platform
2051: * supports always-on-top for this window, the window is immediately
2052: * brought forward, "sticking" it in the top-most position. If the
2053: * window isn`t currently visible, this method sets the always-on-top
2054: * state to <code>true</code> but does not bring the window forward.
2055: * When the window is later shown, it will be always-on-top.
2056: *
2057: * <p> When this method is called on a window with a value of
2058: * <code>false</code> the always-on-top state is set to normal. The
2059: * window remains in the top-most position but it`s z-order can be
2060: * changed as for any other window. Calling this method with a value
2061: * of <code>false</code> on a window that has a normal state has no
2062: * effect. Setting the always-on-top state to false has no effect on
2063: * the relative z-order of the windows if there are no other
2064: * always-on-top windows.
2065: *
2066: * <p><b>Note</b>: some platforms might not support always-on-top
2067: * windows. To detect if always-on-top windows are supported by the
2068: * current platform, use {@link Toolkit#isAlwaysOnTopSupported()} and
2069: * {@link Window#isAlwaysOnTopSupported()}. If always-on-top mode
2070: * isn't supported by the toolkit or for this window, calling this
2071: * method has no effect.
2072: * <p>
2073: * If a SecurityManager is installed, the calling thread must be
2074: * granted the AWTPermission "setWindowAlwaysOnTop" in
2075: * order to set the value of this property. If this
2076: * permission is not granted, this method will throw a
2077: * SecurityException, and the current value of the property will
2078: * be left unchanged.
2079: *
2080: * @param alwaysOnTop true if the window should always be above other
2081: * windows
2082: * @throws SecurityException if the calling thread does not have
2083: * permission to set the value of always-on-top property
2084: * @see #isAlwaysOnTop
2085: * @see #toFront
2086: * @see #toBack
2087: * @see AWTPermission
2088: * @see #isAlwaysOnTopSupported
2089: * @see Toolkit#isAlwaysOnTopSupported
2090: * @since 1.5
2091: */
2092: public final void setAlwaysOnTop(boolean alwaysOnTop)
2093: throws SecurityException {
2094: SecurityManager security = System.getSecurityManager();
2095: if (security != null) {
2096: security
2097: .checkPermission(SecurityConstants.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION);
2098: }
2099:
2100: boolean oldAlwaysOnTop;
2101: synchronized (this ) {
2102: oldAlwaysOnTop = this .alwaysOnTop;
2103: this .alwaysOnTop = alwaysOnTop;
2104: }
2105: if (oldAlwaysOnTop != alwaysOnTop) {
2106: if (isAlwaysOnTopSupported()) {
2107: WindowPeer peer = (WindowPeer) this .peer;
2108: synchronized (getTreeLock()) {
2109: if (peer != null) {
2110: peer.setAlwaysOnTop(alwaysOnTop);
2111: }
2112: }
2113: }
2114: firePropertyChange("alwaysOnTop", oldAlwaysOnTop,
2115: alwaysOnTop);
2116: }
2117: }
2118:
2119: /**
2120: * Returns whether the always-on-top mode is supported for this
2121: * window. Some platforms may not support always-on-top windows, some
2122: * may support only some kinds of top-level windows; for example,
2123: * a platform may not support always-on-top modal dialogs.
2124: * @return <code>true</code>, if the always-on-top mode is
2125: * supported by the toolkit and for this window,
2126: * <code>false</code>, if always-on-top mode is not supported
2127: * for this window or toolkit doesn't support always-on-top windows.
2128: * @see #setAlwaysOnTop(boolean)
2129: * @see Toolkit#isAlwaysOnTopSupported
2130: * @since 1.6
2131: */
2132: public boolean isAlwaysOnTopSupported() {
2133: return Toolkit.getDefaultToolkit().isAlwaysOnTopSupported();
2134: }
2135:
2136: /**
2137: * Returns whether this window is an always-on-top window.
2138: * @return <code>true</code>, if the window is in always-on-top state,
2139: * <code>false</code> otherwise
2140: * @see #setAlwaysOnTop
2141: * @since 1.5
2142: */
2143: public final boolean isAlwaysOnTop() {
2144: return alwaysOnTop;
2145: }
2146:
2147: /**
2148: * Returns the child Component of this Window that has focus if this Window
2149: * is focused; returns null otherwise.
2150: *
2151: * @return the child Component with focus, or null if this Window is not
2152: * focused
2153: * @see #getMostRecentFocusOwner
2154: * @see #isFocused
2155: */
2156: public Component getFocusOwner() {
2157: return (isFocused()) ? KeyboardFocusManager
2158: .getCurrentKeyboardFocusManager().getFocusOwner()
2159: : null;
2160: }
2161:
2162: /**
2163: * Returns the child Component of this Window that will receive the focus
2164: * when this Window is focused. If this Window is currently focused, this
2165: * method returns the same Component as <code>getFocusOwner()</code>. If
2166: * this Window is not focused, then the child Component that most recently
2167: * requested focus will be returned. If no child Component has ever
2168: * requested focus, and this is a focusable Window, then this Window's
2169: * initial focusable Component is returned. If no child Component has ever
2170: * requested focus, and this is a non-focusable Window, null is returned.
2171: *
2172: * @return the child Component that will receive focus when this Window is
2173: * focused
2174: * @see #getFocusOwner
2175: * @see #isFocused
2176: * @see #isFocusableWindow
2177: * @since 1.4
2178: */
2179: public Component getMostRecentFocusOwner() {
2180: if (isFocused()) {
2181: return getFocusOwner();
2182: } else {
2183: Component mostRecent = KeyboardFocusManager
2184: .getMostRecentFocusOwner(this );
2185: if (mostRecent != null) {
2186: return mostRecent;
2187: } else {
2188: return (isFocusableWindow()) ? getFocusTraversalPolicy()
2189: .getInitialComponent(this )
2190: : null;
2191: }
2192: }
2193: }
2194:
2195: /**
2196: * Returns whether this Window is active. Only a Frame or a Dialog may be
2197: * active. The native windowing system may denote the active Window or its
2198: * children with special decorations, such as a highlighted title bar. The
2199: * active Window is always either the focused Window, or the first Frame or
2200: * Dialog that is an owner of the focused Window.
2201: *
2202: * @return whether this is the active Window.
2203: * @see #isFocused
2204: * @since 1.4
2205: */
2206: public boolean isActive() {
2207: return (KeyboardFocusManager.getCurrentKeyboardFocusManager()
2208: .getActiveWindow() == this );
2209: }
2210:
2211: /**
2212: * Returns whether this Window is focused. If there exists a focus owner,
2213: * the focused Window is the Window that is, or contains, that focus owner.
2214: * If there is no focus owner, then no Window is focused.
2215: * <p>
2216: * If the focused Window is a Frame or a Dialog it is also the active
2217: * Window. Otherwise, the active Window is the first Frame or Dialog that
2218: * is an owner of the focused Window.
2219: *
2220: * @return whether this is the focused Window.
2221: * @see #isActive
2222: * @since 1.4
2223: */
2224: public boolean isFocused() {
2225: return (KeyboardFocusManager.getCurrentKeyboardFocusManager()
2226: .getGlobalFocusedWindow() == this );
2227: }
2228:
2229: /**
2230: * Gets a focus traversal key for this Window. (See <code>
2231: * setFocusTraversalKeys</code> for a full description of each key.)
2232: * <p>
2233: * If the traversal key has not been explicitly set for this Window,
2234: * then this Window's parent's traversal key is returned. If the
2235: * traversal key has not been explicitly set for any of this Window's
2236: * ancestors, then the current KeyboardFocusManager's default traversal key
2237: * is returned.
2238: *
2239: * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2240: * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
2241: * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
2242: * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
2243: * @return the AWTKeyStroke for the specified key
2244: * @see Container#setFocusTraversalKeys
2245: * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
2246: * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
2247: * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
2248: * @see KeyboardFocusManager#DOWN_CYCLE_TRAVERSAL_KEYS
2249: * @throws IllegalArgumentException if id is not one of
2250: * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2251: * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
2252: * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
2253: * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
2254: * @since 1.4
2255: */
2256: public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
2257: if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
2258: throw new IllegalArgumentException(
2259: "invalid focus traversal key identifier");
2260: }
2261:
2262: // Okay to return Set directly because it is an unmodifiable view
2263: Set keystrokes = (focusTraversalKeys != null) ? focusTraversalKeys[id]
2264: : null;
2265:
2266: if (keystrokes != null) {
2267: return keystrokes;
2268: } else {
2269: return KeyboardFocusManager
2270: .getCurrentKeyboardFocusManager()
2271: .getDefaultFocusTraversalKeys(id);
2272: }
2273: }
2274:
2275: /**
2276: * Does nothing because Windows must always be roots of a focus traversal
2277: * cycle. The passed-in value is ignored.
2278: *
2279: * @param focusCycleRoot this value is ignored
2280: * @see #isFocusCycleRoot
2281: * @see Container#setFocusTraversalPolicy
2282: * @see Container#getFocusTraversalPolicy
2283: * @since 1.4
2284: */
2285: public final void setFocusCycleRoot(boolean focusCycleRoot) {
2286: }
2287:
2288: /**
2289: * Always returns <code>true</code> because all Windows must be roots of a
2290: * focus traversal cycle.
2291: *
2292: * @return <code>true</code>
2293: * @see #setFocusCycleRoot
2294: * @see Container#setFocusTraversalPolicy
2295: * @see Container#getFocusTraversalPolicy
2296: * @since 1.4
2297: */
2298: public final boolean isFocusCycleRoot() {
2299: return true;
2300: }
2301:
2302: /**
2303: * Always returns <code>null</code> because Windows have no ancestors; they
2304: * represent the top of the Component hierarchy.
2305: *
2306: * @return <code>null</code>
2307: * @see Container#isFocusCycleRoot()
2308: * @since 1.4
2309: */
2310: public final Container getFocusCycleRootAncestor() {
2311: return null;
2312: }
2313:
2314: /**
2315: * Returns whether this Window can become the focused Window, that is,
2316: * whether this Window or any of its subcomponents can become the focus
2317: * owner. For a Frame or Dialog to be focusable, its focusable Window state
2318: * must be set to <code>true</code>. For a Window which is not a Frame or
2319: * Dialog to be focusable, its focusable Window state must be set to
2320: * <code>true</code>, its nearest owning Frame or Dialog must be
2321: * showing on the screen, and it must contain at least one Component in
2322: * its focus traversal cycle. If any of these conditions is not met, then
2323: * neither this Window nor any of its subcomponents can become the focus
2324: * owner.
2325: *
2326: * @return <code>true</code> if this Window can be the focused Window;
2327: * <code>false</code> otherwise
2328: * @see #getFocusableWindowState
2329: * @see #setFocusableWindowState
2330: * @see #isShowing
2331: * @see Component#isFocusable
2332: * @since 1.4
2333: */
2334: public final boolean isFocusableWindow() {
2335: // If a Window/Frame/Dialog was made non-focusable, then it is always
2336: // non-focusable.
2337: if (!getFocusableWindowState()) {
2338: return false;
2339: }
2340:
2341: // All other tests apply only to Windows.
2342: if (this instanceof Frame || this instanceof Dialog) {
2343: return true;
2344: }
2345:
2346: // A Window must have at least one Component in its root focus
2347: // traversal cycle to be focusable.
2348: if (getFocusTraversalPolicy().getDefaultComponent(this ) == null) {
2349: return false;
2350: }
2351:
2352: // A Window's nearest owning Frame or Dialog must be showing on the
2353: // screen.
2354: for (Window owner = getOwner(); owner != null; owner = owner
2355: .getOwner()) {
2356: if (owner instanceof Frame || owner instanceof Dialog) {
2357: return owner.isShowing();
2358: }
2359: }
2360:
2361: return false;
2362: }
2363:
2364: /**
2365: * Returns whether this Window can become the focused Window if it meets
2366: * the other requirements outlined in <code>isFocusableWindow</code>. If
2367: * this method returns <code>false</code>, then
2368: * <code>isFocusableWindow</code> will return <code>false</code> as well.
2369: * If this method returns <code>true</code>, then
2370: * <code>isFocusableWindow</code> may return <code>true</code> or
2371: * <code>false</code> depending upon the other requirements which must be
2372: * met in order for a Window to be focusable.
2373: * <p>
2374: * By default, all Windows have a focusable Window state of
2375: * <code>true</code>.
2376: *
2377: * @return whether this Window can be the focused Window
2378: * @see #isFocusableWindow
2379: * @see #setFocusableWindowState
2380: * @see #isShowing
2381: * @see Component#setFocusable
2382: * @since 1.4
2383: */
2384: public boolean getFocusableWindowState() {
2385: return focusableWindowState;
2386: }
2387:
2388: /**
2389: * Sets whether this Window can become the focused Window if it meets
2390: * the other requirements outlined in <code>isFocusableWindow</code>. If
2391: * this Window's focusable Window state is set to <code>false</code>, then
2392: * <code>isFocusableWindow</code> will return <code>false</code>. If this
2393: * Window's focusable Window state is set to <code>true</code>, then
2394: * <code>isFocusableWindow</code> may return <code>true</code> or
2395: * <code>false</code> depending upon the other requirements which must be
2396: * met in order for a Window to be focusable.
2397: * <p>
2398: * Setting a Window's focusability state to <code>false</code> is the
2399: * standard mechanism for an application to identify to the AWT a Window
2400: * which will be used as a floating palette or toolbar, and thus should be
2401: * a non-focusable Window.
2402: *
2403: * Setting the focusability state on a visible <code>Window</code>
2404: * can have a delayed effect on some platforms — the actual
2405: * change may happen only when the <code>Window</code> becomes
2406: * hidden and then visible again. To ensure consistent behavior
2407: * across platforms, set the <code>Window</code>'s focusable state
2408: * when the <code>Window</code> is invisible and then show it.
2409: *
2410: * @param focusableWindowState whether this Window can be the focused
2411: * Window
2412: * @see #isFocusableWindow
2413: * @see #getFocusableWindowState
2414: * @see #isShowing
2415: * @see Component#setFocusable
2416: * @since 1.4
2417: */
2418: public void setFocusableWindowState(boolean focusableWindowState) {
2419: boolean oldFocusableWindowState;
2420: synchronized (this ) {
2421: oldFocusableWindowState = this .focusableWindowState;
2422: this .focusableWindowState = focusableWindowState;
2423: }
2424: WindowPeer peer = (WindowPeer) this .peer;
2425: if (peer != null) {
2426: peer.updateFocusableWindowState();
2427: }
2428: firePropertyChange("focusableWindowState",
2429: oldFocusableWindowState, focusableWindowState);
2430: if (oldFocusableWindowState && !focusableWindowState
2431: && isFocused()) {
2432: for (Window owner = getOwner(); owner != null; owner = owner
2433: .getOwner()) {
2434: Component toFocus = KeyboardFocusManager
2435: .getMostRecentFocusOwner(owner);
2436: if (toFocus != null
2437: && toFocus.requestFocus(false,
2438: CausedFocusEvent.Cause.ACTIVATION)) {
2439: return;
2440: }
2441: }
2442: KeyboardFocusManager.getCurrentKeyboardFocusManager()
2443: .clearGlobalFocusOwner();
2444: }
2445: }
2446:
2447: /**
2448: * Sets whether this window should receive focus on
2449: * subsequently being shown (with a call to {@link #setVisible setVisible(true)}),
2450: * or being moved to the front (with a call to {@link #toFront}).
2451: * <p>
2452: * Note that {@link #setVisible setVisible(true)} may be called indirectly
2453: * (e.g. when showing an owner of the window makes the window to be shown).
2454: * {@link #toFront} may also be called indirectly (e.g. when
2455: * {@link #setVisible setVisible(true)} is called on already visible window).
2456: * In all such cases this property takes effect as well.
2457: * <p>
2458: * The value of the property is not inherited by owned windows.
2459: *
2460: * @param autoRequestFocus whether this window should be focused on
2461: * subsequently being shown or being moved to the front
2462: * @see #isAutoRequestFocus
2463: * @see #isFocusableWindow
2464: * @see #setVisible
2465: * @see #toFront
2466: * @since 1.7
2467: */
2468: public void setAutoRequestFocus(boolean autoRequestFocus) {
2469: this .autoRequestFocus = autoRequestFocus;
2470: }
2471:
2472: /**
2473: * Returns whether this window should receive focus on subsequently being shown
2474: * (with a call to {@link #setVisible setVisible(true)}), or being moved to the front
2475: * (with a call to {@link #toFront}).
2476: * <p>
2477: * By default, the window has {@code autoRequestFocus} value of {@code true}.
2478: *
2479: * @return {@code autoRequestFocus} value
2480: * @see #setAutoRequestFocus
2481: * @since 1.7
2482: */
2483: public boolean isAutoRequestFocus() {
2484: return autoRequestFocus;
2485: }
2486:
2487: /**
2488: * Adds a PropertyChangeListener to the listener list. The listener is
2489: * registered for all bound properties of this class, including the
2490: * following:
2491: * <ul>
2492: * <li>this Window's font ("font")</li>
2493: * <li>this Window's background color ("background")</li>
2494: * <li>this Window's foreground color ("foreground")</li>
2495: * <li>this Window's focusability ("focusable")</li>
2496: * <li>this Window's focus traversal keys enabled state
2497: * ("focusTraversalKeysEnabled")</li>
2498: * <li>this Window's Set of FORWARD_TRAVERSAL_KEYS
2499: * ("forwardFocusTraversalKeys")</li>
2500: * <li>this Window's Set of BACKWARD_TRAVERSAL_KEYS
2501: * ("backwardFocusTraversalKeys")</li>
2502: * <li>this Window's Set of UP_CYCLE_TRAVERSAL_KEYS
2503: * ("upCycleFocusTraversalKeys")</li>
2504: * <li>this Window's Set of DOWN_CYCLE_TRAVERSAL_KEYS
2505: * ("downCycleFocusTraversalKeys")</li>
2506: * <li>this Window's focus traversal policy ("focusTraversalPolicy")
2507: * </li>
2508: * <li>this Window's focusable Window state ("focusableWindowState")
2509: * </li>
2510: * <li>this Window's always-on-top state("alwaysOnTop")</li>
2511: * </ul>
2512: * Note that if this Window is inheriting a bound property, then no
2513: * event will be fired in response to a change in the inherited property.
2514: * <p>
2515: * If listener is null, no exception is thrown and no action is performed.
2516: *
2517: * @param listener the PropertyChangeListener to be added
2518: *
2519: * @see Component#removePropertyChangeListener
2520: * @see #addPropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
2521: */
2522: public void addPropertyChangeListener(
2523: PropertyChangeListener listener) {
2524: super .addPropertyChangeListener(listener);
2525: }
2526:
2527: /**
2528: * Adds a PropertyChangeListener to the listener list for a specific
2529: * property. The specified property may be user-defined, or one of the
2530: * following:
2531: * <ul>
2532: * <li>this Window's font ("font")</li>
2533: * <li>this Window's background color ("background")</li>
2534: * <li>this Window's foreground color ("foreground")</li>
2535: * <li>this Window's focusability ("focusable")</li>
2536: * <li>this Window's focus traversal keys enabled state
2537: * ("focusTraversalKeysEnabled")</li>
2538: * <li>this Window's Set of FORWARD_TRAVERSAL_KEYS
2539: * ("forwardFocusTraversalKeys")</li>
2540: * <li>this Window's Set of BACKWARD_TRAVERSAL_KEYS
2541: * ("backwardFocusTraversalKeys")</li>
2542: * <li>this Window's Set of UP_CYCLE_TRAVERSAL_KEYS
2543: * ("upCycleFocusTraversalKeys")</li>
2544: * <li>this Window's Set of DOWN_CYCLE_TRAVERSAL_KEYS
2545: * ("downCycleFocusTraversalKeys")</li>
2546: * <li>this Window's focus traversal policy ("focusTraversalPolicy")
2547: * </li>
2548: * <li>this Window's focusable Window state ("focusableWindowState")
2549: * </li>
2550: * <li>this Window's always-on-top state("alwaysOnTop")</li>
2551: * </ul>
2552: * Note that if this Window is inheriting a bound property, then no
2553: * event will be fired in response to a change in the inherited property.
2554: * <p>
2555: * If listener is null, no exception is thrown and no action is performed.
2556: *
2557: * @param propertyName one of the property names listed above
2558: * @param listener the PropertyChangeListener to be added
2559: *
2560: * @see #addPropertyChangeListener(java.beans.PropertyChangeListener)
2561: * @see Component#removePropertyChangeListener
2562: */
2563: public void addPropertyChangeListener(String propertyName,
2564: PropertyChangeListener listener) {
2565: super .addPropertyChangeListener(propertyName, listener);
2566: }
2567:
2568: /**
2569: * Dispatches an event to this window or one of its sub components.
2570: * @param e the event
2571: */
2572: void dispatchEventImpl(AWTEvent e) {
2573: if (e.getID() == ComponentEvent.COMPONENT_RESIZED) {
2574: invalidate();
2575: validate();
2576: }
2577: super .dispatchEventImpl(e);
2578: }
2579:
2580: /**
2581: * @deprecated As of JDK version 1.1
2582: * replaced by <code>dispatchEvent(AWTEvent)</code>.
2583: */
2584: @Deprecated
2585: public boolean postEvent(Event e) {
2586: if (handleEvent(e)) {
2587: e.consume();
2588: return true;
2589: }
2590: return false;
2591: }
2592:
2593: /**
2594: * Checks if this Window is showing on screen.
2595: * @see Component#setVisible
2596: */
2597: public boolean isShowing() {
2598: return visible;
2599: }
2600:
2601: /**
2602: * @deprecated As of J2SE 1.4, replaced by
2603: * {@link Component#applyComponentOrientation Component.applyComponentOrientation}.
2604: */
2605: @Deprecated
2606: public void applyResourceBundle(ResourceBundle rb) {
2607: applyComponentOrientation(ComponentOrientation
2608: .getOrientation(rb));
2609: }
2610:
2611: /**
2612: * @deprecated As of J2SE 1.4, replaced by
2613: * {@link Component#applyComponentOrientation Component.applyComponentOrientation}.
2614: */
2615: @Deprecated
2616: public void applyResourceBundle(String rbName) {
2617: applyResourceBundle(ResourceBundle.getBundle(rbName));
2618: }
2619:
2620: /*
2621: * Support for tracking all windows owned by this window
2622: */
2623: void addOwnedWindow(WeakReference weakWindow) {
2624: if (weakWindow != null) {
2625: synchronized (ownedWindowList) {
2626: // this if statement should really be an assert, but we don't
2627: // have asserts...
2628: if (!ownedWindowList.contains(weakWindow)) {
2629: ownedWindowList.addElement(weakWindow);
2630: }
2631: }
2632: }
2633: }
2634:
2635: void removeOwnedWindow(WeakReference weakWindow) {
2636: if (weakWindow != null) {
2637: // synchronized block not required since removeElement is
2638: // already synchronized
2639: ownedWindowList.removeElement(weakWindow);
2640: }
2641: }
2642:
2643: void connectOwnedWindow(Window child) {
2644: child.parent = this ;
2645: addOwnedWindow(child.weakThis);
2646: }
2647:
2648: private void addToWindowList() {
2649: synchronized (Window.class) {
2650: Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>) appContext
2651: .get(Window.class);
2652: if (windowList == null) {
2653: windowList = new Vector<WeakReference<Window>>();
2654: appContext.put(Window.class, windowList);
2655: }
2656: windowList.add(weakThis);
2657: }
2658: }
2659:
2660: private static void removeFromWindowList(AppContext context,
2661: WeakReference weakThis) {
2662: synchronized (Window.class) {
2663: Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>) context
2664: .get(Window.class);
2665: if (windowList != null) {
2666: windowList.remove(weakThis);
2667: }
2668: }
2669: }
2670:
2671: private void removeFromWindowList() {
2672: removeFromWindowList(appContext, weakThis);
2673: }
2674:
2675: /**
2676: * The window serialized data version.
2677: *
2678: * @serial
2679: */
2680: private int windowSerializedDataVersion = 2;
2681:
2682: /**
2683: * Writes default serializable fields to stream. Writes
2684: * a list of serializable <code>WindowListener</code>s and
2685: * <code>WindowFocusListener</code>s as optional data.
2686: * Writes a list of child windows as optional data.
2687: * Writes a list of icon images as optional data
2688: *
2689: * @param s the <code>ObjectOutputStream</code> to write
2690: * @serialData <code>null</code> terminated sequence of
2691: * 0 or more pairs; the pair consists of a <code>String</code>
2692: * and and <code>Object</code>; the <code>String</code>
2693: * indicates the type of object and is one of the following:
2694: * <code>windowListenerK</code> indicating a
2695: * <code>WindowListener</code> object;
2696: * <code>windowFocusWindowK</code> indicating a
2697: * <code>WindowFocusListener</code> object;
2698: * <code>ownedWindowK</code> indicating a child
2699: * <code>Window</code> object
2700: *
2701: * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)
2702: * @see Component#windowListenerK
2703: * @see Component#windowFocusListenerK
2704: * @see Component#ownedWindowK
2705: * @see #readObject(ObjectInputStream)
2706: */
2707: private void writeObject(ObjectOutputStream s) throws IOException {
2708: synchronized (this ) {
2709: // Update old focusMgr fields so that our object stream can be read
2710: // by previous releases
2711: focusMgr = new FocusManager();
2712: focusMgr.focusRoot = this ;
2713: focusMgr.focusOwner = getMostRecentFocusOwner();
2714:
2715: s.defaultWriteObject();
2716:
2717: // Clear fields so that we don't keep extra references around
2718: focusMgr = null;
2719:
2720: AWTEventMulticaster
2721: .save(s, windowListenerK, windowListener);
2722: AWTEventMulticaster.save(s, windowFocusListenerK,
2723: windowFocusListener);
2724: AWTEventMulticaster.save(s, windowStateListenerK,
2725: windowStateListener);
2726: }
2727:
2728: s.writeObject(null);
2729:
2730: synchronized (ownedWindowList) {
2731: for (int i = 0; i < ownedWindowList.size(); i++) {
2732: Window child = ownedWindowList.elementAt(i).get();
2733: if (child != null) {
2734: s.writeObject(ownedWindowK);
2735: s.writeObject(child);
2736: }
2737: }
2738: }
2739: s.writeObject(null);
2740:
2741: //write icon array
2742: if (icons != null) {
2743: for (Image i : icons) {
2744: if (i instanceof Serializable) {
2745: s.writeObject(i);
2746: }
2747: }
2748: }
2749: s.writeObject(null);
2750: }
2751:
2752: //
2753: // Part of deserialization procedure to be called before
2754: // user's code.
2755: //
2756: private void initDeserializedWindow() {
2757: setWarningString();
2758: inputContextLock = new Object();
2759:
2760: // Deserialized Windows are not yet visible.
2761: visible = false;
2762:
2763: weakThis = new WeakReference(this );
2764:
2765: anchor = new Object();
2766: sun.java2d.Disposer.addRecord(anchor, new WindowDisposerRecord(
2767: appContext, this ));
2768:
2769: addToWindowList();
2770:
2771: }
2772:
2773: private void deserializeResources(ObjectInputStream s)
2774: throws ClassNotFoundException, IOException,
2775: HeadlessException {
2776: ownedWindowList = new Vector();
2777:
2778: if (windowSerializedDataVersion < 2) {
2779: // Translate old-style focus tracking to new model. For 1.4 and
2780: // later releases, we'll rely on the Window's initial focusable
2781: // Component.
2782: if (focusMgr != null) {
2783: if (focusMgr.focusOwner != null) {
2784: KeyboardFocusManager.setMostRecentFocusOwner(this ,
2785: focusMgr.focusOwner);
2786: }
2787: }
2788:
2789: // This field is non-transient and relies on default serialization.
2790: // However, the default value is insufficient, so we need to set
2791: // it explicitly for object data streams prior to 1.4.
2792: focusableWindowState = true;
2793:
2794: }
2795:
2796: Object keyOrNull;
2797: while (null != (keyOrNull = s.readObject())) {
2798: String key = ((String) keyOrNull).intern();
2799:
2800: if (windowListenerK == key) {
2801: addWindowListener((WindowListener) (s.readObject()));
2802: } else if (windowFocusListenerK == key) {
2803: addWindowFocusListener((WindowFocusListener) (s
2804: .readObject()));
2805: } else if (windowStateListenerK == key) {
2806: addWindowStateListener((WindowStateListener) (s
2807: .readObject()));
2808: } else
2809: // skip value for unrecognized key
2810: s.readObject();
2811: }
2812:
2813: try {
2814: while (null != (keyOrNull = s.readObject())) {
2815: String key = ((String) keyOrNull).intern();
2816:
2817: if (ownedWindowK == key)
2818: connectOwnedWindow((Window) s.readObject());
2819:
2820: else
2821: // skip value for unrecognized key
2822: s.readObject();
2823: }
2824:
2825: //read icons
2826: Object obj = s.readObject(); //Throws OptionalDataException
2827: //for pre1.6 objects.
2828: icons = new ArrayList<Image>(); //Frame.readObject() assumes
2829: //pre1.6 version if icons is null.
2830: while (obj != null) {
2831: if (obj instanceof Image) {
2832: icons.add((Image) obj);
2833: }
2834: obj = s.readObject();
2835: }
2836: } catch (OptionalDataException e) {
2837: // 1.1 serialized form
2838: // ownedWindowList will be updated by Frame.readObject
2839: }
2840:
2841: }
2842:
2843: /**
2844: * Reads the <code>ObjectInputStream</code> and an optional
2845: * list of listeners to receive various events fired by
2846: * the component; also reads a list of
2847: * (possibly <code>null</code>) child windows.
2848: * Unrecognized keys or values will be ignored.
2849: *
2850: * @param s the <code>ObjectInputStream</code> to read
2851: * @exception HeadlessException if
2852: * <code>GraphicsEnvironment.isHeadless</code> returns
2853: * <code>true</code>
2854: * @see java.awt.GraphicsEnvironment#isHeadless
2855: * @see #writeObject
2856: */
2857: private void readObject(ObjectInputStream s)
2858: throws ClassNotFoundException, IOException,
2859: HeadlessException {
2860: GraphicsEnvironment.checkHeadless();
2861: initDeserializedWindow();
2862: ObjectInputStream.GetField f = s.readFields();
2863:
2864: syncLWRequests = f.get("syncLWRequests", systemSyncLWRequests);
2865: state = f.get("state", 0);
2866: focusableWindowState = f.get("focusableWindowState", true);
2867: windowSerializedDataVersion = f.get(
2868: "windowSerializedDataVersion", 1);
2869: locationByPlatform = f.get("locationByPlatform",
2870: locationByPlatformProp);
2871: // Note: 1.4 (or later) doesn't use focusMgr
2872: focusMgr = (FocusManager) f.get("focusMgr", null);
2873: Dialog.ModalExclusionType et = (Dialog.ModalExclusionType) f
2874: .get("modalExclusionType",
2875: Dialog.ModalExclusionType.NO_EXCLUDE);
2876: setModalExclusionType(et); // since 6.0
2877: boolean aot = f.get("alwaysOnTop", false);
2878: if (aot) {
2879: setAlwaysOnTop(aot); // since 1.5; subject to permission check
2880: }
2881:
2882: deserializeResources(s);
2883: }
2884:
2885: /*
2886: * --- Accessibility Support ---
2887: *
2888: */
2889:
2890: /**
2891: * Gets the AccessibleContext associated with this Window.
2892: * For windows, the AccessibleContext takes the form of an
2893: * AccessibleAWTWindow.
2894: * A new AccessibleAWTWindow instance is created if necessary.
2895: *
2896: * @return an AccessibleAWTWindow that serves as the
2897: * AccessibleContext of this Window
2898: * @since 1.3
2899: */
2900: public AccessibleContext getAccessibleContext() {
2901: if (accessibleContext == null) {
2902: accessibleContext = new AccessibleAWTWindow();
2903: }
2904: return accessibleContext;
2905: }
2906:
2907: /**
2908: * This class implements accessibility support for the
2909: * <code>Window</code> class. It provides an implementation of the
2910: * Java Accessibility API appropriate to window user-interface elements.
2911: * @since 1.3
2912: */
2913: protected class AccessibleAWTWindow extends AccessibleAWTContainer {
2914: /*
2915: * JDK 1.3 serialVersionUID
2916: */
2917: private static final long serialVersionUID = 4215068635060671780L;
2918:
2919: /**
2920: * Get the role of this object.
2921: *
2922: * @return an instance of AccessibleRole describing the role of the
2923: * object
2924: * @see javax.accessibility.AccessibleRole
2925: */
2926: public AccessibleRole getAccessibleRole() {
2927: return AccessibleRole.WINDOW;
2928: }
2929:
2930: /**
2931: * Get the state of this object.
2932: *
2933: * @return an instance of AccessibleStateSet containing the current
2934: * state set of the object
2935: * @see javax.accessibility.AccessibleState
2936: */
2937: public AccessibleStateSet getAccessibleStateSet() {
2938: AccessibleStateSet states = super .getAccessibleStateSet();
2939: if (getFocusOwner() != null) {
2940: states.add(AccessibleState.ACTIVE);
2941: }
2942: return states;
2943: }
2944:
2945: } // inner class AccessibleAWTWindow
2946:
2947: /**
2948: * This method returns the GraphicsConfiguration used by this Window.
2949: * @since 1.3
2950: */
2951: public GraphicsConfiguration getGraphicsConfiguration() {
2952: //NOTE: for multiscreen, this will need to take into account
2953: //which screen the window is on/mostly on instead of returning the
2954: //default or constructor argument config.
2955: synchronized (getTreeLock()) {
2956: if (graphicsConfig == null
2957: && !GraphicsEnvironment.isHeadless()) {
2958: graphicsConfig = GraphicsEnvironment
2959: .getLocalGraphicsEnvironment()
2960: .getDefaultScreenDevice()
2961: .getDefaultConfiguration();
2962: }
2963: return graphicsConfig;
2964: }
2965: }
2966:
2967: /**
2968: * Reset this Window's GraphicsConfiguration to match its peer.
2969: */
2970: void resetGC() {
2971: if (!GraphicsEnvironment.isHeadless()) {
2972: // use the peer's GC
2973: setGCFromPeer();
2974: // if it's still null, use the default
2975: if (graphicsConfig == null) {
2976: graphicsConfig = GraphicsEnvironment
2977: .getLocalGraphicsEnvironment()
2978: .getDefaultScreenDevice()
2979: .getDefaultConfiguration();
2980: }
2981: if (log.isLoggable(Level.FINER)) {
2982: log.finer("+ Window.resetGC(): new GC is \n+ "
2983: + graphicsConfig + "\n+ this is " + this );
2984: }
2985: }
2986: }
2987:
2988: /**
2989: * Sets the location of the window relative to the specified
2990: * component.
2991: * <p>
2992: * If the component is not currently showing, or <code>c</code>
2993: * is <code>null</code>, the window is placed at the center of
2994: * the screen. The center point can be determined with {@link
2995: * GraphicsEnvironment#getCenterPoint GraphicsEnvironment.getCenterPoint}
2996: * <p>
2997: * If the bottom of the component is offscreen, the window is
2998: * placed to the side of the <code>Component</code> that is
2999: * closest to the center of the screen. So if the <code>Component</code>
3000: * is on the right part of the screen, the <code>Window</code>
3001: * is placed to its left, and vice versa.
3002: *
3003: * @param c the component in relation to which the window's location
3004: * is determined
3005: * @see java.awt.GraphicsEnvironment#getCenterPoint
3006: * @since 1.4
3007: */
3008: public void setLocationRelativeTo(Component c) {
3009: Container root = null;
3010:
3011: if (c != null) {
3012: if (c instanceof Window || c instanceof Applet) {
3013: root = (Container) c;
3014: } else {
3015: Container parent;
3016: for (parent = c.getParent(); parent != null; parent = parent
3017: .getParent()) {
3018: if (parent instanceof Window
3019: || parent instanceof Applet) {
3020: root = parent;
3021: break;
3022: }
3023: }
3024: }
3025: }
3026:
3027: if ((c != null && !c.isShowing()) || root == null
3028: || !root.isShowing()) {
3029: Dimension paneSize = getSize();
3030:
3031: Point centerPoint = GraphicsEnvironment
3032: .getLocalGraphicsEnvironment().getCenterPoint();
3033: setLocation(centerPoint.x - paneSize.width / 2,
3034: centerPoint.y - paneSize.height / 2);
3035: } else {
3036: Dimension invokerSize = c.getSize();
3037: Point invokerScreenLocation = c.getLocationOnScreen();
3038:
3039: Rectangle windowBounds = getBounds();
3040: int dx = invokerScreenLocation.x
3041: + ((invokerSize.width - windowBounds.width) >> 1);
3042: int dy = invokerScreenLocation.y
3043: + ((invokerSize.height - windowBounds.height) >> 1);
3044: Rectangle ss = root.getGraphicsConfiguration().getBounds();
3045:
3046: // Adjust for bottom edge being offscreen
3047: if (dy + windowBounds.height > ss.y + ss.height) {
3048: dy = ss.y + ss.height - windowBounds.height;
3049: if (invokerScreenLocation.x - ss.x + invokerSize.width
3050: / 2 < ss.width / 2) {
3051: dx = invokerScreenLocation.x + invokerSize.width;
3052: } else {
3053: dx = invokerScreenLocation.x - windowBounds.width;
3054: }
3055: }
3056:
3057: // Avoid being placed off the edge of the screen
3058: if (dx + windowBounds.width > ss.x + ss.width) {
3059: dx = ss.x + ss.width - windowBounds.width;
3060: }
3061: if (dx < ss.x)
3062: dx = ss.x;
3063: if (dy < ss.y)
3064: dy = ss.y;
3065:
3066: setLocation(dx, dy);
3067: }
3068: }
3069:
3070: /**
3071: * Overridden from Component. Top-level Windows should not propagate a
3072: * MouseWheelEvent beyond themselves into their owning Windows.
3073: */
3074: void deliverMouseWheelToAncestor(MouseWheelEvent e) {
3075: }
3076:
3077: /**
3078: * Overridden from Component. Top-level Windows don't dispatch to ancestors
3079: */
3080: boolean dispatchMouseWheelToAncestor(MouseWheelEvent e) {
3081: return false;
3082: }
3083:
3084: /**
3085: * Creates a new strategy for multi-buffering on this component.
3086: * Multi-buffering is useful for rendering performance. This method
3087: * attempts to create the best strategy available with the number of
3088: * buffers supplied. It will always create a <code>BufferStrategy</code>
3089: * with that number of buffers.
3090: * A page-flipping strategy is attempted first, then a blitting strategy
3091: * using accelerated buffers. Finally, an unaccelerated blitting
3092: * strategy is used.
3093: * <p>
3094: * Each time this method is called,
3095: * the existing buffer strategy for this component is discarded.
3096: * @param numBuffers number of buffers to create
3097: * @exception IllegalArgumentException if numBuffers is less than 1.
3098: * @exception IllegalStateException if the component is not displayable
3099: * @see #isDisplayable
3100: * @see #getBufferStrategy
3101: * @since 1.4
3102: */
3103: public void createBufferStrategy(int numBuffers) {
3104: super .createBufferStrategy(numBuffers);
3105: }
3106:
3107: /**
3108: * Creates a new strategy for multi-buffering on this component with the
3109: * required buffer capabilities. This is useful, for example, if only
3110: * accelerated memory or page flipping is desired (as specified by the
3111: * buffer capabilities).
3112: * <p>
3113: * Each time this method
3114: * is called, the existing buffer strategy for this component is discarded.
3115: * @param numBuffers number of buffers to create, including the front buffer
3116: * @param caps the required capabilities for creating the buffer strategy;
3117: * cannot be <code>null</code>
3118: * @exception AWTException if the capabilities supplied could not be
3119: * supported or met; this may happen, for example, if there is not enough
3120: * accelerated memory currently available, or if page flipping is specified
3121: * but not possible.
3122: * @exception IllegalArgumentException if numBuffers is less than 1, or if
3123: * caps is <code>null</code>
3124: * @see #getBufferStrategy
3125: * @since 1.4
3126: */
3127: public void createBufferStrategy(int numBuffers,
3128: BufferCapabilities caps) throws AWTException {
3129: super .createBufferStrategy(numBuffers, caps);
3130: }
3131:
3132: /**
3133: * Returns the <code>BufferStrategy</code> used by this component. This
3134: * method will return null if a <code>BufferStrategy</code> has not yet
3135: * been created or has been disposed.
3136: *
3137: * @return the buffer strategy used by this component
3138: * @see #createBufferStrategy
3139: * @since 1.4
3140: */
3141: public BufferStrategy getBufferStrategy() {
3142: return super .getBufferStrategy();
3143: }
3144:
3145: Component getTemporaryLostComponent() {
3146: return temporaryLostComponent;
3147: }
3148:
3149: Component setTemporaryLostComponent(Component component) {
3150: Component previousComp = temporaryLostComponent;
3151: // Check that "component" is an acceptable focus owner and don't store it otherwise
3152: // - or later we will have problems with opposite while handling WINDOW_GAINED_FOCUS
3153: if (component == null
3154: || (component.isDisplayable() && component.isVisible()
3155: && component.isEnabled() && component
3156: .isFocusable())) {
3157: temporaryLostComponent = component;
3158: } else {
3159: temporaryLostComponent = null;
3160: }
3161: return previousComp;
3162: }
3163:
3164: /**
3165: * Checks whether this window can contain focus owner.
3166: * Verifies that it is focusable and as container it can container focus owner.
3167: * @since 1.5
3168: */
3169: boolean canContainFocusOwner(Component focusOwnerCandidate) {
3170: return super .canContainFocusOwner(focusOwnerCandidate)
3171: && isFocusableWindow();
3172: }
3173:
3174: private boolean locationByPlatform = locationByPlatformProp;
3175:
3176: /**
3177: * Sets whether this Window should appear at the default location for the
3178: * native windowing system or at the current location (returned by
3179: * <code>getLocation</code>) the next time the Window is made visible.
3180: * This behavior resembles a native window shown without programmatically
3181: * setting its location. Most windowing systems cascade windows if their
3182: * locations are not explicitly set. The actual location is determined once the
3183: * window is shown on the screen.
3184: * <p>
3185: * This behavior can also be enabled by setting the System Property
3186: * "java.awt.Window.locationByPlatform" to "true", though calls to this method
3187: * take precedence.
3188: * <p>
3189: * Calls to <code>setVisible</code>, <code>setLocation</code> and
3190: * <code>setBounds</code> after calling <code>setLocationByPlatform</code> clear
3191: * this property of the Window.
3192: * <p>
3193: * For example, after the following code is executed:
3194: * <pre><blockquote>
3195: * setLocationByPlatform(true);
3196: * setVisible(true);
3197: * boolean flag = isLocationByPlatform();
3198: * </blockquote></pre>
3199: * The window will be shown at platform's default location and
3200: * <code>flag</code> will be <code>false</code>.
3201: * <p>
3202: * In the following sample:
3203: * <pre><blockquote>
3204: * setLocationByPlatform(true);
3205: * setLocation(10, 10);
3206: * boolean flag = isLocationByPlatform();
3207: * setVisible(true);
3208: * </blockquote></pre>
3209: * The window will be shown at (10, 10) and <code>flag</code> will be
3210: * <code>false</code>.
3211: *
3212: * @param locationByPlatform <code>true</code> if this Window should appear
3213: * at the default location, <code>false</code> if at the current location
3214: * @throws <code>IllegalComponentStateException</code> if the window
3215: * is showing on screen and locationByPlatform is <code>true</code>.
3216: * @see #setLocation
3217: * @see #isShowing
3218: * @see #setVisible
3219: * @see #isLocationByPlatform
3220: * @see java.lang.System#getProperty(String)
3221: * @since 1.5
3222: */
3223: public void setLocationByPlatform(boolean locationByPlatform) {
3224: synchronized (getTreeLock()) {
3225: if (locationByPlatform && isShowing()) {
3226: throw new IllegalComponentStateException(
3227: "The window is showing on screen.");
3228: }
3229: this .locationByPlatform = locationByPlatform;
3230: }
3231: }
3232:
3233: /**
3234: * Returns <code>true</code> if this Window will appear at the default location
3235: * for the native windowing system the next time this Window is made visible.
3236: * This method always returns <code>false</code> if the Window is showing on the
3237: * screen.
3238: *
3239: * @return whether this Window will appear at the default location
3240: * @see #setLocationByPlatform
3241: * @see #isShowing
3242: * @since 1.5
3243: */
3244: public boolean isLocationByPlatform() {
3245: synchronized (getTreeLock()) {
3246: return locationByPlatform;
3247: }
3248: }
3249:
3250: /**
3251: * {@inheritDoc}
3252: * <p>
3253: * The {@code width} or {@code height} values
3254: * are automatically enlarged if either is less than
3255: * the minimum size as specified by previous call to
3256: * {@code setMinimumSize}.
3257: *
3258: * @see #getBounds
3259: * @see #setLocation(int, int)
3260: * @see #setLocation(Point)
3261: * @see #setSize(int, int)
3262: * @see #setSize(Dimension)
3263: * @see #setMinimumSize
3264: * @see #setLocationByPlatform
3265: * @see #isLocationByPlatform
3266: * @since 1.6
3267: */
3268: public void setBounds(int x, int y, int width, int height) {
3269: synchronized (getTreeLock()) {
3270: if (getBoundsOp() == ComponentPeer.SET_LOCATION
3271: || getBoundsOp() == ComponentPeer.SET_BOUNDS) {
3272: locationByPlatform = false;
3273: }
3274: super .setBounds(x, y, width, height);
3275: }
3276: }
3277:
3278: /**
3279: * {@inheritDoc}
3280: * <p>
3281: * The {@code r.width} or {@code r.height} values
3282: * will be automatically enlarged if either is less than
3283: * the minimum size as specified by previous call to
3284: * {@code setMinimumSize}.
3285: *
3286: * @see #getBounds
3287: * @see #setLocation(int, int)
3288: * @see #setLocation(Point)
3289: * @see #setSize(int, int)
3290: * @see #setSize(Dimension)
3291: * @see #setMinimumSize
3292: * @see #setLocationByPlatform
3293: * @see #isLocationByPlatform
3294: * @since 1.6
3295: */
3296: public void setBounds(Rectangle r) {
3297: setBounds(r.x, r.y, r.width, r.height);
3298: }
3299:
3300: /**
3301: * Determines whether this component will be displayed on the screen.
3302: * @return <code>true</code> if the component and all of its ancestors
3303: * until a toplevel window are visible, <code>false</code> otherwise
3304: */
3305: boolean isRecursivelyVisible() {
3306: // 5079694 fix: for a toplevel to be displayed, its parent doesn't have to be visible.
3307: // We're overriding isRecursivelyVisible to implement this policy.
3308: return visible;
3309: }
3310: } // class Window
3311:
3312: /**
3313: * This class is no longer used, but is maintained for Serialization
3314: * backward-compatibility.
3315: */
3316: class FocusManager implements java.io.Serializable {
3317: Container focusRoot;
3318: Component focusOwner;
3319:
3320: /*
3321: * JDK 1.1 serialVersionUID
3322: */
3323: static final long serialVersionUID = 2491878825643557906L;
3324: }
|