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 }
|