1 /* 2 * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package java.awt; 26 27 import java.applet.Applet; 28 import java.awt.event.*; 29 import java.awt.geom.Point2D; 30 import java.awt.im.InputContext; 31 import java.awt.image.BufferStrategy; 32 import java.awt.image.BufferedImage; 33 import java.awt.peer.ComponentPeer; 34 import java.awt.peer.WindowPeer; 35 import java.beans.PropertyChangeListener; 36 import java.io.IOException; 37 import java.io.ObjectInputStream; 38 import java.io.ObjectOutputStream; 39 import java.io.OptionalDataException; 40 import java.io.Serializable; 41 import java.lang.ref.WeakReference; 42 import java.lang.reflect.InvocationTargetException; 43 import java.security.AccessController; 44 import java.util.ArrayList; 45 import java.util.Arrays; 46 import java.util.EventListener; 47 import java.util.Locale; 48 import java.util.ResourceBundle; 49 import java.util.Set; 50 import java.util.Vector; 51 import java.util.logging.Level; 52 import java.util.logging.Logger; 53 import java.util.concurrent.atomic.AtomicBoolean; 54 import javax.accessibility.*; 55 import sun.awt.AWTAccessor; 56 import sun.awt.AppContext; 57 import sun.awt.CausedFocusEvent; 58 import sun.awt.SunToolkit; 59 import sun.awt.util.IdentityArrayList; 60 import sun.java2d.pipe.Region; 61 import sun.security.action.GetPropertyAction; 62 import sun.security.util.SecurityConstants; 63 64 /** 65 * A <code>Window</code> object is a top-level window with no borders and no 66 * menubar. 67 * The default layout for a window is <code>BorderLayout</code>. 68 * <p> 69 * A window must have either a frame, dialog, or another window defined as its 70 * owner when it's constructed. 71 * <p> 72 * In a multi-screen environment, you can create a <code>Window</code> 73 * on a different screen device by constructing the <code>Window</code> 74 * with {@link #Window(Window, GraphicsConfiguration)}. The 75 * <code>GraphicsConfiguration</code> object is one of the 76 * <code>GraphicsConfiguration</code> objects of the target screen device. 77 * <p> 78 * In a virtual device multi-screen environment in which the desktop 79 * area could span multiple physical screen devices, the bounds of all 80 * configurations are relative to the virtual device coordinate system. 81 * The origin of the virtual-coordinate system is at the upper left-hand 82 * corner of the primary physical screen. Depending on the location of 83 * the primary screen in the virtual device, negative coordinates are 84 * possible, as shown in the following figure. 85 * <p> 86 * <img src="doc-files/MultiScreen.gif" 87 * alt="Diagram shows virtual device containing 4 physical screens. Primary physical screen shows coords (0,0), other screen shows (-80,-100)." 88 * ALIGN=center HSPACE=10 VSPACE=7> 89 * <p> 90 * In such an environment, when calling <code>setLocation</code>, 91 * you must pass a virtual coordinate to this method. Similarly, 92 * calling <code>getLocationOnScreen</code> on a <code>Window</code> returns 93 * virtual device coordinates. Call the <code>getBounds</code> method 94 * of a <code>GraphicsConfiguration</code> to find its origin in the virtual 95 * coordinate system. 96 * <p> 97 * The following code sets the location of a <code>Window</code> 98 * at (10, 10) relative to the origin of the physical screen 99 * of the corresponding <code>GraphicsConfiguration</code>. If the 100 * bounds of the <code>GraphicsConfiguration</code> is not taken 101 * into account, the <code>Window</code> location would be set 102 * at (10, 10) relative to the virtual-coordinate system and would appear 103 * on the primary physical screen, which might be different from the 104 * physical screen of the specified <code>GraphicsConfiguration</code>. 105 * 106 * <pre> 107 * Window w = new Window(Window owner, GraphicsConfiguration gc); 108 * Rectangle bounds = gc.getBounds(); 109 * w.setLocation(10 + bounds.x, 10 + bounds.y); 110 * </pre> 111 * 112 * <p> 113 * Note: the location and size of top-level windows (including 114 * <code>Window</code>s, <code>Frame</code>s, and <code>Dialog</code>s) 115 * are under the control of the desktop's window management system. 116 * Calls to <code>setLocation</code>, <code>setSize</code>, and 117 * <code>setBounds</code> are requests (not directives) which are 118 * forwarded to the window management system. Every effort will be 119 * made to honor such requests. However, in some cases the window 120 * management system may ignore such requests, or modify the requested 121 * geometry in order to place and size the <code>Window</code> in a way 122 * that more closely matches the desktop settings. 123 * <p> 124 * Due to the asynchronous nature of native event handling, the results 125 * returned by <code>getBounds</code>, <code>getLocation</code>, 126 * <code>getLocationOnScreen</code>, and <code>getSize</code> might not 127 * reflect the actual geometry of the Window on screen until the last 128 * request has been processed. During the processing of subsequent 129 * requests these values might change accordingly while the window 130 * management system fulfills the requests. 131 * <p> 132 * An application may set the size and location of an invisible 133 * {@code Window} arbitrarily, but the window management system may 134 * subsequently change its size and/or location when the 135 * {@code Window} is made visible. One or more {@code ComponentEvent}s 136 * will be generated to indicate the new geometry. 137 * <p> 138 * Windows are capable of generating the following WindowEvents: 139 * WindowOpened, WindowClosed, WindowGainedFocus, WindowLostFocus. 140 * 141 * @author Sami Shaio 142 * @author Arthur van Hoff 143 * @see WindowEvent 144 * @see #addWindowListener 145 * @see java.awt.BorderLayout 146 * @since JDK1.0 147 */ 148 public class Window extends Container implements Accessible { 149 150 /** 151 * This represents the warning message that is 152 * to be displayed in a non secure window. ie : 153 * a window that has a security manager installed for 154 * which calling SecurityManager.checkTopLevelWindow() 155 * is false. This message can be displayed anywhere in 156 * the window. 157 * 158 * @serial 159 * @see #getWarningString 160 */ 161 String warningString; 162 163 /** 164 * {@code icons} is the graphical way we can 165 * represent the frames and dialogs. 166 * {@code Window} can't display icon but it's 167 * being inherited by owned {@code Dialog}s. 168 * 169 * @serial 170 * @see #getIconImages 171 * @see #setIconImages(List<? extends Image>) 172 */ 173 transient java.util.List<Image> icons; 174 175 /** 176 * Holds the reference to the component which last had focus in this window 177 * before it lost focus. 178 */ 179 private transient Component temporaryLostComponent; 180 181 static boolean systemSyncLWRequests = false; 182 boolean syncLWRequests = false; 183 transient boolean beforeFirstShow = true; 184 185 static final int OPENED = 0x01; 186 187 /** 188 * An Integer value representing the Window State. 189 * 190 * @serial 191 * @since 1.2 192 * @see #show 193 */ 194 int state; 195 196 /** 197 * A boolean value representing Window always-on-top state 198 * @since 1.5 199 * @serial 200 * @see #setAlwaysOnTop 201 * @see #isAlwaysOnTop 202 */ 203 private boolean alwaysOnTop; 204 205 /** 206 * Contains all the windows that have a peer object associated, 207 * i. e. between addNotify() and removeNotify() calls. The list 208 * of all Window instances can be obtained from AppContext object. 209 * 210 * @since 1.6 211 */ 212 private static final IdentityArrayList<Window> allWindows = new IdentityArrayList<Window>(); 213 214 /** 215 * A vector containing all the windows this 216 * window currently owns. 217 * @since 1.2 218 * @see #getOwnedWindows 219 */ 220 transient Vector<WeakReference<Window>> ownedWindowList = 221 new Vector<WeakReference<Window>>(); 222 223 /* 224 * We insert a weak reference into the Vector of all Windows in AppContext 225 * instead of 'this' so that garbage collection can still take place 226 * correctly. 227 */ 228 private transient WeakReference<Window> weakThis; 229 230 transient boolean showWithParent; 231 232 /** 233 * Contains the modal dialog that blocks this window, or null 234 * if the window is unblocked. 235 * 236 * @since 1.6 237 */ 238 transient Dialog modalBlocker; 239 240 /** 241 * @serial 242 * 243 * @see java.awt.Dialog.ModalExclusionType 244 * @see #getModalExclusionType 245 * @see #setModalExclusionType 246 * 247 * @since 1.6 248 */ 249 Dialog.ModalExclusionType modalExclusionType; 250 251 transient WindowListener windowListener; 252 transient WindowStateListener windowStateListener; 253 transient WindowFocusListener windowFocusListener; 254 255 transient InputContext inputContext; 256 private transient Object inputContextLock = new Object(); 257 258 /** 259 * Unused. Maintained for serialization backward-compatibility. 260 * 261 * @serial 262 * @since 1.2 263 */ 264 private FocusManager focusMgr; 265 266 /** 267 * Indicates whether this Window can become the focused Window. 268 * 269 * @serial 270 * @see #getFocusableWindowState 271 * @see #setFocusableWindowState 272 * @since 1.4 273 */ 274 private boolean focusableWindowState = true; 275 276 /** 277 * Indicates whether this window should receive focus on 278 * subsequently being shown (with a call to {@code setVisible(true)}), or 279 * being moved to the front (with a call to {@code toFront()}). 280 * 281 * @serial 282 * @see #setAutoRequestFocus 283 * @see #isAutoRequestFocus 284 * @since 1.7 285 */ 286 private transient volatile boolean autoRequestFocus = true; 287 288 /* 289 * Indicates that this window is being shown. This flag is set to true at 290 * the beginning of show() and to false at the end of show(). 291 * 292 * @see #show() 293 * @see Dialog#shouldBlock 294 */ 295 transient boolean isInShow = false; 296 297 /* 298 * The opacity level of the window 299 * 300 * @see #setOpacity(float) 301 * @see #getOpacity() 302 * @since 1.7 303 */ 304 private float opacity = 1.0f; 305 306 /* 307 * The shape assigned to this window. This field is set to {@code null} if 308 * no shape is set (rectangular window). 309 * 310 * @see #getShape() 311 * @see #setShape(Shape) 312 * @since 1.7 313 */ 314 private Shape shape = null; 315 316 private static final String base = "win"; 317 private static int nameCounter = 0; 318 319 /* 320 * JDK 1.1 serialVersionUID 321 */ 322 private static final long serialVersionUID = 4497834738069338734L; 323 324 private static final Logger log = Logger.getLogger("java.awt.Window"); 325 326 private static final boolean locationByPlatformProp; 327 328 transient boolean isTrayIconWindow = false; 329 330 /** 331 * These fields are initialized in the native peer code 332 * or via AWTAccessor's WindowAccessor. 333 */ 334 private transient volatile int securityWarningWidth = 0; 335 private transient volatile int securityWarningHeight = 0; 336 337 /** 338 * These fields represent the desired location for the security 339 * warning if this window is untrusted. 340 * See com.sun.awt.SecurityWarning for more details. 341 */ 342 private transient double securityWarningPointX = 2.0; 343 private transient double securityWarningPointY = 0.0; 344 private transient float securityWarningAlignmentX = RIGHT_ALIGNMENT; 345 private transient float securityWarningAlignmentY = TOP_ALIGNMENT; 346 347 static { 348 /* ensure that the necessary native libraries are loaded */ 349 Toolkit.loadLibraries(); 350 if (!GraphicsEnvironment.isHeadless()) { 351 initIDs(); 352 } 353 354 String s = (String) java.security.AccessController.doPrivileged( 355 new GetPropertyAction("java.awt.syncLWRequests")); 356 systemSyncLWRequests = (s != null && s.equals("true")); 357 s = (String) java.security.AccessController.doPrivileged( 358 new GetPropertyAction("java.awt.Window.locationByPlatform")); 359 locationByPlatformProp = (s != null && s.equals("true")); 360 361 AWTAccessor.setWindowAccessor(new AWTAccessor.WindowAccessor() { 362 public float getOpacity(Window window) { 363 return window.opacity; 364 } 365 public void setOpacity(Window window, float opacity) { 366 window.setOpacity(opacity); 367 } 368 public Shape getShape(Window window) { 369 return window.getShape(); 370 } 371 public void setShape(Window window, Shape shape) { 372 window.setShape(shape); 373 } 374 public boolean isOpaque(Window window) { 375 /* 376 return window.getBackground().getAlpha() < 255; 377 */ 378 synchronized (window.getTreeLock()) { 379 return window.opaque; 380 } 381 } 382 public void setOpaque(Window window, boolean opaque) { 383 /* 384 Color bg = window.getBackground(); 385 window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(), 386 opaque ? 255 : 0)); 387 */ 388 window.setOpaque(opaque); 389 } 390 public void updateWindow(Window window) { 391 window.updateWindow(); 392 } 393 394 public void setLWRequestStatus(Window changed, boolean status) { 395 changed.syncLWRequests = status; 396 } 397 398 public Dimension getSecurityWarningSize(Window window) { 399 return new Dimension(window.securityWarningWidth, 400 window.securityWarningHeight); 401 } 402 403 public void setSecurityWarningSize(Window window, int width, int height) 404 { 405 window.securityWarningWidth = width; 406 window.securityWarningHeight = height; 407 } 408 409 public void setSecurityWarningPosition(Window window, 410 Point2D point, float alignmentX, float alignmentY) 411 { 412 window.securityWarningPointX = point.getX(); 413 window.securityWarningPointY = point.getY(); 414 window.securityWarningAlignmentX = alignmentX; 415 window.securityWarningAlignmentY = alignmentY; 416 417 synchronized (window.getTreeLock()) { 418 WindowPeer peer = (WindowPeer)window.getPeer(); 419 if (peer != null) { 420 peer.repositionSecurityWarning(); 421 } 422 } 423 } 424 425 public Point2D calculateSecurityWarningPosition(Window window, 426 double x, double y, double w, double h) 427 { 428 return window.calculateSecurityWarningPosition(x, y, w, h); 429 } 430 }); // WindowAccessor 431 } // static 432 433 /** 434 * Initialize JNI field and method IDs for fields that may be 435 accessed from C. 436 */ 437 private static native void initIDs(); 438 439 /** 440 * Constructs a new, initially invisible window in default size with the 441 * specified <code>GraphicsConfiguration</code>. 442 * <p> 443 * If there is a security manager, this method first calls 444 * the security manager's <code>checkTopLevelWindow</code> 445 * method with <code>this</code> 446 * as its argument to determine whether or not the window 447 * must be displayed with a warning banner. 448 * 449 * @param gc the <code>GraphicsConfiguration</code> of the target screen 450 * device. If <code>gc</code> is <code>null</code>, the system default 451 * <code>GraphicsConfiguration</code> is assumed 452 * @exception IllegalArgumentException if <code>gc</code> 453 * is not from a screen device 454 * @exception HeadlessException when 455 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code> 456 * 457 * @see java.awt.GraphicsEnvironment#isHeadless 458 * @see java.lang.SecurityManager#checkTopLevelWindow 459 */ 460 Window(GraphicsConfiguration gc) { 461 init(gc); 462 } 463 464 transient Object anchor = new Object(); 465 static class WindowDisposerRecord implements sun.java2d.DisposerRecord { 466 final WeakReference<Window> owner; 467 final WeakReference weakThis; 468 final AppContext context; 469 WindowDisposerRecord(AppContext context, Window victim) { 470 owner = new WeakReference<Window>(victim.getOwner()); 471 weakThis = victim.weakThis; 472 this.context = context; 473 } 474 public void dispose() { 475 Window parent = owner.get(); 476 if (parent != null) { 477 parent.removeOwnedWindow(weakThis); 478 } 479 Window.removeFromWindowList(context, weakThis); 480 } 481 } 482 483 private void init(GraphicsConfiguration gc) { 484 GraphicsEnvironment.checkHeadless(); 485 486 syncLWRequests = systemSyncLWRequests; 487 488 weakThis = new WeakReference<Window>(this); 489 addToWindowList(); 490 491 setWarningString(); 492 this.cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); 493 this.visible = false; 494 if (gc == null) { 495 this.graphicsConfig = 496 GraphicsEnvironment.getLocalGraphicsEnvironment(). 497 getDefaultScreenDevice().getDefaultConfiguration(); 498 } else { 499 this.graphicsConfig = gc; 500 } 501 if (graphicsConfig.getDevice().getType() != 502 GraphicsDevice.TYPE_RASTER_SCREEN) { 503 throw new IllegalArgumentException("not a screen device"); 504 } 505 setLayout(new BorderLayout()); 506 507 /* offset the initial location with the original of the screen */ 508 /* and any insets */ 509 Rectangle screenBounds = graphicsConfig.getBounds(); 510 Insets screenInsets = getToolkit().getScreenInsets(graphicsConfig); 511 int x = getX() + screenBounds.x + screenInsets.left; 512 int y = getY() + screenBounds.y + screenInsets.top; 513 if (x != this.x || y != this.y) { 514 setLocation(x, y); 515 /* reset after setLocation */ 516 setLocationByPlatform(locationByPlatformProp); 517 } 518 519 modalExclusionType = Dialog.ModalExclusionType.NO_EXCLUDE; 520 521 sun.java2d.Disposer.addRecord(anchor, new WindowDisposerRecord(appContext, this)); 522 } 523 524 /** 525 * Constructs a new, initially invisible window in the default size. 526 * 527 * <p>First, if there is a security manager, its 528 * <code>checkTopLevelWindow</code> 529 * method is called with <code>this</code> 530 * as its argument 531 * to see if it's ok to display the window without a warning banner. 532 * If the default implementation of <code>checkTopLevelWindow</code> 533 * is used (that is, that method is not overriden), then this results in 534 * a call to the security manager's <code>checkPermission</code> method 535 * with an <code>AWTPermission("showWindowWithoutWarningBanner")</code> 536 * permission. It that method raises a SecurityException, 537 * <code>checkTopLevelWindow</code> returns false, otherwise it 538 * returns true. If it returns false, a warning banner is created. 539 * 540 * @exception HeadlessException when 541 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code> 542 * 543 * @see java.awt.GraphicsEnvironment#isHeadless 544 * @see java.lang.SecurityManager#checkTopLevelWindow 545 */ 546 Window() throws HeadlessException { 547 GraphicsEnvironment.checkHeadless(); 548 init((GraphicsConfiguration)null); 549 } 550 551 /** 552 * Constructs a new, initially invisible window with the specified 553 * <code>Frame</code> as its owner. The window will not be focusable 554 * unless its owner is showing on the screen. 555 * <p> 556 * If there is a security manager, this method first calls 557 * the security manager's <code>checkTopLevelWindow</code> 558 * method with <code>this</code> 559 * as its argument to determine whether or not the window 560 * must be displayed with a warning banner. 561 * 562 * @param owner the <code>Frame</code> to act as owner or <code>null</code> 563 * if this window has no owner 564 * @exception IllegalArgumentException if the <code>owner</code>'s 565 * <code>GraphicsConfiguration</code> is not from a screen device 566 * @exception HeadlessException when 567 * <code>GraphicsEnvironment.isHeadless</code> returns <code>true</code> 568 * 569 * @see java.awt.GraphicsEnvironment#isHeadless 570 * @see java.lang.SecurityManager#checkTopLevelWindow 571 * @see #isShowing 572 */ 573 public Window(Frame owner) { 574 this(owner == null ? (GraphicsConfiguration)null : 575 owner.getGraphicsConfiguration()); 576 ownedInit(owner); 577 } 578 579 /** 580 * Constructs a new, initially invisible window with the specified 581 * <code>Window</code> as its owner. This window will not be focusable 582 * unless its nearest owning <code>Frame</code> or <code>Dialog</code> 583 * is showing on the screen. 584 * <p> 585 * If there is a security manager, this method first calls 586 * the security manager's <code>checkTopLevelWindow</code> 587 * method with <code>this</code> 588 * as its argument to determine whether or not the window 589 * must be displayed with a warning banner. 590 * 591 * @param owner the <code>Window</code> to act as owner or 592 * <code>null</code> if this window has no owner 593 * @exception IllegalArgumentException if the <code>owner</code>'s 594 * <code>GraphicsConfiguration</code> is not from a screen device 595 * @exception HeadlessException when 596 * <code>GraphicsEnvironment.isHeadless()</code> returns 597 * <code>true</code> 598 * 599 * @see java.awt.GraphicsEnvironment#isHeadless 600 * @see java.lang.SecurityManager#checkTopLevelWindow 601 * @see #isShowing 602 * 603 * @since 1.2 604 */ 605 public Window(Window owner) { 606 this(owner == null ? (GraphicsConfiguration)null : 607 owner.getGraphicsConfiguration()); 608 ownedInit(owner); 609 } 610 611 /** 612 * Constructs a new, initially invisible window with the specified owner 613 * <code>Window</code> and a <code>GraphicsConfiguration</code> 614 * of a screen device. The Window will not be focusable unless 615 * its nearest owning <code>Frame</code> or <code>Dialog</code> 616 * is showing on the screen. 617 * <p> 618 * If there is a security manager, this method first calls 619 * the security manager's <code>checkTopLevelWindow</code> 620 * method with <code>this</code> 621 * as its argument to determine whether or not the window 622 * must be displayed with a warning banner. 623 * 624 * @param owner the window to act as owner or <code>null</code> 625 * if this window has no owner 626 * @param gc the <code>GraphicsConfiguration</code> of the target 627 * screen device; if <code>gc</code> is <code>null</code>, 628 * the system default <code>GraphicsConfiguration</code> is assumed 629 * @exception IllegalArgumentException if <code>gc</code> 630 * is not from a screen device 631 * @exception HeadlessException when 632 * <code>GraphicsEnvironment.isHeadless()</code> returns 633 * <code>true</code> 634 * 635 * @see java.awt.GraphicsEnvironment#isHeadless 636 * @see java.lang.SecurityManager#checkTopLevelWindow 637 * @see GraphicsConfiguration#getBounds 638 * @see #isShowing 639 * @since 1.3 640 */ 641 public Window(Window owner, GraphicsConfiguration gc) { 642 this(gc); 643 ownedInit(owner); 644 } 645 646 private void ownedInit(Window owner) { 647 this.parent = owner; 648 if (owner != null) { 649 owner.addOwnedWindow(weakThis); 650 } 651 } 652 653 /** 654 * Construct a name for this component. Called by getName() when the 655 * name is null. 656 */ 657 String constructComponentName() { 658 synchronized (Window.class) { 659 return base + nameCounter++; 660 } 661 } 662 663 /** 664 * Returns the sequence of images to be displayed as the icon for this window. 665 * <p> 666 * This method returns a copy of the internally stored list, so all operations 667 * on the returned object will not affect the window's behavior. 668 * 669 * @return the copy of icon images' list for this window, or 670 * empty list if this window doesn't have icon images. 671 * @see #setIconImages 672 * @see #setIconImage(Image) 673 * @since 1.6 674 */ 675 public java.util.List<Image> getIconImages() { 676 java.util.List<Image> icons = this.icons; 677 if (icons == null || icons.size() == 0) { 678 return new ArrayList<Image>(); 679 } 680 return new ArrayList<Image>(icons); 681 } 682 683 /** 684 * Sets the sequence of images to be displayed as the icon 685 * for this window. Subsequent calls to {@code getIconImages} will 686 * always return a copy of the {@code icons} list. 687 * <p> 688 * Depending on the platform capabilities one or several images 689 * of different dimensions will be used as the window's icon. 690 * <p> 691 * The {@code icons} list is scanned for the images of most 692 * appropriate dimensions from the beginning. If the list contains 693 * several images of the same size, the first will be used. 694 * <p> 695 * Ownerless windows with no icon specified use platfrom-default icon. 696 * The icon of an owned window may be inherited from the owner 697 * unless explicitly overridden. 698 * Setting the icon to {@code null} or empty list restores 699 * the default behavior. 700 * <p> 701 * Note : Native windowing systems may use different images of differing 702 * dimensions to represent a window, depending on the context (e.g. 703 * window decoration, window list, taskbar, etc.). They could also use 704 * just a single image for all contexts or no image at all. 705 * 706 * @param icons the list of icon images to be displayed. 707 * @see #getIconImages() 708 * @see #setIconImage(Image) 709 * @since 1.6 710 */ 711 public synchronized void setIconImages(java.util.List<? extends Image> icons) { 712 this.icons = (icons == null) ? new ArrayList<Image>() : 713 new ArrayList<Image>(icons); 714 WindowPeer peer = (WindowPeer)this.peer; 715 if (peer != null) { 716 peer.updateIconImages(); 717 } 718 // Always send a property change event 719 firePropertyChange("iconImage", null, null); 720 } 721 722 /** 723 * Sets the image to be displayed as the icon for this window. 724 * <p> 725 * This method can be used instead of {@link #setIconImages setIconImages()} 726 * to specify a single image as a window's icon. 727 * <p> 728 * The following statement: 729 * <pre> 730 * setIconImage(image); 731 * </pre> 732 * is equivalent to: 733 * <pre> 734 * ArrayList<Image> imageList = new ArrayList<Image>(); 735 * imageList.add(image); 736 * setIconImages(imageList); 737 * </pre> 738 * <p> 739 * Note : Native windowing systems may use different images of differing 740 * dimensions to represent a window, depending on the context (e.g. 741 * window decoration, window list, taskbar, etc.). They could also use 742 * just a single image for all contexts or no image at all. 743 * 744 * @param image the icon image to be displayed. 745 * @see #setIconImages 746 * @see #getIconImages() 747 * @since 1.6 748 */ 749 public void setIconImage(Image image) { 750 ArrayList<Image> imageList = new ArrayList<Image>(); 751 if (image != null) { 752 imageList.add(image); 753 } 754 setIconImages(imageList); 755 } 756 757 /** 758 * Makes this Window displayable by creating the connection to its 759 * native screen resource. 760 * This method is called internally by the toolkit and should 761 * not be called directly by programs. 762 * @see Component#isDisplayable 763 * @see Container#removeNotify 764 * @since JDK1.0 765 */ 766 public void addNotify() { 767 synchronized (getTreeLock()) { 768 Container parent = this.parent; 769 if (parent != null && parent.getPeer() == null) { 770 parent.addNotify(); 771 } 772 if (peer == null) { 773 peer = getToolkit().createWindow(this); 774 } 775 synchronized (allWindows) { 776 allWindows.add(this); 777 } 778 super.addNotify(); 779 } 780 } 781 782 /** 783 * {@inheritDoc} 784 */ 785 public void removeNotify() { 786 synchronized (getTreeLock()) { 787 synchronized (allWindows) { 788 allWindows.remove(this); 789 } 790 super.removeNotify(); 791 } 792 } 793 794 /** 795 * Causes this Window to be sized to fit the preferred size 796 * and layouts of its subcomponents. If the window and/or its owner 797 * are not yet displayable, both are made displayable before 798 * calculating the preferred size. The Window will be validated 799 * after the preferredSize is calculated. 800 * @see Component#isDisplayable 801 */ 802 public void pack() { 803 Container parent = this.parent; 804 if (parent != null && parent.getPeer() == null) { 805 parent.addNotify(); 806 } 807 if (peer == null) { 808 addNotify(); 809 } 810 Dimension newSize = getPreferredSize(); 811 if (peer != null) { 812 setClientSize(newSize.width, newSize.height); 813 } 814 815 if(beforeFirstShow) { 816 isPacked = true; 817 } 818 819 validate(); 820 } 821 822 /** 823 * Sets the minimum size of this window to a constant 824 * value. Subsequent calls to {@code getMinimumSize} 825 * will always return this value. If current window's 826 * size is less than {@code minimumSize} the size of the 827 * window is automatically enlarged to honor the minimum size. 828 * <p> 829 * If the {@code setSize} or {@code setBounds} methods 830 * are called afterwards with a width or height less than 831 * that specified by {@code setMinimumSize} the window 832 * is automatically enlarged to honor the {@code minimumSize} 833 * value. Setting the minimum size to {@code null} restores 834 * the default behavior. 835 * <p> 836 * Resizing operation may be restricted if the user tries 837 * to resize window below the {@code minimumSize} value. 838 * This behaviour is platform-dependent. 839 * 840 * @param minimumSize the new minimum size of this window 841 * @see Component#setMinimumSize 842 * @see #getMinimumSize 843 * @see #isMinimumSizeSet 844 * @see #setSize(Dimension) 845 * @since 1.6 846 */ 847 public void setMinimumSize(Dimension minimumSize) { 848 synchronized (getTreeLock()) { 849 super.setMinimumSize(minimumSize); 850 Dimension size = getSize(); 851 if (isMinimumSizeSet()) { 852 if (size.width < minimumSize.width || size.height < minimumSize.height) { 853 int nw = Math.max(width, minimumSize.width); 854 int nh = Math.max(height, minimumSize.height); 855 setSize(nw, nh); 856 } 857 } 858 if (peer != null) { 859 ((WindowPeer)peer).updateMinimumSize(); 860 } 861 } 862 } 863 864 /** 865 * {@inheritDoc} 866 * <p> 867 * The {@code d.width} and {@code d.height} values 868 * are automatically enlarged if either is less than 869 * the minimum size as specified by previous call to 870 * {@code setMinimumSize}. 871 * 872 * @see #getSize 873 * @see #setBounds 874 * @see #setMinimumSize 875 * @since 1.6 876 */ 877 public void setSize(Dimension d) { 878 super.setSize(d); 879 } 880 881 /** 882 * {@inheritDoc} 883 * <p> 884 * The {@code width} and {@code height} values 885 * are automatically enlarged if either is less than 886 * the minimum size as specified by previous call to 887 * {@code setMinimumSize}. 888 * 889 * @see #getSize 890 * @see #setBounds 891 * @see #setMinimumSize 892 * @since 1.6 893 */ 894 public void setSize(int width, int height) { 895 super.setSize(width, height); 896 } 897 898 /** 899 * @deprecated As of JDK version 1.1, 900 * replaced by <code>setBounds(int, int, int, int)</code>. 901 */ 902 @Deprecated 903 public void reshape(int x, int y, int width, int height) { 904 if (isMinimumSizeSet()) { 905 Dimension minSize = getMinimumSize(); 906 if (width < minSize.width) { 907 width = minSize.width; 908 } 909 if (height < minSize.height) { 910 height = minSize.height; 911 } 912 } 913 super.reshape(x, y, width, height); 914 } 915 916 void setClientSize(int w, int h) { 917 synchronized (getTreeLock()) { 918 setBoundsOp(ComponentPeer.SET_CLIENT_SIZE); 919 setBounds(x, y, w, h); 920 } 921 } 922 923 static private final AtomicBoolean 924 beforeFirstWindowShown = new AtomicBoolean(true); 925 926 static final void closeSplashScreen() { 927 if (beforeFirstWindowShown.getAndSet(false)) { 928 SunToolkit.closeSplashScreen(); 929 } 930 } 931 932 /** 933 * Shows or hides this {@code Window} depending on the value of parameter 934 * {@code b}. 935 * @param b if {@code true}, makes the {@code Window} visible, 936 * otherwise hides the {@code Window}. 937 * If the {@code Window} and/or its owner 938 * are not yet displayable, both are made displayable. The 939 * {@code Window} will be validated prior to being made visible. 940 * If the {@code Window} is already visible, this will bring the 941 * {@code Window} to the front.<p> 942 * If {@code false}, hides this {@code Window}, its subcomponents, and all 943 * of its owned children. 944 * The {@code Window} and its subcomponents can be made visible again 945 * with a call to {@code #setVisible(true)}. 946 * @see java.awt.Component#isDisplayable 947 * @see java.awt.Component#setVisible 948 * @see java.awt.Window#toFront 949 * @see java.awt.Window#dispose 950 */ 951 public void setVisible(boolean b) { 952 super.setVisible(b); 953 } 954 955 /** 956 * Makes the Window visible. If the Window and/or its owner 957 * are not yet displayable, both are made displayable. The 958 * Window will be validated prior to being made visible. 959 * If the Window is already visible, this will bring the Window 960 * to the front. 961 * @see Component#isDisplayable 962 * @see #toFront 963 * @deprecated As of JDK version 1.5, replaced by 964 * {@link #setVisible(boolean)}. 965 */ 966 @Deprecated 967 public void show() { 968 if (peer == null) { 969 addNotify(); 970 } 971 validate(); 972 973 isInShow = true; 974 if (visible) { 975 toFront(); 976 } else { 977 beforeFirstShow = false; 978 closeSplashScreen(); 979 Dialog.checkShouldBeBlocked(this); 980 super.show(); 981 locationByPlatform = false; 982 for (int i = 0; i < ownedWindowList.size(); i++) { 983 Window child = ownedWindowList.elementAt(i).get(); 984 if ((child != null) && child.showWithParent) { 985 child.show(); 986 child.showWithParent = false; 987 } // endif 988 } // endfor 989 if (!isModalBlocked()) { 990 updateChildrenBlocking(); 991 } else { 992 // fix for 6532736: after this window is shown, its blocker 993 // should be raised to front 994 modalBlocker.toFront_NoClientCode(); 995 } 996 if (this instanceof Frame || this instanceof Dialog) { 997 updateChildFocusableWindowState(this); 998 } 999 } 1000 isInShow = false; 1001 1002 // If first time shown, generate WindowOpened event 1003 if ((state & OPENED) == 0) { 1004 postWindowEvent(WindowEvent.WINDOW_OPENED); 1005 state |= OPENED; 1006 } 1007 } 1008 1009 static void updateChildFocusableWindowState(Window w) { 1010 if (w.getPeer() != null && w.isShowing()) { 1011 ((WindowPeer)w.getPeer()).updateFocusableWindowState(); 1012 } 1013 for (int i = 0; i < w.ownedWindowList.size(); i++) { 1014 Window child = w.ownedWindowList.elementAt(i).get(); 1015 if (child != null) { 1016 updateChildFocusableWindowState(child); 1017 } 1018 } 1019 } 1020 1021 synchronized void postWindowEvent(int id) { 1022 if (windowListener != null 1023 || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0 1024 || Toolkit.enabledOnToolkit(AWTEvent.WINDOW_EVENT_MASK)) { 1025 WindowEvent e = new WindowEvent(this, id); 1026 Toolkit.getEventQueue().postEvent(e); 1027 } 1028 } 1029 1030 /** 1031 * Hide this Window, its subcomponents, and all of its owned children. 1032 * The Window and its subcomponents can be made visible again 1033 * with a call to {@code show}. 1034 * </p> 1035 * @see #show 1036 * @see #dispose 1037 * @deprecated As of JDK version 1.5, replaced by 1038 * {@link #setVisible(boolean)}. 1039 */ 1040 @Deprecated 1041 public void hide() { 1042 synchronized(ownedWindowList) { 1043 for (int i = 0; i < ownedWindowList.size(); i++) { 1044 Window child = ownedWindowList.elementAt(i).get(); 1045 if ((child != null) && child.visible) { 1046 child.hide(); 1047 child.showWithParent = true; 1048 } 1049 } 1050 } 1051 if (isModalBlocked()) { 1052 modalBlocker.unblockWindow(this); 1053 } 1054 super.hide(); 1055 } 1056 1057 final void clearMostRecentFocusOwnerOnHide() { 1058 /* do nothing */ 1059 } 1060 1061 /** 1062 * Releases all of the native screen resources used by this 1063 * <code>Window</code>, its subcomponents, and all of its owned 1064 * children. That is, the resources for these <code>Component</code>s 1065 * will be destroyed, any memory they consume will be returned to the 1066 * OS, and they will be marked as undisplayable. 1067 * <p> 1068 * The <code>Window</code> and its subcomponents can be made displayable 1069 * again by rebuilding the native resources with a subsequent call to 1070 * <code>pack</code> or <code>show</code>. The states of the recreated 1071 * <code>Window</code> and its subcomponents will be identical to the 1072 * states of these objects at the point where the <code>Window</code> 1073 * was disposed (not accounting for additional modifications between 1074 * those actions). 1075 * <p> 1076 * <b>Note</b>: When the last displayable window 1077 * within the Java virtual machine (VM) is disposed of, the VM may 1078 * terminate. See <a href="doc-files/AWTThreadIssues.html#Autoshutdown"> 1079 * AWT Threading Issues</a> for more information. 1080 * @see Component#isDisplayable 1081 * @see #pack 1082 * @see #show 1083 */ 1084 public void dispose() { 1085 doDispose(); 1086 } 1087 1088 /* 1089 * Fix for 4872170. 1090 * If dispose() is called on parent then its children have to be disposed as well 1091 * as reported in javadoc. So we need to implement this functionality even if a 1092 * child overrides dispose() in a wrong way without calling super.dispose(). 1093 */ 1094 void disposeImpl() { 1095 dispose(); 1096 if (getPeer() != null) { 1097 doDispose(); 1098 } 1099 } 1100 1101 void doDispose() { 1102 class DisposeAction implements Runnable { 1103 public void run() { 1104 // Check if this window is the fullscreen window for the 1105 // device. Exit the fullscreen mode prior to disposing 1106 // of the window if that's the case. 1107 GraphicsDevice gd = getGraphicsConfiguration().getDevice(); 1108 if (gd.getFullScreenWindow() == Window.this) { 1109 gd.setFullScreenWindow(null); 1110 } 1111 1112 Object[] ownedWindowArray; 1113 synchronized(ownedWindowList) { 1114 ownedWindowArray = new Object[ownedWindowList.size()]; 1115 ownedWindowList.copyInto(ownedWindowArray); 1116 } 1117 for (int i = 0; i < ownedWindowArray.length; i++) { 1118 Window child = (Window) (((WeakReference) 1119 (ownedWindowArray[i])).get()); 1120 if (child != null) { 1121 child.disposeImpl(); 1122 } 1123 } 1124 hide(); 1125 beforeFirstShow = true; 1126 removeNotify(); 1127 synchronized (inputContextLock) { 1128 if (inputContext != null) { 1129 inputContext.dispose(); 1130 inputContext = null; 1131 } 1132 } 1133 clearCurrentFocusCycleRootOnHide(); 1134 } 1135 } 1136 DisposeAction action = new DisposeAction(); 1137 if (EventQueue.isDispatchThread()) { 1138 action.run(); 1139 } 1140 else { 1141 try { 1142 EventQueue.invokeAndWait(this, action); 1143 } 1144 catch (InterruptedException e) { 1145 System.err.println("Disposal was interrupted:"); 1146 e.printStackTrace(); 1147 } 1148 catch (InvocationTargetException e) { 1149 System.err.println("Exception during disposal:"); 1150 e.printStackTrace(); 1151 } 1152 } 1153 // Execute outside the Runnable because postWindowEvent is 1154 // synchronized on (this). We don't need to synchronize the call 1155 // on the EventQueue anyways. 1156 postWindowEvent(WindowEvent.WINDOW_CLOSED); 1157 } 1158 1159 /* 1160 * Should only be called while holding the tree lock. 1161 * It's overridden here because parent == owner in Window, 1162 * and we shouldn't adjust counter on owner 1163 */ 1164 void adjustListeningChildrenOnParent(long mask, int num) { 1165 } 1166 1167 // Should only be called while holding tree lock 1168 void adjustDecendantsOnParent(int num) { 1169 // do nothing since parent == owner and we shouldn't 1170 // ajust counter on owner 1171 } 1172 1173 /** 1174 * If this Window is visible, brings this Window to the front and may make 1175 * it the focused Window. 1176 * <p> 1177 * Places this Window at the top of the stacking order and shows it in 1178 * front of any other Windows in this VM. No action will take place if this 1179 * Window is not visible. Some platforms do not allow Windows which own 1180 * other Windows to appear on top of those owned Windows. Some platforms 1181 * may not permit this VM to place its Windows above windows of native 1182 * applications, or Windows of other VMs. This permission may depend on 1183 * whether a Window in this VM is already focused. Every attempt will be 1184 * made to move this Window as high as possible in the stacking order; 1185 * however, developers should not assume that this method will move this 1186 * Window above all other windows in every situation. 1187 * <p> 1188 * Because of variations in native windowing systems, no guarantees about 1189 * changes to the focused and active Windows can be made. Developers must 1190 * never assume that this Window is the focused or active Window until this 1191 * Window receives a WINDOW_GAINED_FOCUS or WINDOW_ACTIVATED event. On 1192 * platforms where the top-most window is the focused window, this method 1193 * will <b>probably</b> focus this Window, if it is not already focused. On 1194 * platforms where the stacking order does not typically affect the focused 1195 * window, this method will <b>probably</b> leave the focused and active 1196 * Windows unchanged. 1197 * <p> 1198 * If this method causes this Window to be focused, and this Window is a 1199 * Frame or a Dialog, it will also become activated. If this Window is 1200 * focused, but it is not a Frame or a Dialog, then the first Frame or 1201 * Dialog that is an owner of this Window will be activated. 1202 * <p> 1203 * If this window is blocked by modal dialog, then the blocking dialog 1204 * is brought to the front and remains above the blocked window. 1205 * 1206 * @see #toBack 1207 */ 1208 public void toFront() { 1209 toFront_NoClientCode(); 1210 } 1211 1212 // This functionality is implemented in a final package-private method 1213 // to insure that it cannot be overridden by client subclasses. 1214 final void toFront_NoClientCode() { 1215 if (visible) { 1216 WindowPeer peer = (WindowPeer)this.peer; 1217 if (peer != null) { 1218 peer.toFront(); 1219 } 1220 if (isModalBlocked()) { 1221 modalBlocker.toFront_NoClientCode(); 1222 } 1223 } 1224 } 1225 1226 /** 1227 * If this Window is visible, sends this Window to the back and may cause 1228 * it to lose focus or activation if it is the focused or active Window. 1229 * <p> 1230 * Places this Window at the bottom of the stacking order and shows it 1231 * behind any other Windows in this VM. No action will take place is this 1232 * Window is not visible. Some platforms do not allow Windows which are 1233 * owned by other Windows to appear below their owners. Every attempt will 1234 * be made to move this Window as low as possible in the stacking order; 1235 * however, developers should not assume that this method will move this 1236 * Window below all other windows in every situation. 1237 * <p> 1238 * Because of variations in native windowing systems, no guarantees about 1239 * changes to the focused and active Windows can be made. Developers must 1240 * never assume that this Window is no longer the focused or active Window 1241 * until this Window receives a WINDOW_LOST_FOCUS or WINDOW_DEACTIVATED 1242 * event. On platforms where the top-most window is the focused window, 1243 * this method will <b>probably</b> cause this Window to lose focus. In 1244 * that case, the next highest, focusable Window in this VM will receive 1245 * focus. On platforms where the stacking order does not typically affect 1246 * the focused window, this method will <b>probably</b> leave the focused 1247 * and active Windows unchanged. 1248 * 1249 * @see #toFront 1250 */ 1251 public void toBack() { 1252 toBack_NoClientCode(); 1253 } 1254 1255 // This functionality is implemented in a final package-private method 1256 // to insure that it cannot be overridden by client subclasses. 1257 final void toBack_NoClientCode() { 1258 if(isAlwaysOnTop()) { 1259 try { 1260 setAlwaysOnTop(false); 1261 }catch(SecurityException e) { 1262 } 1263 } 1264 if (visible) { 1265 WindowPeer peer = (WindowPeer)this.peer; 1266 if (peer != null) { 1267 peer.toBack(); 1268 } 1269 } 1270 } 1271 1272 /** 1273 * Returns the toolkit of this frame. 1274 * @return the toolkit of this window. 1275 * @see Toolkit 1276 * @see Toolkit#getDefaultToolkit 1277 * @see Component#getToolkit 1278 */ 1279 public Toolkit getToolkit() { 1280 return Toolkit.getDefaultToolkit(); 1281 } 1282 1283 /** 1284 * Gets the warning string that is displayed with this window. 1285 * If this window is insecure, the warning string is displayed 1286 * somewhere in the visible area of the window. A window is 1287 * insecure if there is a security manager, and the security 1288 * manager's <code>checkTopLevelWindow</code> method returns 1289 * <code>false</code> when this window is passed to it as an 1290 * argument. 1291 * <p> 1292 * If the window is secure, then <code>getWarningString</code> 1293 * returns <code>null</code>. If the window is insecure, this 1294 * method checks for the system property 1295 * <code>awt.appletWarning</code> 1296 * and returns the string value of that property. 1297 * @return the warning string for this window. 1298 * @see java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object) 1299 */ 1300 public final String getWarningString() { 1301 return warningString; 1302 } 1303 1304 private void setWarningString() { 1305 warningString = null; 1306 SecurityManager sm = System.getSecurityManager(); 1307 if (sm != null) { 1308 if (!sm.checkTopLevelWindow(this)) { 1309 // make sure the privileged action is only 1310 // for getting the property! We don't want the 1311 // above checkTopLevelWindow call to always succeed! 1312 warningString = (String) AccessController.doPrivileged( 1313 new GetPropertyAction("awt.appletWarning", 1314 "Java Applet Window")); 1315 } 1316 } 1317 } 1318 1319 /** 1320 * Gets the <code>Locale</code> object that is associated 1321 * with this window, if the locale has been set. 1322 * If no locale has been set, then the default locale 1323 * is returned. 1324 * @return the locale that is set for this window. 1325 * @see java.util.Locale 1326 * @since JDK1.1 1327 */ 1328 public Locale getLocale() { 1329 if (this.locale == null) { 1330 return Locale.getDefault(); 1331 } 1332 return this.locale; 1333 } 1334 1335 /** 1336 * Gets the input context for this window. A window always has an input context, 1337 * which is shared by subcomponents unless they create and set their own. 1338 * @see Component#getInputContext 1339 * @since 1.2 1340 */ 1341 public InputContext getInputContext() { 1342 synchronized (inputContextLock) { 1343 if (inputContext == null) { 1344 inputContext = InputContext.getInstance(); 1345 } 1346 } 1347 return inputContext; 1348 } 1349 1350 /** 1351 * Set the cursor image to a specified cursor. 1352 * <p> 1353 * The method may have no visual effect if the Java platform 1354 * implementation and/or the native system do not support 1355 * changing the mouse cursor shape. 1356 * @param cursor One of the constants defined 1357 * by the <code>Cursor</code> class. If this parameter is null 1358 * then the cursor for this window will be set to the type 1359 * Cursor.DEFAULT_CURSOR. 1360 * @see Component#getCursor 1361 * @see Cursor 1362 * @since JDK1.1 1363 */ 1364 public void setCursor(Cursor cursor) { 1365 if (cursor == null) { 1366 cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); 1367 } 1368 super.setCursor(cursor); 1369 } 1370 1371 /** 1372 * Returns the owner of this window. 1373 * @since 1.2 1374 */ 1375 public Window getOwner() { 1376 return getOwner_NoClientCode(); 1377 } 1378 final Window getOwner_NoClientCode() { 1379 return (Window)parent; 1380 } 1381 1382 /** 1383 * Return an array containing all the windows this 1384 * window currently owns. 1385 * @since 1.2 1386 */ 1387 public Window[] getOwnedWindows() { 1388 return getOwnedWindows_NoClientCode(); 1389 } 1390 final Window[] getOwnedWindows_NoClientCode() { 1391 Window realCopy[]; 1392 1393 synchronized(ownedWindowList) { 1394 // Recall that ownedWindowList is actually a Vector of 1395 // WeakReferences and calling get() on one of these references 1396 // may return null. Make two arrays-- one the size of the 1397 // Vector (fullCopy with size fullSize), and one the size of 1398 // all non-null get()s (realCopy with size realSize). 1399 int fullSize = ownedWindowList.size(); 1400 int realSize = 0; 1401 Window fullCopy[] = new Window[fullSize]; 1402 1403 for (int i = 0; i < fullSize; i++) { 1404 fullCopy[realSize] = ownedWindowList.elementAt(i).get(); 1405 1406 if (fullCopy[realSize] != null) { 1407 realSize++; 1408 } 1409 } 1410 1411 if (fullSize != realSize) { 1412 realCopy = Arrays.copyOf(fullCopy, realSize); 1413 } else { 1414 realCopy = fullCopy; 1415 } 1416 } 1417 1418 return realCopy; 1419 } 1420 1421 boolean isModalBlocked() { 1422 return modalBlocker != null; 1423 } 1424 1425 void setModalBlocked(Dialog blocker, boolean blocked, boolean peerCall) { 1426 this.modalBlocker = blocked ? blocker : null; 1427 if (peerCall) { 1428 WindowPeer peer = (WindowPeer)this.peer; 1429 if (peer != null) { 1430 peer.setModalBlocked(blocker, blocked); 1431 } 1432 } 1433 } 1434 1435 Dialog getModalBlocker() { 1436 return modalBlocker; 1437 } 1438 1439 /* 1440 * Returns a list of all displayable Windows, i. e. all the 1441 * Windows which peer is not null. 1442 * 1443 * @see #addNotify 1444 * @see #removeNotify 1445 */ 1446 static IdentityArrayList<Window> getAllWindows() { 1447 synchronized (allWindows) { 1448 IdentityArrayList<Window> v = new IdentityArrayList<Window>(); 1449 v.addAll(allWindows); 1450 return v; 1451 } 1452 } 1453 1454 static IdentityArrayList<Window> getAllUnblockedWindows() { 1455 synchronized (allWindows) { 1456 IdentityArrayList<Window> unblocked = new IdentityArrayList<Window>(); 1457 for (int i = 0; i < allWindows.size(); i++) { 1458 Window w = allWindows.get(i); 1459 if (!w.isModalBlocked()) { 1460 unblocked.add(w); 1461 } 1462 } 1463 return unblocked; 1464 } 1465 } 1466 1467 private static Window[] getWindows(AppContext appContext) { 1468 synchronized (Window.class) { 1469 Window realCopy[]; 1470 Vector<WeakReference<Window>> windowList = 1471 (Vector<WeakReference<Window>>)appContext.get(Window.class); 1472 if (windowList != null) { 1473 int fullSize = windowList.size(); 1474 int realSize = 0; 1475 Window fullCopy[] = new Window[fullSize]; 1476 for (int i = 0; i < fullSize; i++) { 1477 Window w = windowList.get(i).get(); 1478 if (w != null) { 1479 fullCopy[realSize++] = w; 1480 } 1481 } 1482 if (fullSize != realSize) { 1483 realCopy = Arrays.copyOf(fullCopy, realSize); 1484 } else { 1485 realCopy = fullCopy; 1486 } 1487 } else { 1488 realCopy = new Window[0]; 1489 } 1490 return realCopy; 1491 } 1492 } 1493 1494 /** 1495 * Returns an array of all {@code Window}s, both owned and ownerless, 1496 * created by this application. 1497 * If called from an applet, the array includes only the {@code Window}s 1498 * accessible by that applet. 1499 * <p> 1500 * <b>Warning:</b> this method may return system created windows, such 1501 * as a print dialog. Applications should not assume the existence of 1502 * these dialogs, nor should an application assume anything about these 1503 * dialogs such as component positions, <code>LayoutManager</code>s 1504 * or serialization. 1505 * 1506 * @see Frame#getFrames 1507 * @see Window#getOwnerlessWindows 1508 * 1509 * @since 1.6 1510 */ 1511 public static Window[] getWindows() { 1512 return getWindows(AppContext.getAppContext()); 1513 } 1514 1515 /** 1516 * Returns an array of all {@code Window}s created by this application 1517 * that have no owner. They include {@code Frame}s and ownerless 1518 * {@code Dialog}s and {@code Window}s. 1519 * If called from an applet, the array includes only the {@code Window}s 1520 * accessible by that applet. 1521 * <p> 1522 * <b>Warning:</b> this method may return system created windows, such 1523 * as a print dialog. Applications should not assume the existence of 1524 * these dialogs, nor should an application assume anything about these 1525 * dialogs such as component positions, <code>LayoutManager</code>s 1526 * or serialization. 1527 * 1528 * @see Frame#getFrames 1529 * @see Window#getWindows() 1530 * 1531 * @since 1.6 1532 */ 1533 public static Window[] getOwnerlessWindows() { 1534 Window[] allWindows = Window.getWindows(); 1535 1536 int ownerlessCount = 0; 1537 for (Window w : allWindows) { 1538 if (w.getOwner() == null) { 1539 ownerlessCount++; 1540 } 1541 } 1542 1543 Window[] ownerless = new Window[ownerlessCount]; 1544 int c = 0; 1545 for (Window w : allWindows) { 1546 if (w.getOwner() == null) { 1547 ownerless[c++] = w; 1548 } 1549 } 1550 1551 return ownerless; 1552 } 1553 1554 Window getDocumentRoot() { 1555 synchronized (getTreeLock()) { 1556 Window w = this; 1557 while (w.getOwner() != null) { 1558 w = w.getOwner(); 1559 } 1560 return w; 1561 } 1562 } 1563 1564 /** 1565 * Specifies the modal exclusion type for this window. If a window is modal 1566 * excluded, it is not blocked by some modal dialogs. See {@link 1567 * java.awt.Dialog.ModalExclusionType Dialog.ModalExclusionType} for 1568 * possible modal exclusion types. 1569 * <p> 1570 * If the given type is not supported, <code>NO_EXCLUDE</code> is used. 1571 * <p> 1572 * Note: changing the modal exclusion type for a visible window may have no 1573 * effect until it is hidden and then shown again. 1574 * 1575 * @param exclusionType the modal exclusion type for this window; a <code>null</code> 1576 * value is equivivalent to {@link Dialog.ModalExclusionType#NO_EXCLUDE 1577 * NO_EXCLUDE} 1578 * @throws SecurityException if the calling thread does not have permission 1579 * to set the modal exclusion property to the window with the given 1580 * <code>exclusionType</code> 1581 * @see java.awt.Dialog.ModalExclusionType 1582 * @see java.awt.Window#getModalExclusionType 1583 * @see java.awt.Toolkit#isModalExclusionTypeSupported 1584 * 1585 * @since 1.6 1586 */ 1587 public void setModalExclusionType(Dialog.ModalExclusionType exclusionType) { 1588 if (exclusionType == null) { 1589 exclusionType = Dialog.ModalExclusionType.NO_EXCLUDE; 1590 } 1591 if (!Toolkit.getDefaultToolkit().isModalExclusionTypeSupported(exclusionType)) { 1592 exclusionType = Dialog.ModalExclusionType.NO_EXCLUDE; 1593 } 1594 if (modalExclusionType == exclusionType) { 1595 return; 1596 } 1597 if (exclusionType == Dialog.ModalExclusionType.TOOLKIT_EXCLUDE) { 1598 SecurityManager sm = System.getSecurityManager(); 1599 if (sm != null) { 1600 sm.checkPermission(SecurityConstants.TOOLKIT_MODALITY_PERMISSION); 1601 } 1602 } 1603 modalExclusionType = exclusionType; 1604 1605 // if we want on-fly changes, we need to uncomment the lines below 1606 // and override the method in Dialog to use modalShow() instead 1607 // of updateChildrenBlocking() 1608 /* 1609 if (isModalBlocked()) { 1610 modalBlocker.unblockWindow(this); 1611 } 1612 Dialog.checkShouldBeBlocked(this); 1613 updateChildrenBlocking(); 1614 */ 1615 } 1616 1617 /** 1618 * Returns the modal exclusion type of this window. 1619 * 1620 * @return the modal exclusion type of this window 1621 * 1622 * @see java.awt.Dialog.ModalExclusionType 1623 * @see java.awt.Window#setModalExclusionType 1624 * 1625 * @since 1.6 1626 */ 1627 public Dialog.ModalExclusionType getModalExclusionType() { 1628 return modalExclusionType; 1629 } 1630 1631 boolean isModalExcluded(Dialog.ModalExclusionType exclusionType) { 1632 if ((modalExclusionType != null) && 1633 modalExclusionType.compareTo(exclusionType) >= 0) 1634 { 1635 return true; 1636 } 1637 Window owner = getOwner_NoClientCode(); 1638 return (owner != null) && owner.isModalExcluded(exclusionType); 1639 } 1640 1641 void updateChildrenBlocking() { 1642 Vector<Window> childHierarchy = new Vector<Window>(); 1643 Window[] ownedWindows = getOwnedWindows(); 1644 for (int i = 0; i < ownedWindows.length; i++) { 1645 childHierarchy.add(ownedWindows[i]); 1646 } 1647 int k = 0; 1648 while (k < childHierarchy.size()) { 1649 Window w = childHierarchy.get(k); 1650 if (w.isVisible()) { 1651 if (w.isModalBlocked()) { 1652 Dialog blocker = w.getModalBlocker(); 1653 blocker.unblockWindow(w); 1654 } 1655 Dialog.checkShouldBeBlocked(w); 1656 Window[] wOwned = w.getOwnedWindows(); 1657 for (int j = 0; j < wOwned.length; j++) { 1658 childHierarchy.add(wOwned[j]); 1659 } 1660 } 1661 k++; 1662 } 1663 } 1664 1665 /** 1666 * Adds the specified window listener to receive window events from 1667 * this window. 1668 * If l is null, no exception is thrown and no action is performed. 1669 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 1670 * >AWT Threading Issues</a> for details on AWT's threading model. 1671 * 1672 * @param l the window listener 1673 * @see #removeWindowListener 1674 * @see #getWindowListeners 1675 */ 1676 public synchronized void addWindowListener(WindowListener l) { 1677 if (l == null) { 1678 return; 1679 } 1680 newEventsOnly = true; 1681 windowListener = AWTEventMulticaster.add(windowListener, l); 1682 } 1683 1684 /** 1685 * Adds the specified window state listener to receive window 1686 * events from this window. If <code>l</code> is <code>null</code>, 1687 * no exception is thrown and no action is performed. 1688 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 1689 * >AWT Threading Issues</a> for details on AWT's threading model. 1690 * 1691 * @param l the window state listener 1692 * @see #removeWindowStateListener 1693 * @see #getWindowStateListeners 1694 * @since 1.4 1695 */ 1696 public synchronized void addWindowStateListener(WindowStateListener l) { 1697 if (l == null) { 1698 return; 1699 } 1700 windowStateListener = AWTEventMulticaster.add(windowStateListener, l); 1701 newEventsOnly = true; 1702 } 1703 1704 /** 1705 * Adds the specified window focus listener to receive window events 1706 * from this window. 1707 * If l is null, no exception is thrown and no action is performed. 1708 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 1709 * >AWT Threading Issues</a> for details on AWT's threading model. 1710 * 1711 * @param l the window focus listener 1712 * @see #removeWindowFocusListener 1713 * @see #getWindowFocusListeners 1714 * @since 1.4 1715 */ 1716 public synchronized void addWindowFocusListener(WindowFocusListener l) { 1717 if (l == null) { 1718 return; 1719 } 1720 windowFocusListener = AWTEventMulticaster.add(windowFocusListener, l); 1721 newEventsOnly = true; 1722 } 1723 1724 /** 1725 * Removes the specified window listener so that it no longer 1726 * receives window events from this window. 1727 * If l is null, no exception is thrown and no action is performed. 1728 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 1729 * >AWT Threading Issues</a> for details on AWT's threading model. 1730 * 1731 * @param l the window listener 1732 * @see #addWindowListener 1733 * @see #getWindowListeners 1734 */ 1735 public synchronized void removeWindowListener(WindowListener l) { 1736 if (l == null) { 1737 return; 1738 } 1739 windowListener = AWTEventMulticaster.remove(windowListener, l); 1740 } 1741 1742 /** 1743 * Removes the specified window state listener so that it no 1744 * longer receives window events from this window. If 1745 * <code>l</code> is <code>null</code>, no exception is thrown and 1746 * no action is performed. 1747 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 1748 * >AWT Threading Issues</a> for details on AWT's threading model. 1749 * 1750 * @param l the window state listener 1751 * @see #addWindowStateListener 1752 * @see #getWindowStateListeners 1753 * @since 1.4 1754 */ 1755 public synchronized void removeWindowStateListener(WindowStateListener l) { 1756 if (l == null) { 1757 return; 1758 } 1759 windowStateListener = AWTEventMulticaster.remove(windowStateListener, l); 1760 } 1761 1762 /** 1763 * Removes the specified window focus listener so that it no longer 1764 * receives window events from this window. 1765 * If l is null, no exception is thrown and no action is performed. 1766 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 1767 * >AWT Threading Issues</a> for details on AWT's threading model. 1768 * 1769 * @param l the window focus listener 1770 * @see #addWindowFocusListener 1771 * @see #getWindowFocusListeners 1772 * @since 1.4 1773 */ 1774 public synchronized void removeWindowFocusListener(WindowFocusListener l) { 1775 if (l == null) { 1776 return; 1777 } 1778 windowFocusListener = AWTEventMulticaster.remove(windowFocusListener, l); 1779 } 1780 1781 /** 1782 * Returns an array of all the window listeners 1783 * registered on this window. 1784 * 1785 * @return all of this window's <code>WindowListener</code>s 1786 * or an empty array if no window 1787 * listeners are currently registered 1788 * 1789 * @see #addWindowListener 1790 * @see #removeWindowListener 1791 * @since 1.4 1792 */ 1793 public synchronized WindowListener[] getWindowListeners() { 1794 return (WindowListener[])(getListeners(WindowListener.class)); 1795 } 1796 1797 /** 1798 * Returns an array of all the window focus listeners 1799 * registered on this window. 1800 * 1801 * @return all of this window's <code>WindowFocusListener</code>s 1802 * or an empty array if no window focus 1803 * listeners are currently registered 1804 * 1805 * @see #addWindowFocusListener 1806 * @see #removeWindowFocusListener 1807 * @since 1.4 1808 */ 1809 public synchronized WindowFocusListener[] getWindowFocusListeners() { 1810 return (WindowFocusListener[])(getListeners(WindowFocusListener.class)); 1811 } 1812 1813 /** 1814 * Returns an array of all the window state listeners 1815 * registered on this window. 1816 * 1817 * @return all of this window's <code>WindowStateListener</code>s 1818 * or an empty array if no window state 1819 * listeners are currently registered 1820 * 1821 * @see #addWindowStateListener 1822 * @see #removeWindowStateListener 1823 * @since 1.4 1824 */ 1825 public synchronized WindowStateListener[] getWindowStateListeners() { 1826 return (WindowStateListener[])(getListeners(WindowStateListener.class)); 1827 } 1828 1829 1830 /** 1831 * Returns an array of all the objects currently registered 1832 * as <code><em>Foo</em>Listener</code>s 1833 * upon this <code>Window</code>. 1834 * <code><em>Foo</em>Listener</code>s are registered using the 1835 * <code>add<em>Foo</em>Listener</code> method. 1836 * 1837 * <p> 1838 * 1839 * You can specify the <code>listenerType</code> argument 1840 * with a class literal, such as 1841 * <code><em>Foo</em>Listener.class</code>. 1842 * For example, you can query a 1843 * <code>Window</code> <code>w</code> 1844 * for its window listeners with the following code: 1845 * 1846 * <pre>WindowListener[] wls = (WindowListener[])(w.getListeners(WindowListener.class));</pre> 1847 * 1848 * If no such listeners exist, this method returns an empty array. 1849 * 1850 * @param listenerType the type of listeners requested; this parameter 1851 * should specify an interface that descends from 1852 * <code>java.util.EventListener</code> 1853 * @return an array of all objects registered as 1854 * <code><em>Foo</em>Listener</code>s on this window, 1855 * or an empty array if no such 1856 * listeners have been added 1857 * @exception ClassCastException if <code>listenerType</code> 1858 * doesn't specify a class or interface that implements 1859 * <code>java.util.EventListener</code> 1860 * 1861 * @see #getWindowListeners 1862 * @since 1.3 1863 */ 1864 public <T extends EventListener> T[] getListeners(Class<T> listenerType) { 1865 EventListener l = null; 1866 if (listenerType == WindowFocusListener.class) { 1867 l = windowFocusListener; 1868 } else if (listenerType == WindowStateListener.class) { 1869 l = windowStateListener; 1870 } else if (listenerType == WindowListener.class) { 1871 l = windowListener; 1872 } else { 1873 return super.getListeners(listenerType); 1874 } 1875 return AWTEventMulticaster.getListeners(l, listenerType); 1876 } 1877 1878 // REMIND: remove when filtering is handled at lower level 1879 boolean eventEnabled(AWTEvent e) { 1880 switch(e.id) { 1881 case WindowEvent.WINDOW_OPENED: 1882 case WindowEvent.WINDOW_CLOSING: 1883 case WindowEvent.WINDOW_CLOSED: 1884 case WindowEvent.WINDOW_ICONIFIED: 1885 case WindowEvent.WINDOW_DEICONIFIED: 1886 case WindowEvent.WINDOW_ACTIVATED: 1887 case WindowEvent.WINDOW_DEACTIVATED: 1888 if ((eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0 || 1889 windowListener != null) { 1890 return true; 1891 } 1892 return false; 1893 case WindowEvent.WINDOW_GAINED_FOCUS: 1894 case WindowEvent.WINDOW_LOST_FOCUS: 1895 if ((eventMask & AWTEvent.WINDOW_FOCUS_EVENT_MASK) != 0 || 1896 windowFocusListener != null) { 1897 return true; 1898 } 1899 return false; 1900 case WindowEvent.WINDOW_STATE_CHANGED: 1901 if ((eventMask & AWTEvent.WINDOW_STATE_EVENT_MASK) != 0 || 1902 windowStateListener != null) { 1903 return true; 1904 } 1905 return false; 1906 default: 1907 break; 1908 } 1909 return super.eventEnabled(e); 1910 } 1911 1912 /** 1913 * Processes events on this window. If the event is an 1914 * <code>WindowEvent</code>, it invokes the 1915 * <code>processWindowEvent</code> method, else it invokes its 1916 * superclass's <code>processEvent</code>. 1917 * <p>Note that if the event parameter is <code>null</code> 1918 * the behavior is unspecified and may result in an 1919 * exception. 1920 * 1921 * @param e the event 1922 */ 1923 protected void processEvent(AWTEvent e) { 1924 if (e instanceof WindowEvent) { 1925 switch (e.getID()) { 1926 case WindowEvent.WINDOW_OPENED: 1927 case WindowEvent.WINDOW_CLOSING: 1928 case WindowEvent.WINDOW_CLOSED: 1929 case WindowEvent.WINDOW_ICONIFIED: 1930 case WindowEvent.WINDOW_DEICONIFIED: 1931 case WindowEvent.WINDOW_ACTIVATED: 1932 case WindowEvent.WINDOW_DEACTIVATED: 1933 processWindowEvent((WindowEvent)e); 1934 break; 1935 case WindowEvent.WINDOW_GAINED_FOCUS: 1936 case WindowEvent.WINDOW_LOST_FOCUS: 1937 processWindowFocusEvent((WindowEvent)e); 1938 break; 1939 case WindowEvent.WINDOW_STATE_CHANGED: 1940 processWindowStateEvent((WindowEvent)e); 1941 default: 1942 break; 1943 } 1944 return; 1945 } 1946 super.processEvent(e); 1947 } 1948 1949 /** 1950 * Processes window events occurring on this window by 1951 * dispatching them to any registered WindowListener objects. 1952 * NOTE: This method will not be called unless window events 1953 * are enabled for this component; this happens when one of the 1954 * following occurs: 1955 * <ul> 1956 * <li>A WindowListener object is registered via 1957 * <code>addWindowListener</code> 1958 * <li>Window events are enabled via <code>enableEvents</code> 1959 * </ul> 1960 * <p>Note that if the event parameter is <code>null</code> 1961 * the behavior is unspecified and may result in an 1962 * exception. 1963 * 1964 * @param e the window event 1965 * @see Component#enableEvents 1966 */ 1967 protected void processWindowEvent(WindowEvent e) { 1968 WindowListener listener = windowListener; 1969 if (listener != null) { 1970 switch(e.getID()) { 1971 case WindowEvent.WINDOW_OPENED: 1972 listener.windowOpened(e); 1973 break; 1974 case WindowEvent.WINDOW_CLOSING: 1975 listener.windowClosing(e); 1976 break; 1977 case WindowEvent.WINDOW_CLOSED: 1978 listener.windowClosed(e); 1979 break; 1980 case WindowEvent.WINDOW_ICONIFIED: 1981 listener.windowIconified(e); 1982 break; 1983 case WindowEvent.WINDOW_DEICONIFIED: 1984 listener.windowDeiconified(e); 1985 break; 1986 case WindowEvent.WINDOW_ACTIVATED: 1987 listener.windowActivated(e); 1988 break; 1989 case WindowEvent.WINDOW_DEACTIVATED: 1990 listener.windowDeactivated(e); 1991 break; 1992 default: 1993 break; 1994 } 1995 } 1996 } 1997 1998 /** 1999 * Processes window focus event occuring on this window by 2000 * dispatching them to any registered WindowFocusListener objects. 2001 * NOTE: this method will not be called unless window focus events 2002 * are enabled for this window. This happens when one of the 2003 * following occurs: 2004 * <ul> 2005 * <li>a WindowFocusListener is registered via 2006 * <code>addWindowFocusListener</code> 2007 * <li>Window focus events are enabled via <code>enableEvents</code> 2008 * </ul> 2009 * <p>Note that if the event parameter is <code>null</code> 2010 * the behavior is unspecified and may result in an 2011 * exception. 2012 * 2013 * @param e the window focus event 2014 * @see Component#enableEvents 2015 * @since 1.4 2016 */ 2017 protected void processWindowFocusEvent(WindowEvent e) { 2018 WindowFocusListener listener = windowFocusListener; 2019 if (listener != null) { 2020 switch (e.getID()) { 2021 case WindowEvent.WINDOW_GAINED_FOCUS: 2022 listener.windowGainedFocus(e); 2023 break; 2024 case WindowEvent.WINDOW_LOST_FOCUS: 2025 listener.windowLostFocus(e); 2026 break; 2027 default: 2028 break; 2029 } 2030 } 2031 } 2032 2033 /** 2034 * Processes window state event occuring on this window by 2035 * dispatching them to any registered <code>WindowStateListener</code> 2036 * objects. 2037 * NOTE: this method will not be called unless window state events 2038 * are enabled for this window. This happens when one of the 2039 * following occurs: 2040 * <ul> 2041 * <li>a <code>WindowStateListener</code> is registered via 2042 * <code>addWindowStateListener</code> 2043 * <li>window state events are enabled via <code>enableEvents</code> 2044 * </ul> 2045 * <p>Note that if the event parameter is <code>null</code> 2046 * the behavior is unspecified and may result in an 2047 * exception. 2048 * 2049 * @param e the window state event 2050 * @see java.awt.Component#enableEvents 2051 * @since 1.4 2052 */ 2053 protected void processWindowStateEvent(WindowEvent e) { 2054 WindowStateListener listener = windowStateListener; 2055 if (listener != null) { 2056 switch (e.getID()) { 2057 case WindowEvent.WINDOW_STATE_CHANGED: 2058 listener.windowStateChanged(e); 2059 break; 2060 default: 2061 break; 2062 } 2063 } 2064 } 2065 2066 /** 2067 * Implements a debugging hook -- checks to see if 2068 * the user has typed <i>control-shift-F1</i>. If so, 2069 * the list of child windows is dumped to <code>System.out</code>. 2070 * @param e the keyboard event 2071 */ 2072 void preProcessKeyEvent(KeyEvent e) { 2073 // Dump the list of child windows to System.out. 2074 if (e.isActionKey() && e.getKeyCode() == KeyEvent.VK_F1 && 2075 e.isControlDown() && e.isShiftDown() && 2076 e.getID() == KeyEvent.KEY_PRESSED) { 2077 list(System.out, 0); 2078 } 2079 } 2080 2081 void postProcessKeyEvent(KeyEvent e) { 2082 // Do nothing 2083 } 2084 2085 2086 /** 2087 * Sets whether this window should always be above other windows. If 2088 * there are multiple always-on-top windows, their relative order is 2089 * unspecified and platform dependent. 2090 * <p> 2091 * If some other window is already always-on-top then the 2092 * relative order between these windows is unspecified (depends on 2093 * platform). No window can be brought to be over the always-on-top 2094 * window except maybe another always-on-top window. 2095 * <p> 2096 * All windows owned by an always-on-top window inherit this state and 2097 * automatically become always-on-top. If a window ceases to be 2098 * always-on-top, the windows that it owns will no longer be 2099 * always-on-top. When an always-on-top window is sent {@link #toBack 2100 * toBack}, its always-on-top state is set to <code>false</code>. 2101 * 2102 * <p> When this method is called on a window with a value of 2103 * <code>true</code>, and the window is visible and the platform 2104 * supports always-on-top for this window, the window is immediately 2105 * brought forward, "sticking" it in the top-most position. If the 2106 * window isn`t currently visible, this method sets the always-on-top 2107 * state to <code>true</code> but does not bring the window forward. 2108 * When the window is later shown, it will be always-on-top. 2109 * 2110 * <p> When this method is called on a window with a value of 2111 * <code>false</code> the always-on-top state is set to normal. The 2112 * window remains in the top-most position but it`s z-order can be 2113 * changed as for any other window. Calling this method with a value 2114 * of <code>false</code> on a window that has a normal state has no 2115 * effect. Setting the always-on-top state to false has no effect on 2116 * the relative z-order of the windows if there are no other 2117 * always-on-top windows. 2118 * 2119 * <p><b>Note</b>: some platforms might not support always-on-top 2120 * windows. To detect if always-on-top windows are supported by the 2121 * current platform, use {@link Toolkit#isAlwaysOnTopSupported()} and 2122 * {@link Window#isAlwaysOnTopSupported()}. If always-on-top mode 2123 * isn't supported by the toolkit or for this window, calling this 2124 * method has no effect. 2125 * <p> 2126 * If a SecurityManager is installed, the calling thread must be 2127 * granted the AWTPermission "setWindowAlwaysOnTop" in 2128 * order to set the value of this property. If this 2129 * permission is not granted, this method will throw a 2130 * SecurityException, and the current value of the property will 2131 * be left unchanged. 2132 * 2133 * @param alwaysOnTop true if the window should always be above other 2134 * windows 2135 * @throws SecurityException if the calling thread does not have 2136 * permission to set the value of always-on-top property 2137 * @see #isAlwaysOnTop 2138 * @see #toFront 2139 * @see #toBack 2140 * @see AWTPermission 2141 * @see #isAlwaysOnTopSupported 2142 * @see Toolkit#isAlwaysOnTopSupported 2143 * @since 1.5 2144 */ 2145 public final void setAlwaysOnTop(boolean alwaysOnTop) throws SecurityException { 2146 SecurityManager security = System.getSecurityManager(); 2147 if (security != null) { 2148 security.checkPermission(SecurityConstants.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION); 2149 } 2150 2151 boolean oldAlwaysOnTop; 2152 synchronized(this) { 2153 oldAlwaysOnTop = this.alwaysOnTop; 2154 this.alwaysOnTop = alwaysOnTop; 2155 } 2156 if (oldAlwaysOnTop != alwaysOnTop ) { 2157 if (isAlwaysOnTopSupported()) { 2158 WindowPeer peer = (WindowPeer)this.peer; 2159 synchronized(getTreeLock()) { 2160 if (peer != null) { 2161 peer.updateAlwaysOnTopState(); 2162 } 2163 } 2164 } 2165 firePropertyChange("alwaysOnTop", oldAlwaysOnTop, alwaysOnTop); 2166 } 2167 } 2168 2169 /** 2170 * Returns whether the always-on-top mode is supported for this 2171 * window. Some platforms may not support always-on-top windows, some 2172 * may support only some kinds of top-level windows; for example, 2173 * a platform may not support always-on-top modal dialogs. 2174 * @return <code>true</code>, if the always-on-top mode is 2175 * supported by the toolkit and for this window, 2176 * <code>false</code>, if always-on-top mode is not supported 2177 * for this window or toolkit doesn't support always-on-top windows. 2178 * @see #setAlwaysOnTop(boolean) 2179 * @see Toolkit#isAlwaysOnTopSupported 2180 * @since 1.6 2181 */ 2182 public boolean isAlwaysOnTopSupported() { 2183 return Toolkit.getDefaultToolkit().isAlwaysOnTopSupported(); 2184 } 2185 2186 2187 /** 2188 * Returns whether this window is an always-on-top window. 2189 * @return <code>true</code>, if the window is in always-on-top state, 2190 * <code>false</code> otherwise 2191 * @see #setAlwaysOnTop 2192 * @since 1.5 2193 */ 2194 public final boolean isAlwaysOnTop() { 2195 return alwaysOnTop; 2196 } 2197 2198 2199 /** 2200 * Returns the child Component of this Window that has focus if this Window 2201 * is focused; returns null otherwise. 2202 * 2203 * @return the child Component with focus, or null if this Window is not 2204 * focused 2205 * @see #getMostRecentFocusOwner 2206 * @see #isFocused 2207 */ 2208 public Component getFocusOwner() { 2209 return (isFocused()) 2210 ? KeyboardFocusManager.getCurrentKeyboardFocusManager(). 2211 getFocusOwner() 2212 : null; 2213 } 2214 2215 /** 2216 * Returns the child Component of this Window that will receive the focus 2217 * when this Window is focused. If this Window is currently focused, this 2218 * method returns the same Component as <code>getFocusOwner()</code>. If 2219 * this Window is not focused, then the child Component that most recently 2220 * requested focus will be returned. If no child Component has ever 2221 * requested focus, and this is a focusable Window, then this Window's 2222 * initial focusable Component is returned. If no child Component has ever 2223 * requested focus, and this is a non-focusable Window, null is returned. 2224 * 2225 * @return the child Component that will receive focus when this Window is 2226 * focused 2227 * @see #getFocusOwner 2228 * @see #isFocused 2229 * @see #isFocusableWindow 2230 * @since 1.4 2231 */ 2232 public Component getMostRecentFocusOwner() { 2233 if (isFocused()) { 2234 return getFocusOwner(); 2235 } else { 2236 Component mostRecent = 2237 KeyboardFocusManager.getMostRecentFocusOwner(this); 2238 if (mostRecent != null) { 2239 return mostRecent; 2240 } else { 2241 return (isFocusableWindow()) 2242 ? getFocusTraversalPolicy().getInitialComponent(this) 2243 : null; 2244 } 2245 } 2246 } 2247 2248 /** 2249 * Returns whether this Window is active. Only a Frame or a Dialog may be 2250 * active. The native windowing system may denote the active Window or its 2251 * children with special decorations, such as a highlighted title bar. The 2252 * active Window is always either the focused Window, or the first Frame or 2253 * Dialog that is an owner of the focused Window. 2254 * 2255 * @return whether this is the active Window. 2256 * @see #isFocused 2257 * @since 1.4 2258 */ 2259 public boolean isActive() { 2260 return (KeyboardFocusManager.getCurrentKeyboardFocusManager(). 2261 getActiveWindow() == this); 2262 } 2263 2264 /** 2265 * Returns whether this Window is focused. If there exists a focus owner, 2266 * the focused Window is the Window that is, or contains, that focus owner. 2267 * If there is no focus owner, then no Window is focused. 2268 * <p> 2269 * If the focused Window is a Frame or a Dialog it is also the active 2270 * Window. Otherwise, the active Window is the first Frame or Dialog that 2271 * is an owner of the focused Window. 2272 * 2273 * @return whether this is the focused Window. 2274 * @see #isActive 2275 * @since 1.4 2276 */ 2277 public boolean isFocused() { 2278 return (KeyboardFocusManager.getCurrentKeyboardFocusManager(). 2279 getGlobalFocusedWindow() == this); 2280 } 2281 2282 /** 2283 * Gets a focus traversal key for this Window. (See <code> 2284 * setFocusTraversalKeys</code> for a full description of each key.) 2285 * <p> 2286 * If the traversal key has not been explicitly set for this Window, 2287 * then this Window's parent's traversal key is returned. If the 2288 * traversal key has not been explicitly set for any of this Window's 2289 * ancestors, then the current KeyboardFocusManager's default traversal key 2290 * is returned. 2291 * 2292 * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, 2293 * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, 2294 * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or 2295 * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS 2296 * @return the AWTKeyStroke for the specified key 2297 * @see Container#setFocusTraversalKeys 2298 * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS 2299 * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS 2300 * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS 2301 * @see KeyboardFocusManager#DOWN_CYCLE_TRAVERSAL_KEYS 2302 * @throws IllegalArgumentException if id is not one of 2303 * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, 2304 * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, 2305 * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or 2306 * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS 2307 * @since 1.4 2308 */ 2309 public Set<AWTKeyStroke> getFocusTraversalKeys(int id) { 2310 if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) { 2311 throw new IllegalArgumentException("invalid focus traversal key identifier"); 2312 } 2313 2314 // Okay to return Set directly because it is an unmodifiable view 2315 Set keystrokes = (focusTraversalKeys != null) 2316 ? focusTraversalKeys[id] 2317 : null; 2318 2319 if (keystrokes != null) { 2320 return keystrokes; 2321 } else { 2322 return KeyboardFocusManager.getCurrentKeyboardFocusManager(). 2323 getDefaultFocusTraversalKeys(id); 2324 } 2325 } 2326 2327 /** 2328 * Does nothing because Windows must always be roots of a focus traversal 2329 * cycle. The passed-in value is ignored. 2330 * 2331 * @param focusCycleRoot this value is ignored 2332 * @see #isFocusCycleRoot 2333 * @see Container#setFocusTraversalPolicy 2334 * @see Container#getFocusTraversalPolicy 2335 * @since 1.4 2336 */ 2337 public final void setFocusCycleRoot(boolean focusCycleRoot) { 2338 } 2339 2340 /** 2341 * Always returns <code>true</code> because all Windows must be roots of a 2342 * focus traversal cycle. 2343 * 2344 * @return <code>true</code> 2345 * @see #setFocusCycleRoot 2346 * @see Container#setFocusTraversalPolicy 2347 * @see Container#getFocusTraversalPolicy 2348 * @since 1.4 2349 */ 2350 public final boolean isFocusCycleRoot() { 2351 return true; 2352 } 2353 2354 /** 2355 * Always returns <code>null</code> because Windows have no ancestors; they 2356 * represent the top of the Component hierarchy. 2357 * 2358 * @return <code>null</code> 2359 * @see Container#isFocusCycleRoot() 2360 * @since 1.4 2361 */ 2362 public final Container getFocusCycleRootAncestor() { 2363 return null; 2364 } 2365 2366 /** 2367 * Returns whether this Window can become the focused Window, that is, 2368 * whether this Window or any of its subcomponents can become the focus 2369 * owner. For a Frame or Dialog to be focusable, its focusable Window state 2370 * must be set to <code>true</code>. For a Window which is not a Frame or 2371 * Dialog to be focusable, its focusable Window state must be set to 2372 * <code>true</code>, its nearest owning Frame or Dialog must be 2373 * showing on the screen, and it must contain at least one Component in 2374 * its focus traversal cycle. If any of these conditions is not met, then 2375 * neither this Window nor any of its subcomponents can become the focus 2376 * owner. 2377 * 2378 * @return <code>true</code> if this Window can be the focused Window; 2379 * <code>false</code> otherwise 2380 * @see #getFocusableWindowState 2381 * @see #setFocusableWindowState 2382 * @see #isShowing 2383 * @see Component#isFocusable 2384 * @since 1.4 2385 */ 2386 public final boolean isFocusableWindow() { 2387 // If a Window/Frame/Dialog was made non-focusable, then it is always 2388 // non-focusable. 2389 if (!getFocusableWindowState()) { 2390 return false; 2391 } 2392 2393 // All other tests apply only to Windows. 2394 if (this instanceof Frame || this instanceof Dialog) { 2395 return true; 2396 } 2397 2398 // A Window must have at least one Component in its root focus 2399 // traversal cycle to be focusable. 2400 if (getFocusTraversalPolicy().getDefaultComponent(this) == null) { 2401 return false; 2402 } 2403 2404 // A Window's nearest owning Frame or Dialog must be showing on the 2405 // screen. 2406 for (Window owner = getOwner(); owner != null; 2407 owner = owner.getOwner()) 2408 { 2409 if (owner instanceof Frame || owner instanceof Dialog) { 2410 return owner.isShowing(); 2411 } 2412 } 2413 2414 return false; 2415 } 2416 2417 /** 2418 * Returns whether this Window can become the focused Window if it meets 2419 * the other requirements outlined in <code>isFocusableWindow</code>. If 2420 * this method returns <code>false</code>, then 2421 * <code>isFocusableWindow</code> will return <code>false</code> as well. 2422 * If this method returns <code>true</code>, then 2423 * <code>isFocusableWindow</code> may return <code>true</code> or 2424 * <code>false</code> depending upon the other requirements which must be 2425 * met in order for a Window to be focusable. 2426 * <p> 2427 * By default, all Windows have a focusable Window state of 2428 * <code>true</code>. 2429 * 2430 * @return whether this Window can be the focused Window 2431 * @see #isFocusableWindow 2432 * @see #setFocusableWindowState 2433 * @see #isShowing 2434 * @see Component#setFocusable 2435 * @since 1.4 2436 */ 2437 public boolean getFocusableWindowState() { 2438 return focusableWindowState; 2439 } 2440 2441 /** 2442 * Sets whether this Window can become the focused Window if it meets 2443 * the other requirements outlined in <code>isFocusableWindow</code>. If 2444 * this Window's focusable Window state is set to <code>false</code>, then 2445 * <code>isFocusableWindow</code> will return <code>false</code>. If this 2446 * Window's focusable Window state is set to <code>true</code>, then 2447 * <code>isFocusableWindow</code> may return <code>true</code> or 2448 * <code>false</code> depending upon the other requirements which must be 2449 * met in order for a Window to be focusable. 2450 * <p> 2451 * Setting a Window's focusability state to <code>false</code> is the 2452 * standard mechanism for an application to identify to the AWT a Window 2453 * which will be used as a floating palette or toolbar, and thus should be 2454 * a non-focusable Window. 2455 * 2456 * Setting the focusability state on a visible <code>Window</code> 2457 * can have a delayed effect on some platforms the actual 2458 * change may happen only when the <code>Window</code> becomes 2459 * hidden and then visible again. To ensure consistent behavior 2460 * across platforms, set the <code>Window</code>'s focusable state 2461 * when the <code>Window</code> is invisible and then show it. 2462 * 2463 * @param focusableWindowState whether this Window can be the focused 2464 * Window 2465 * @see #isFocusableWindow 2466 * @see #getFocusableWindowState 2467 * @see #isShowing 2468 * @see Component#setFocusable 2469 * @since 1.4 2470 */ 2471 public void setFocusableWindowState(boolean focusableWindowState) { 2472 boolean oldFocusableWindowState; 2473 synchronized (this) { 2474 oldFocusableWindowState = this.focusableWindowState; 2475 this.focusableWindowState = focusableWindowState; 2476 } 2477 WindowPeer peer = (WindowPeer)this.peer; 2478 if (peer != null) { 2479 peer.updateFocusableWindowState(); 2480 } 2481 firePropertyChange("focusableWindowState", oldFocusableWindowState, 2482 focusableWindowState); 2483 if (oldFocusableWindowState && !focusableWindowState && isFocused()) { 2484 for (Window owner = getOwner(); 2485 owner != null; 2486 owner = owner.getOwner()) 2487 { 2488 Component toFocus = 2489 KeyboardFocusManager.getMostRecentFocusOwner(owner); 2490 if (toFocus != null && toFocus.requestFocus(false, CausedFocusEvent.Cause.ACTIVATION)) { 2491 return; 2492 } 2493 } 2494 KeyboardFocusManager.getCurrentKeyboardFocusManager(). 2495 clearGlobalFocusOwner(); 2496 } 2497 } 2498 2499 /** 2500 * Adds a PropertyChangeListener to the listener list. The listener is 2501 * registered for all bound properties of this class, including the 2502 * following: 2503 * <ul> 2504 * <li>this Window's font ("font")</li> 2505 * <li>this Window's background color ("background")</li> 2506 * <li>this Window's foreground color ("foreground")</li> 2507 * <li>this Window's focusability ("focusable")</li> 2508 * <li>this Window's focus traversal keys enabled state 2509 * ("focusTraversalKeysEnabled")</li> 2510 * <li>this Window's Set of FORWARD_TRAVERSAL_KEYS 2511 * ("forwardFocusTraversalKeys")</li> 2512 * <li>this Window's Set of BACKWARD_TRAVERSAL_KEYS 2513 * ("backwardFocusTraversalKeys")</li> 2514 * <li>this Window's Set of UP_CYCLE_TRAVERSAL_KEYS 2515 * ("upCycleFocusTraversalKeys")</li> 2516 * <li>this Window's Set of DOWN_CYCLE_TRAVERSAL_KEYS 2517 * ("downCycleFocusTraversalKeys")</li> 2518 * <li>this Window's focus traversal policy ("focusTraversalPolicy") 2519 * </li> 2520 * <li>this Window's focusable Window state ("focusableWindowState") 2521 * </li> 2522 * <li>this Window's always-on-top state("alwaysOnTop")</li> 2523 * </ul> 2524 * Note that if this Window is inheriting a bound property, then no 2525 * event will be fired in response to a change in the inherited property. 2526 * <p> 2527 * If listener is null, no exception is thrown and no action is performed. 2528 * 2529 * @param listener the PropertyChangeListener to be added 2530 * 2531 * @see Component#removePropertyChangeListener 2532 * @see #addPropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener) 2533 */ 2534 public void addPropertyChangeListener(PropertyChangeListener listener) { 2535 super.addPropertyChangeListener(listener); 2536 } 2537 2538 /** 2539 * Adds a PropertyChangeListener to the listener list for a specific 2540 * property. The specified property may be user-defined, or one of the 2541 * following: 2542 * <ul> 2543 * <li>this Window's font ("font")</li> 2544 * <li>this Window's background color ("background")</li> 2545 * <li>this Window's foreground color ("foreground")</li> 2546 * <li>this Window's focusability ("focusable")</li> 2547 * <li>this Window's focus traversal keys enabled state 2548 * ("focusTraversalKeysEnabled")</li> 2549 * <li>this Window's Set of FORWARD_TRAVERSAL_KEYS 2550 * ("forwardFocusTraversalKeys")</li> 2551 * <li>this Window's Set of BACKWARD_TRAVERSAL_KEYS 2552 * ("backwardFocusTraversalKeys")</li> 2553 * <li>this Window's Set of UP_CYCLE_TRAVERSAL_KEYS 2554 * ("upCycleFocusTraversalKeys")</li> 2555 * <li>this Window's Set of DOWN_CYCLE_TRAVERSAL_KEYS 2556 * ("downCycleFocusTraversalKeys")</li> 2557 * <li>this Window's focus traversal policy ("focusTraversalPolicy") 2558 * </li> 2559 * <li>this Window's focusable Window state ("focusableWindowState") 2560 * </li> 2561 * <li>this Window's always-on-top state("alwaysOnTop")</li> 2562 * </ul> 2563 * Note that if this Window is inheriting a bound property, then no 2564 * event will be fired in response to a change in the inherited property. 2565 * <p> 2566 * If listener is null, no exception is thrown and no action is performed. 2567 * 2568 * @param propertyName one of the property names listed above 2569 * @param listener the PropertyChangeListener to be added 2570 * 2571 * @see #addPropertyChangeListener(java.beans.PropertyChangeListener) 2572 * @see Component#removePropertyChangeListener 2573 */ 2574 public void addPropertyChangeListener(String propertyName, 2575 PropertyChangeListener listener) { 2576 super.addPropertyChangeListener(propertyName, listener); 2577 } 2578 2579 /** 2580 * Dispatches an event to this window or one of its sub components. 2581 * @param e the event 2582 */ 2583 void dispatchEventImpl(AWTEvent e) { 2584 if (e.getID() == ComponentEvent.COMPONENT_RESIZED) { 2585 invalidate(); 2586 validate(); 2587 } 2588 super.dispatchEventImpl(e); 2589 } 2590 2591 /** 2592 * @deprecated As of JDK version 1.1 2593 * replaced by <code>dispatchEvent(AWTEvent)</code>. 2594 */ 2595 @Deprecated 2596 public boolean postEvent(Event e) { 2597 if (handleEvent(e)) { 2598 e.consume(); 2599 return true; 2600 } 2601 return false; 2602 } 2603 2604 /** 2605 * Checks if this Window is showing on screen. 2606 * @see Component#setVisible 2607 */ 2608 public boolean isShowing() { 2609 return visible; 2610 } 2611 2612 /** 2613 * @deprecated As of J2SE 1.4, replaced by 2614 * {@link Component#applyComponentOrientation Component.applyComponentOrientation}. 2615 */ 2616 @Deprecated 2617 public void applyResourceBundle(ResourceBundle rb) { 2618 applyComponentOrientation(ComponentOrientation.getOrientation(rb)); 2619 } 2620 2621 /** 2622 * @deprecated As of J2SE 1.4, replaced by 2623 * {@link Component#applyComponentOrientation Component.applyComponentOrientation}. 2624 */ 2625 @Deprecated 2626 public void applyResourceBundle(String rbName) { 2627 applyResourceBundle(ResourceBundle.getBundle(rbName)); 2628 } 2629 2630 /* 2631 * Support for tracking all windows owned by this window 2632 */ 2633 void addOwnedWindow(WeakReference weakWindow) { 2634 if (weakWindow != null) { 2635 synchronized(ownedWindowList) { 2636 // this if statement should really be an assert, but we don't 2637 // have asserts... 2638 if (!ownedWindowList.contains(weakWindow)) { 2639 ownedWindowList.addElement(weakWindow); 2640 } 2641 } 2642 } 2643 } 2644 2645 void removeOwnedWindow(WeakReference weakWindow) { 2646 if (weakWindow != null) { 2647 // synchronized block not required since removeElement is 2648 // already synchronized 2649 ownedWindowList.removeElement(weakWindow); 2650 } 2651 } 2652 2653 void connectOwnedWindow(Window child) { 2654 child.parent = this; 2655 addOwnedWindow(child.weakThis); 2656 } 2657 2658 private void addToWindowList() { 2659 synchronized (Window.class) { 2660 Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>)appContext.get(Window.class); 2661 if (windowList == null) { 2662 windowList = new Vector<WeakReference<Window>>(); 2663 appContext.put(Window.class, windowList); 2664 } 2665 windowList.add(weakThis); 2666 } 2667 } 2668 2669 private static void removeFromWindowList(AppContext context, WeakReference weakThis) { 2670 synchronized (Window.class) { 2671 Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>)context.get(Window.class); 2672 if (windowList != null) { 2673 windowList.remove(weakThis); 2674 } 2675 } 2676 } 2677 2678 private void removeFromWindowList() { 2679 removeFromWindowList(appContext, weakThis); 2680 } 2681 2682 /** 2683 * The window serialized data version. 2684 * 2685 * @serial 2686 */ 2687 private int windowSerializedDataVersion = 2; 2688 2689 /** 2690 * Writes default serializable fields to stream. Writes 2691 * a list of serializable <code>WindowListener</code>s and 2692 * <code>WindowFocusListener</code>s as optional data. 2693 * Writes a list of child windows as optional data. 2694 * Writes a list of icon images as optional data 2695 * 2696 * @param s the <code>ObjectOutputStream</code> to write 2697 * @serialData <code>null</code> terminated sequence of 2698 * 0 or more pairs; the pair consists of a <code>String</code> 2699 * and and <code>Object</code>; the <code>String</code> 2700 * indicates the type of object and is one of the following: 2701 * <code>windowListenerK</code> indicating a 2702 * <code>WindowListener</code> object; 2703 * <code>windowFocusWindowK</code> indicating a 2704 * <code>WindowFocusListener</code> object; 2705 * <code>ownedWindowK</code> indicating a child 2706 * <code>Window</code> object 2707 * 2708 * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener) 2709 * @see Component#windowListenerK 2710 * @see Component#windowFocusListenerK 2711 * @see Component#ownedWindowK 2712 * @see #readObject(ObjectInputStream) 2713 */ 2714 private void writeObject(ObjectOutputStream s) throws IOException { 2715 synchronized (this) { 2716 // Update old focusMgr fields so that our object stream can be read 2717 // by previous releases 2718 focusMgr = new FocusManager(); 2719 focusMgr.focusRoot = this; 2720 focusMgr.focusOwner = getMostRecentFocusOwner(); 2721 2722 s.defaultWriteObject(); 2723 2724 // Clear fields so that we don't keep extra references around 2725 focusMgr = null; 2726 2727 AWTEventMulticaster.save(s, windowListenerK, windowListener); 2728 AWTEventMulticaster.save(s, windowFocusListenerK, windowFocusListener); 2729 AWTEventMulticaster.save(s, windowStateListenerK, windowStateListener); 2730 } 2731 2732 s.writeObject(null); 2733 2734 synchronized (ownedWindowList) { 2735 for (int i = 0; i < ownedWindowList.size(); i++) { 2736 Window child = ownedWindowList.elementAt(i).get(); 2737 if (child != null) { 2738 s.writeObject(ownedWindowK); 2739 s.writeObject(child); 2740 } 2741 } 2742 } 2743 s.writeObject(null); 2744 2745 //write icon array 2746 if (icons != null) { 2747 for (Image i : icons) { 2748 if (i instanceof Serializable) { 2749 s.writeObject(i); 2750 } 2751 } 2752 } 2753 s.writeObject(null); 2754 } 2755 2756 // 2757 // Part of deserialization procedure to be called before 2758 // user's code. 2759 // 2760 private void initDeserializedWindow() { 2761 setWarningString(); 2762 inputContextLock = new Object(); 2763 2764 // Deserialized Windows are not yet visible. 2765 visible = false; 2766 2767 weakThis = new WeakReference(this); 2768 2769 anchor = new Object(); 2770 sun.java2d.Disposer.addRecord(anchor, new WindowDisposerRecord(appContext, this)); 2771 2772 addToWindowList(); 2773 2774 } 2775 2776 private void deserializeResources(ObjectInputStream s) 2777 throws ClassNotFoundException, IOException, HeadlessException { 2778 ownedWindowList = new Vector(); 2779 2780 if (windowSerializedDataVersion < 2) { 2781 // Translate old-style focus tracking to new model. For 1.4 and 2782 // later releases, we'll rely on the Window's initial focusable 2783 // Component. 2784 if (focusMgr != null) { 2785 if (focusMgr.focusOwner != null) { 2786 KeyboardFocusManager. 2787 setMostRecentFocusOwner(this, focusMgr.focusOwner); 2788 } 2789 } 2790 2791 // This field is non-transient and relies on default serialization. 2792 // However, the default value is insufficient, so we need to set 2793 // it explicitly for object data streams prior to 1.4. 2794 focusableWindowState = true; 2795 2796 2797 } 2798 2799 Object keyOrNull; 2800 while(null != (keyOrNull = s.readObject())) { 2801 String key = ((String)keyOrNull).intern(); 2802 2803 if (windowListenerK == key) { 2804 addWindowListener((WindowListener)(s.readObject())); 2805 } else if (windowFocusListenerK == key) { 2806 addWindowFocusListener((WindowFocusListener)(s.readObject())); 2807 } else if (windowStateListenerK == key) { 2808 addWindowStateListener((WindowStateListener)(s.readObject())); 2809 } else // 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 // skip value for unrecognized key 2821 s.readObject(); 2822 } 2823 2824 //read icons 2825 Object obj = s.readObject(); //Throws OptionalDataException 2826 //for pre1.6 objects. 2827 icons = new ArrayList<Image>(); //Frame.readObject() assumes 2828 //pre1.6 version if icons is null. 2829 while (obj != null) { 2830 if (obj instanceof Image) { 2831 icons.add((Image)obj); 2832 } 2833 obj = s.readObject(); 2834 } 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, HeadlessException 2859 { 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("windowSerializedDataVersion", 1); 2868 locationByPlatform = f.get("locationByPlatform", locationByPlatformProp); 2869 // Note: 1.4 (or later) doesn't use focusMgr 2870 focusMgr = (FocusManager)f.get("focusMgr", null); 2871 Dialog.ModalExclusionType et = (Dialog.ModalExclusionType) 2872 f.get("modalExclusionType", Dialog.ModalExclusionType.NO_EXCLUDE); 2873 setModalExclusionType(et); // since 6.0 2874 boolean aot = f.get("alwaysOnTop", false); 2875 if(aot) { 2876 setAlwaysOnTop(aot); // since 1.5; subject to permission check 2877 } 2878 shape = (Shape)f.get("shape", null); 2879 opacity = (Float)f.get("opacity", 1.0f); 2880 2881 this.securityWarningWidth = 0; 2882 this.securityWarningHeight = 0; 2883 this.securityWarningPointX = 2.0; 2884 this.securityWarningPointY = 0.0; 2885 this.securityWarningAlignmentX = RIGHT_ALIGNMENT; 2886 this.securityWarningAlignmentY = TOP_ALIGNMENT; 2887 2888 deserializeResources(s); 2889 } 2890 2891 /* 2892 * --- Accessibility Support --- 2893 * 2894 */ 2895 2896 /** 2897 * Gets the AccessibleContext associated with this Window. 2898 * For windows, the AccessibleContext takes the form of an 2899 * AccessibleAWTWindow. 2900 * A new AccessibleAWTWindow instance is created if necessary. 2901 * 2902 * @return an AccessibleAWTWindow that serves as the 2903 * AccessibleContext of this Window 2904 * @since 1.3 2905 */ 2906 public AccessibleContext getAccessibleContext() { 2907 if (accessibleContext == null) { 2908 accessibleContext = new AccessibleAWTWindow(); 2909 } 2910 return accessibleContext; 2911 } 2912 2913 /** 2914 * This class implements accessibility support for the 2915 * <code>Window</code> class. It provides an implementation of the 2916 * Java Accessibility API appropriate to window user-interface elements. 2917 * @since 1.3 2918 */ 2919 protected class AccessibleAWTWindow extends AccessibleAWTContainer 2920 { 2921 /* 2922 * JDK 1.3 serialVersionUID 2923 */ 2924 private static final long serialVersionUID = 4215068635060671780L; 2925 2926 /** 2927 * Get the role of this object. 2928 * 2929 * @return an instance of AccessibleRole describing the role of the 2930 * object 2931 * @see javax.accessibility.AccessibleRole 2932 */ 2933 public AccessibleRole getAccessibleRole() { 2934 return AccessibleRole.WINDOW; 2935 } 2936 2937 /** 2938 * Get the state of this object. 2939 * 2940 * @return an instance of AccessibleStateSet containing the current 2941 * state set of the object 2942 * @see javax.accessibility.AccessibleState 2943 */ 2944 public AccessibleStateSet getAccessibleStateSet() { 2945 AccessibleStateSet states = super.getAccessibleStateSet(); 2946 if (getFocusOwner() != null) { 2947 states.add(AccessibleState.ACTIVE); 2948 } 2949 return states; 2950 } 2951 2952 } // inner class AccessibleAWTWindow 2953 2954 /** 2955 * This method returns the GraphicsConfiguration used by this Window. 2956 * @since 1.3 2957 */ 2958 public GraphicsConfiguration getGraphicsConfiguration() { 2959 //NOTE: for multiscreen, this will need to take into account 2960 //which screen the window is on/mostly on instead of returning the 2961 //default or constructor argument config. 2962 synchronized(getTreeLock()) { 2963 if (graphicsConfig == null && !GraphicsEnvironment.isHeadless()) { 2964 graphicsConfig = 2965 GraphicsEnvironment. getLocalGraphicsEnvironment(). 2966 getDefaultScreenDevice(). 2967 getDefaultConfiguration(); 2968 } 2969 return graphicsConfig; 2970 } 2971 } 2972 2973 /** 2974 * Reset this Window's GraphicsConfiguration to match its peer. 2975 */ 2976 void resetGC() { 2977 if (!GraphicsEnvironment.isHeadless()) { 2978 // use the peer's GC 2979 setGCFromPeer(); 2980 // if it's still null, use the default 2981 if (graphicsConfig == null) { 2982 graphicsConfig = GraphicsEnvironment. 2983 getLocalGraphicsEnvironment(). 2984 getDefaultScreenDevice(). 2985 getDefaultConfiguration(); 2986 } 2987 if (log.isLoggable(Level.FINER)) { 2988 log.finer("+ Window.resetGC(): new GC is \n+ " + graphicsConfig + "\n+ this is " + this); 2989 } 2990 } 2991 } 2992 2993 /** 2994 * Sets the location of the window relative to the specified 2995 * component. 2996 * <p> 2997 * If the component is not currently showing, or <code>c</code> 2998 * is <code>null</code>, the window is placed at the center of 2999 * the screen. The center point can be determined with {@link 3000 * GraphicsEnvironment#getCenterPoint GraphicsEnvironment.getCenterPoint} 3001 * <p> 3002 * If the bottom of the component is offscreen, the window is 3003 * placed to the side of the <code>Component</code> that is 3004 * closest to the center of the screen. So if the <code>Component</code> 3005 * is on the right part of the screen, the <code>Window</code> 3006 * is placed to its left, and vice versa. 3007 * 3008 * @param c the component in relation to which the window's location 3009 * is determined 3010 * @see java.awt.GraphicsEnvironment#getCenterPoint 3011 * @since 1.4 3012 */ 3013 public void setLocationRelativeTo(Component c) { 3014 Container root=null; 3015 3016 if (c != null) { 3017 if (c instanceof Window || c instanceof Applet) { 3018 root = (Container)c; 3019 } else { 3020 Container parent; 3021 for(parent = c.getParent() ; parent != null ; parent = parent.getParent()) { 3022 if (parent instanceof Window || parent instanceof Applet) { 3023 root = parent; 3024 break; 3025 } 3026 } 3027 } 3028 } 3029 3030 if((c != null && !c.isShowing()) || root == null || 3031 !root.isShowing()) { 3032 Dimension paneSize = getSize(); 3033 3034 Point centerPoint = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint(); 3035 setLocation(centerPoint.x - paneSize.width / 2, 3036 centerPoint.y - paneSize.height / 2); 3037 } else { 3038 Dimension invokerSize = c.getSize(); 3039 Point invokerScreenLocation = c.getLocationOnScreen(); 3040 3041 Rectangle windowBounds = getBounds(); 3042 int dx = invokerScreenLocation.x+((invokerSize.width-windowBounds.width)>>1); 3043 int dy = invokerScreenLocation.y+((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 / 2 < 3050 ss.width / 2) { 3051 dx = invokerScreenLocation.x+invokerSize.width; 3052 } 3053 else { 3054 dx = invokerScreenLocation.x-windowBounds.width; 3055 } 3056 } 3057 3058 // Avoid being placed off the edge of the screen 3059 if (dx+windowBounds.width > ss.x + ss.width) { 3060 dx = ss.x + ss.width - windowBounds.width; 3061 } 3062 if (dx < ss.x) dx = ss.x; 3063 if (dy < ss.y) dy = ss.y; 3064 3065 setLocation(dx, dy); 3066 } 3067 } 3068 3069 /** 3070 * Overridden from Component. Top-level Windows should not propagate a 3071 * MouseWheelEvent beyond themselves into their owning Windows. 3072 */ 3073 void deliverMouseWheelToAncestor(MouseWheelEvent e) {} 3074 3075 /** 3076 * Overridden from Component. Top-level Windows don't dispatch to ancestors 3077 */ 3078 boolean dispatchMouseWheelToAncestor(MouseWheelEvent e) {return false;} 3079 3080 /** 3081 * Creates a new strategy for multi-buffering on this component. 3082 * Multi-buffering is useful for rendering performance. This method 3083 * attempts to create the best strategy available with the number of 3084 * buffers supplied. It will always create a <code>BufferStrategy</code> 3085 * with that number of buffers. 3086 * A page-flipping strategy is attempted first, then a blitting strategy 3087 * using accelerated buffers. Finally, an unaccelerated blitting 3088 * strategy is used. 3089 * <p> 3090 * Each time this method is called, 3091 * the existing buffer strategy for this component is discarded. 3092 * @param numBuffers number of buffers to create 3093 * @exception IllegalArgumentException if numBuffers is less than 1. 3094 * @exception IllegalStateException if the component is not displayable 3095 * @see #isDisplayable 3096 * @see #getBufferStrategy 3097 * @since 1.4 3098 */ 3099 public void createBufferStrategy(int numBuffers) { 3100 super.createBufferStrategy(numBuffers); 3101 } 3102 3103 /** 3104 * Creates a new strategy for multi-buffering on this component with the 3105 * required buffer capabilities. This is useful, for example, if only 3106 * accelerated memory or page flipping is desired (as specified by the 3107 * buffer capabilities). 3108 * <p> 3109 * Each time this method 3110 * is called, the existing buffer strategy for this component is discarded. 3111 * @param numBuffers number of buffers to create, including the front buffer 3112 * @param caps the required capabilities for creating the buffer strategy; 3113 * cannot be <code>null</code> 3114 * @exception AWTException if the capabilities supplied could not be 3115 * supported or met; this may happen, for example, if there is not enough 3116 * accelerated memory currently available, or if page flipping is specified 3117 * but not possible. 3118 * @exception IllegalArgumentException if numBuffers is less than 1, or if 3119 * caps is <code>null</code> 3120 * @see #getBufferStrategy 3121 * @since 1.4 3122 */ 3123 public void createBufferStrategy(int numBuffers, 3124 BufferCapabilities caps) throws AWTException { 3125 super.createBufferStrategy(numBuffers, caps); 3126 } 3127 3128 /** 3129 * Returns the <code>BufferStrategy</code> used by this component. This 3130 * method will return null if a <code>BufferStrategy</code> has not yet 3131 * been created or has been disposed. 3132 * 3133 * @return the buffer strategy used by this component 3134 * @see #createBufferStrategy 3135 * @since 1.4 3136 */ 3137 public BufferStrategy getBufferStrategy() { 3138 return super.getBufferStrategy(); 3139 } 3140 3141 Component getTemporaryLostComponent() { 3142 return temporaryLostComponent; 3143 } 3144 Component setTemporaryLostComponent(Component component) { 3145 Component previousComp = temporaryLostComponent; 3146 // Check that "component" is an acceptable focus owner and don't store it otherwise 3147 // - or later we will have problems with opposite while handling WINDOW_GAINED_FOCUS 3148 if (component == null || component.canBeFocusOwner()) { 3149 temporaryLostComponent = component; 3150 } else { 3151 temporaryLostComponent = null; 3152 } 3153 return previousComp; 3154 } 3155 3156 /** 3157 * Checks whether this window can contain focus owner. 3158 * Verifies that it is focusable and as container it can container focus owner. 3159 * @since 1.5 3160 */ 3161 boolean canContainFocusOwner(Component focusOwnerCandidate) { 3162 return super.canContainFocusOwner(focusOwnerCandidate) && isFocusableWindow(); 3163 } 3164 3165 private boolean locationByPlatform = locationByPlatformProp; 3166 3167 3168 /** 3169 * Sets whether this Window should appear at the default location for the 3170 * native windowing system or at the current location (returned by 3171 * <code>getLocation</code>) the next time the Window is made visible. 3172 * This behavior resembles a native window shown without programmatically 3173 * setting its location. Most windowing systems cascade windows if their 3174 * locations are not explicitly set. The actual location is determined once the 3175 * window is shown on the screen. 3176 * <p> 3177 * This behavior can also be enabled by setting the System Property 3178 * "java.awt.Window.locationByPlatform" to "true", though calls to this method 3179 * take precedence. 3180 * <p> 3181 * Calls to <code>setVisible</code>, <code>setLocation</code> and 3182 * <code>setBounds</code> after calling <code>setLocationByPlatform</code> clear 3183 * this property of the Window. 3184 * <p> 3185 * For example, after the following code is executed: 3186 * <pre><blockquote> 3187 * setLocationByPlatform(true); 3188 * setVisible(true); 3189 * boolean flag = isLocationByPlatform(); 3190 * </blockquote></pre> 3191 * The window will be shown at platform's default location and 3192 * <code>flag</code> will be <code>false</code>. 3193 * <p> 3194 * In the following sample: 3195 * <pre><blockquote> 3196 * setLocationByPlatform(true); 3197 * setLocation(10, 10); 3198 * boolean flag = isLocationByPlatform(); 3199 * setVisible(true); 3200 * </blockquote></pre> 3201 * The window will be shown at (10, 10) and <code>flag</code> will be 3202 * <code>false</code>. 3203 * 3204 * @param locationByPlatform <code>true</code> if this Window should appear 3205 * at the default location, <code>false</code> if at the current location 3206 * @throws <code>IllegalComponentStateException</code> if the window 3207 * is showing on screen and locationByPlatform is <code>true</code>. 3208 * @see #setLocation 3209 * @see #isShowing 3210 * @see #setVisible 3211 * @see #isLocationByPlatform 3212 * @see java.lang.System#getProperty(String) 3213 * @since 1.5 3214 */ 3215 public void setLocationByPlatform(boolean locationByPlatform) { 3216 synchronized (getTreeLock()) { 3217 if (locationByPlatform && isShowing()) { 3218 throw new IllegalComponentStateException("The window is showing on screen."); 3219 } 3220 this.locationByPlatform = locationByPlatform; 3221 } 3222 } 3223 3224 /** 3225 * Returns <code>true</code> if this Window will appear at the default location 3226 * for the native windowing system the next time this Window is made visible. 3227 * This method always returns <code>false</code> if the Window is showing on the 3228 * screen. 3229 * 3230 * @return whether this Window will appear at the default location 3231 * @see #setLocationByPlatform 3232 * @see #isShowing 3233 * @since 1.5 3234 */ 3235 public boolean isLocationByPlatform() { 3236 synchronized (getTreeLock()) { 3237 return locationByPlatform; 3238 } 3239 } 3240 3241 /** 3242 * {@inheritDoc} 3243 * <p> 3244 * The {@code width} or {@code height} values 3245 * are automatically enlarged if either is less than 3246 * the minimum size as specified by previous call to 3247 * {@code setMinimumSize}. 3248 * 3249 * @see #getBounds 3250 * @see #setLocation(int, int) 3251 * @see #setLocation(Point) 3252 * @see #setSize(int, int) 3253 * @see #setSize(Dimension) 3254 * @see #setMinimumSize 3255 * @see #setLocationByPlatform 3256 * @see #isLocationByPlatform 3257 * @since 1.6 3258 */ 3259 public void setBounds(int x, int y, int width, int height) { 3260 synchronized (getTreeLock()) { 3261 if (getBoundsOp() == ComponentPeer.SET_LOCATION || 3262 getBoundsOp() == ComponentPeer.SET_BOUNDS) 3263 { 3264 locationByPlatform = false; 3265 } 3266 super.setBounds(x, y, width, height); 3267 } 3268 } 3269 3270 /** 3271 * {@inheritDoc} 3272 * <p> 3273 * The {@code r.width} or {@code r.height} values 3274 * will be automatically enlarged if either is less than 3275 * the minimum size as specified by previous call to 3276 * {@code setMinimumSize}. 3277 * 3278 * @see #getBounds 3279 * @see #setLocation(int, int) 3280 * @see #setLocation(Point) 3281 * @see #setSize(int, int) 3282 * @see #setSize(Dimension) 3283 * @see #setMinimumSize 3284 * @see #setLocationByPlatform 3285 * @see #isLocationByPlatform 3286 * @since 1.6 3287 */ 3288 public void setBounds(Rectangle r) { 3289 setBounds(r.x, r.y, r.width, r.height); 3290 } 3291 3292 /** 3293 * Determines whether this component will be displayed on the screen. 3294 * @return <code>true</code> if the component and all of its ancestors 3295 * until a toplevel window are visible, <code>false</code> otherwise 3296 */ 3297 boolean isRecursivelyVisible() { 3298 // 5079694 fix: for a toplevel to be displayed, its parent doesn't have to be visible. 3299 // We're overriding isRecursivelyVisible to implement this policy. 3300 return visible; 3301 } 3302 3303 3304 // ******************** SHAPES & TRANSPARENCY CODE ******************** 3305 3306 /** 3307 * JavaDoc 3308 */ 3309 /*public */float getOpacity() { 3310 synchronized (getTreeLock()) { 3311 return opacity; 3312 } 3313 } 3314 3315 /** 3316 * JavaDoc 3317 */ 3318 /*public */void setOpacity(float opacity) { 3319 synchronized (getTreeLock()) { 3320 if (opacity < 0.0f || opacity > 1.0f) { 3321 throw new IllegalArgumentException( 3322 "The value of opacity should be in the range [0.0f .. 1.0f]."); 3323 } 3324 GraphicsConfiguration gc = getGraphicsConfiguration(); 3325 GraphicsDevice gd = gc.getDevice(); 3326 if (!gd.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.TRANSLUCENT)) { 3327 throw new UnsupportedOperationException( 3328 "TRANSLUCENT translucency is not supported."); 3329 } 3330 if ((gc.getDevice().getFullScreenWindow() == this) && (opacity < 1.0f)) { 3331 throw new IllegalArgumentException( 3332 "Setting opacity for full-screen window is not supported."); 3333 } 3334 this.opacity = opacity; 3335 WindowPeer peer = (WindowPeer)getPeer(); 3336 if (peer != null) { 3337 peer.setOpacity(opacity); 3338 } 3339 } 3340 } 3341 3342 /** 3343 * JavaDoc 3344 */ 3345 /*public */Shape getShape() { 3346 synchronized (getTreeLock()) { 3347 return shape; 3348 } 3349 } 3350 3351 /** 3352 * JavaDoc 3353 * 3354 * @param window the window to set the shape to 3355 * @param shape the shape to set to the window 3356 * @throws IllegalArgumentException if the window is in full screen mode, 3357 * and the shape is not null 3358 */ 3359 /*public */void setShape(Shape shape) { 3360 synchronized (getTreeLock()) { 3361 GraphicsConfiguration gc = getGraphicsConfiguration(); 3362 GraphicsDevice gd = gc.getDevice(); 3363 if (!gd.isWindowTranslucencySupported( 3364 GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT)) 3365 { 3366 throw new UnsupportedOperationException( 3367 "PERPIXEL_TRANSPARENT translucency is not supported."); 3368 } 3369 if ((gc.getDevice().getFullScreenWindow() == this) && (shape != null)) { 3370 throw new IllegalArgumentException( 3371 "Setting shape for full-screen window is not supported."); 3372 } 3373 this.shape = shape; 3374 WindowPeer peer = (WindowPeer)getPeer(); 3375 if (peer != null) { 3376 peer.applyShape(shape == null ? null : Region.getInstance(shape, null)); 3377 } 3378 } 3379 } 3380 3381 /** 3382 * JavaDoc 3383 */ 3384 /* 3385 @Override 3386 public void setBackground(Color bgColor) { 3387 Color oldBg = getBackground(); 3388 super.setBackground(bgColor); 3389 if (oldBg != null && oldBg.equals(bgColor)) { 3390 return; 3391 } 3392 int oldAlpha = oldBg != null ? oldBg.getAlpha() : 255; 3393 int alpha = bgColor.getAlpha(); 3394 if ((oldAlpha == 255) && (alpha < 255)) { // non-opaque window 3395 GraphicsConfiguration gc = getGraphicsConfiguration(); 3396 GraphicsDevice gd = gc.getDevice(); 3397 if (gc.getDevice().getFullScreenWindow() == this) { 3398 throw new IllegalComponentStateException( 3399 "Making full-screen window non opaque is not supported."); 3400 } 3401 if (!gc.isTranslucencyCapable()) { 3402 GraphicsConfiguration capableGC = gd.getTranslucencyCapableGC(); 3403 if (capableGC == null) { 3404 throw new UnsupportedOperationException( 3405 "PERPIXEL_TRANSLUCENT translucency is not supported"); 3406 } 3407 setGraphicsConfiguration(capableGC); 3408 } 3409 setLayersOpaque(this, false); 3410 } else if ((oldAlpha < 255) && (alpha == 255)) { 3411 setLayersOpaque(this, true); 3412 } 3413 WindowPeer peer = (WindowPeer)getPeer(); 3414 if (peer != null) { 3415 peer.setOpaque(alpha == 255); 3416 } 3417 } 3418 */ 3419 3420 private transient boolean opaque = true; 3421 3422 void setOpaque(boolean opaque) { 3423 synchronized (getTreeLock()) { 3424 GraphicsConfiguration gc = getGraphicsConfiguration(); 3425 if (!opaque && !com.sun.awt.AWTUtilities.isTranslucencyCapable(gc)) { 3426 throw new IllegalArgumentException( 3427 "The window must use a translucency-compatible graphics configuration"); 3428 } 3429 if (!com.sun.awt.AWTUtilities.isTranslucencySupported( 3430 com.sun.awt.AWTUtilities.Translucency.PERPIXEL_TRANSLUCENT)) 3431 { 3432 throw new UnsupportedOperationException( 3433 "PERPIXEL_TRANSLUCENT translucency is not supported."); 3434 } 3435 if ((gc.getDevice().getFullScreenWindow() == this) && !opaque) { 3436 throw new IllegalArgumentException( 3437 "Making full-screen window non opaque is not supported."); 3438 } 3439 setLayersOpaque(this, opaque); 3440 this.opaque = opaque; 3441 WindowPeer peer = (WindowPeer)getPeer(); 3442 if (peer != null) { 3443 peer.setOpaque(opaque); 3444 } 3445 } 3446 } 3447 3448 private void updateWindow() { 3449 synchronized (getTreeLock()) { 3450 WindowPeer peer = (WindowPeer)getPeer(); 3451 if (peer != null) { 3452 peer.updateWindow(); 3453 } 3454 } 3455 } 3456 3457 private static final Color TRANSPARENT_BACKGROUND_COLOR = new Color(0, 0, 0, 0); 3458 3459 /** 3460 * {@inheritDoc} 3461 * 3462 * @since 1.7 3463 */ 3464 @Override 3465 public void paint(Graphics g) { 3466 Color bgColor = getBackground(); 3467 if ((bgColor != null) && (bgColor.getAlpha() < 255)) { 3468 Graphics gg = g.create(); 3469 try { 3470 if (gg instanceof Graphics2D) { 3471 gg.setColor(bgColor); 3472 ((Graphics2D)gg).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC)); 3473 gg.fillRect(0, 0, getWidth(), getHeight()); 3474 } 3475 } finally { 3476 gg.dispose(); 3477 } 3478 } 3479 super.paint(g); 3480 } 3481 3482 private static void setLayersOpaque(Component component, boolean isOpaque) { 3483 // Shouldn't use instanceof to avoid loading Swing classes 3484 // if it's a pure AWT application. 3485 if (Component.doesImplement(component, "javax.swing.RootPaneContainer")) { 3486 javax.swing.RootPaneContainer rpc = (javax.swing.RootPaneContainer)component; 3487 javax.swing.JRootPane root = rpc.getRootPane(); 3488 javax.swing.JLayeredPane lp = root.getLayeredPane(); 3489 Container c = root.getContentPane(); 3490 javax.swing.JComponent content = 3491 (c instanceof javax.swing.JComponent) ? (javax.swing.JComponent)c : null; 3492 lp.setOpaque(isOpaque); 3493 root.setOpaque(isOpaque); 3494 if (content != null) { 3495 content.setOpaque(isOpaque); 3496 3497 // Iterate down one level to see whether we have a JApplet 3498 // (which is also a RootPaneContainer) which requires processing 3499 int numChildren = content.getComponentCount(); 3500 if (numChildren > 0) { 3501 Component child = content.getComponent(0); 3502 // It's OK to use instanceof here because we've 3503 // already loaded the RootPaneContainer class by now 3504 if (child instanceof javax.swing.RootPaneContainer) { 3505 setLayersOpaque(child, isOpaque); 3506 } 3507 } 3508 } 3509 } 3510 3511 Color bg = component.getBackground(); 3512 boolean hasTransparentBg = TRANSPARENT_BACKGROUND_COLOR.equals(bg); 3513 3514 Container container = null; 3515 if (component instanceof Container) { 3516 container = (Container) component; 3517 } 3518 3519 if (isOpaque) { 3520 if (hasTransparentBg) { 3521 // Note: we use the SystemColor.window color as the default. 3522 // This color is used in the WindowPeer implementations to 3523 // initialize the background color of the window if it is null. 3524 // (This might not be the right thing to do for other 3525 // RootPaneContainers we might be invoked with) 3526 Color newColor = null; 3527 if (container != null && container.preserveBackgroundColor != null) { 3528 newColor = container.preserveBackgroundColor; 3529 } else { 3530 newColor = SystemColor.window; 3531 } 3532 component.setBackground(newColor); 3533 } 3534 } else { 3535 if (!hasTransparentBg && container != null) { 3536 container.preserveBackgroundColor = bg; 3537 } 3538 component.setBackground(TRANSPARENT_BACKGROUND_COLOR); 3539 } 3540 } 3541 3542 3543 // ************************** MIXING CODE ******************************* 3544 3545 // A window has a parent, but it does NOT have a container 3546 @Override 3547 final Container getContainer() { 3548 return null; 3549 } 3550 3551 /** 3552 * Applies the shape to the component 3553 * @param shape Shape to be applied to the component 3554 */ 3555 @Override 3556 final void applyCompoundShape(Region shape) { 3557 // The shape calculated by mixing code is not intended to be applied 3558 // to windows or frames 3559 } 3560 3561 @Override 3562 final void applyCurrentShape() { 3563 // The shape calculated by mixing code is not intended to be applied 3564 // to windows or frames 3565 } 3566 3567 @Override 3568 final void mixOnReshaping() { 3569 // The shape calculated by mixing code is not intended to be applied 3570 // to windows or frames 3571 } 3572 3573 @Override 3574 final Point getLocationOnWindow() { 3575 return new Point(0, 0); 3576 } 3577 3578 // ****************** END OF MIXING CODE ******************************** 3579 3580 // This method gets the window location/size as reported by the native 3581 // system since the locally cached values may represent outdated data. 3582 // NOTE: this method is invoked on the toolkit thread, and therefore 3583 // is not supposed to become public/user-overridable. 3584 private Point2D calculateSecurityWarningPosition(double x, double y, 3585 double w, double h) 3586 { 3587 return new Point2D.Double( 3588 x + w * securityWarningAlignmentX + securityWarningPointX, 3589 y + h * securityWarningAlignmentY + securityWarningPointY); 3590 } 3591 3592 } // class Window 3593 3594 3595 /** 3596 * This class is no longer used, but is maintained for Serialization 3597 * backward-compatibility. 3598 */ 3599 class FocusManager implements java.io.Serializable { 3600 Container focusRoot; 3601 Component focusOwner; 3602 3603 /* 3604 * JDK 1.1 serialVersionUID 3605 */ 3606 static final long serialVersionUID = 2491878825643557906L; 3607 }