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