1 /* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package javax.swing; 26 27 import java.awt.*; 28 import java.awt.event.*; 29 import java.beans.PropertyChangeListener; 30 import java.util.Locale; 31 import java.util.Vector; 32 import java.io.Serializable; 33 34 import javax.accessibility.*; 35 36 /** 37 * A <code>JWindow</code> is a container that can be displayed anywhere on the 38 * user's desktop. It does not have the title bar, window-management buttons, 39 * or other trimmings associated with a <code>JFrame</code>, but it is still a 40 * "first-class citizen" of the user's desktop, and can exist anywhere 41 * on it. 42 * <p> 43 * The <code>JWindow</code> component contains a <code>JRootPane</code> 44 * as its only child. The <code>contentPane</code> should be the parent 45 * of any children of the <code>JWindow</code>. 46 * As a convenience, the {@code add}, {@code remove}, and {@code setLayout} 47 * methods of this class are overridden, so that they delegate calls 48 * to the corresponding methods of the {@code ContentPane}. 49 * For example, you can add a child component to a window as follows: 50 * <pre> 51 * window.add(child); 52 * </pre> 53 * And the child will be added to the contentPane. 54 * The <code>contentPane</code> will always be non-<code>null</code>. 55 * Attempting to set it to <code>null</code> will cause the <code>JWindow</code> 56 * to throw an exception. The default <code>contentPane</code> will have a 57 * <code>BorderLayout</code> manager set on it. 58 * Refer to {@link javax.swing.RootPaneContainer} 59 * for details on adding, removing and setting the <code>LayoutManager</code> 60 * of a <code>JWindow</code>. 61 * <p> 62 * Please see the {@link JRootPane} documentation for a complete description of 63 * the <code>contentPane</code>, <code>glassPane</code>, and 64 * <code>layeredPane</code> components. 65 * <p> 66 * In a multi-screen environment, you can create a <code>JWindow</code> 67 * on a different screen device. See {@link java.awt.Window} for more 68 * information. 69 * <p> 70 * <strong>Warning:</strong> Swing is not thread safe. For more 71 * information see <a 72 * href="package-summary.html#threading">Swing's Threading 73 * Policy</a>. 74 * <p> 75 * <strong>Warning:</strong> 76 * Serialized objects of this class will not be compatible with 77 * future Swing releases. The current serialization support is 78 * appropriate for short term storage or RMI between applications running 79 * the same version of Swing. As of 1.4, support for long term storage 80 * of all JavaBeans™ 81 * has been added to the <code>java.beans</code> package. 82 * Please see {@link java.beans.XMLEncoder}. 83 * 84 * @see JRootPane 85 * 86 * @beaninfo 87 * attribute: isContainer true 88 * attribute: containerDelegate getContentPane 89 * description: A toplevel window which has no system border or controls. 90 * 91 * @author David Kloba 92 * @since 1.2 93 */ 94 @SuppressWarnings("serial") 95 public class JWindow extends Window implements Accessible, 96 RootPaneContainer, 97 TransferHandler.HasGetTransferHandler 98 { 99 /** 100 * The <code>JRootPane</code> instance that manages the 101 * <code>contentPane</code> 102 * and optional <code>menuBar</code> for this frame, as well as the 103 * <code>glassPane</code>. 104 * 105 * @see #getRootPane 106 * @see #setRootPane 107 */ 108 protected JRootPane rootPane; 109 110 /** 111 * If true then calls to <code>add</code> and <code>setLayout</code> 112 * will be forwarded to the <code>contentPane</code>. This is initially 113 * false, but is set to true when the <code>JWindow</code> is constructed. 114 * 115 * @see #isRootPaneCheckingEnabled 116 * @see #setRootPaneCheckingEnabled 117 * @see javax.swing.RootPaneContainer 118 */ 119 protected boolean rootPaneCheckingEnabled = false; 120 121 /** 122 * The <code>TransferHandler</code> for this window. 123 */ 124 private TransferHandler transferHandler; 125 126 /** 127 * Creates a window with no specified owner. This window will not be 128 * focusable. 129 * <p> 130 * This constructor sets the component's locale property to the value 131 * returned by <code>JComponent.getDefaultLocale</code>. 132 * 133 * @throws HeadlessException if 134 * <code>GraphicsEnvironment.isHeadless()</code> returns true. 135 * @see java.awt.GraphicsEnvironment#isHeadless 136 * @see #isFocusableWindow 137 * @see JComponent#getDefaultLocale 138 */ 139 public JWindow() { 140 this((Frame)null); 141 } 142 143 /** 144 * Creates a window with the specified <code>GraphicsConfiguration</code> 145 * of a screen device. This window will not be focusable. 146 * <p> 147 * This constructor sets the component's locale property to the value 148 * returned by <code>JComponent.getDefaultLocale</code>. 149 * 150 * @param gc the <code>GraphicsConfiguration</code> that is used 151 * to construct the new window with; if gc is <code>null</code>, 152 * the system default <code>GraphicsConfiguration</code> 153 * is assumed 154 * @throws HeadlessException If 155 * <code>GraphicsEnvironment.isHeadless()</code> returns true. 156 * @throws IllegalArgumentException if <code>gc</code> is not from 157 * a screen device. 158 * 159 * @see java.awt.GraphicsEnvironment#isHeadless 160 * @see #isFocusableWindow 161 * @see JComponent#getDefaultLocale 162 * 163 * @since 1.3 164 */ 165 public JWindow(GraphicsConfiguration gc) { 166 this(null, gc); 167 super.setFocusableWindowState(false); 168 } 169 170 /** 171 * Creates a window with the specified owner frame. 172 * If <code>owner</code> is <code>null</code>, the shared owner 173 * will be used and this window will not be focusable. Also, 174 * this window will not be focusable unless its owner is showing 175 * on the screen. 176 * <p> 177 * This constructor sets the component's locale property to the value 178 * returned by <code>JComponent.getDefaultLocale</code>. 179 * 180 * @param owner the frame from which the window is displayed 181 * @throws HeadlessException if GraphicsEnvironment.isHeadless() 182 * returns true. 183 * @see java.awt.GraphicsEnvironment#isHeadless 184 * @see #isFocusableWindow 185 * @see JComponent#getDefaultLocale 186 */ 187 public JWindow(Frame owner) { 188 super(owner == null? SwingUtilities.getSharedOwnerFrame() : owner); 189 if (owner == null) { 190 WindowListener ownerShutdownListener = 191 SwingUtilities.getSharedOwnerFrameShutdownListener(); 192 addWindowListener(ownerShutdownListener); 193 } 194 windowInit(); 195 } 196 197 /** 198 * Creates a window with the specified owner window. This window 199 * will not be focusable unless its owner is showing on the screen. 200 * If <code>owner</code> is <code>null</code>, the shared owner 201 * will be used and this window will not be focusable. 202 * <p> 203 * This constructor sets the component's locale property to the value 204 * returned by <code>JComponent.getDefaultLocale</code>. 205 * 206 * @param owner the window from which the window is displayed 207 * @throws HeadlessException if 208 * <code>GraphicsEnvironment.isHeadless()</code> returns true. 209 * @see java.awt.GraphicsEnvironment#isHeadless 210 * @see #isFocusableWindow 211 * @see JComponent#getDefaultLocale 212 */ 213 public JWindow(Window owner) { 214 super(owner == null ? (Window)SwingUtilities.getSharedOwnerFrame() : 215 owner); 216 if (owner == null) { 217 WindowListener ownerShutdownListener = 218 SwingUtilities.getSharedOwnerFrameShutdownListener(); 219 addWindowListener(ownerShutdownListener); 220 } 221 windowInit(); 222 } 223 224 /** 225 * Creates a window with the specified owner window and 226 * <code>GraphicsConfiguration</code> of a screen device. If 227 * <code>owner</code> is <code>null</code>, the shared owner will be used 228 * and this window will not be focusable. 229 * <p> 230 * This constructor sets the component's locale property to the value 231 * returned by <code>JComponent.getDefaultLocale</code>. 232 * 233 * @param owner the window from which the window is displayed 234 * @param gc the <code>GraphicsConfiguration</code> that is used 235 * to construct the new window with; if gc is <code>null</code>, 236 * the system default <code>GraphicsConfiguration</code> 237 * is assumed, unless <code>owner</code> is also null, in which 238 * case the <code>GraphicsConfiguration</code> from the 239 * shared owner frame will be used. 240 * @throws HeadlessException if 241 * <code>GraphicsEnvironment.isHeadless()</code> returns true. 242 * @throws IllegalArgumentException if <code>gc</code> is not from 243 * a screen device. 244 * 245 * @see java.awt.GraphicsEnvironment#isHeadless 246 * @see #isFocusableWindow 247 * @see JComponent#getDefaultLocale 248 * 249 * @since 1.3 250 */ 251 public JWindow(Window owner, GraphicsConfiguration gc) { 252 super(owner == null ? (Window)SwingUtilities.getSharedOwnerFrame() : 253 owner, gc); 254 if (owner == null) { 255 WindowListener ownerShutdownListener = 256 SwingUtilities.getSharedOwnerFrameShutdownListener(); 257 addWindowListener(ownerShutdownListener); 258 } 259 windowInit(); 260 } 261 262 /** 263 * Called by the constructors to init the <code>JWindow</code> properly. 264 */ 265 protected void windowInit() { 266 setLocale( JComponent.getDefaultLocale() ); 267 setRootPane(createRootPane()); 268 setRootPaneCheckingEnabled(true); 269 sun.awt.SunToolkit.checkAndSetPolicy(this); 270 } 271 272 /** 273 * Called by the constructor methods to create the default 274 * <code>rootPane</code>. 275 */ 276 protected JRootPane createRootPane() { 277 JRootPane rp = new JRootPane(); 278 // NOTE: this uses setOpaque vs LookAndFeel.installProperty as there 279 // is NO reason for the RootPane not to be opaque. For painting to 280 // work the contentPane must be opaque, therefor the RootPane can 281 // also be opaque. 282 rp.setOpaque(true); 283 return rp; 284 } 285 286 /** 287 * Returns whether calls to <code>add</code> and 288 * <code>setLayout</code> are forwarded to the <code>contentPane</code>. 289 * 290 * @return true if <code>add</code> and <code>setLayout</code> 291 * are forwarded; false otherwise 292 * 293 * @see #addImpl 294 * @see #setLayout 295 * @see #setRootPaneCheckingEnabled 296 * @see javax.swing.RootPaneContainer 297 */ 298 protected boolean isRootPaneCheckingEnabled() { 299 return rootPaneCheckingEnabled; 300 } 301 302 /** 303 * Sets the {@code transferHandler} property, which is a mechanism to 304 * support transfer of data into this component. Use {@code null} 305 * if the component does not support data transfer operations. 306 * <p> 307 * If the system property {@code suppressSwingDropSupport} is {@code false} 308 * (the default) and the current drop target on this component is either 309 * {@code null} or not a user-set drop target, this method will change the 310 * drop target as follows: If {@code newHandler} is {@code null} it will 311 * clear the drop target. If not {@code null} it will install a new 312 * {@code DropTarget}. 313 * <p> 314 * Note: When used with {@code JWindow}, {@code TransferHandler} only 315 * provides data import capability, as the data export related methods 316 * are currently typed to {@code JComponent}. 317 * <p> 318 * Please see 319 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html"> 320 * How to Use Drag and Drop and Data Transfer</a>, a section in 321 * <em>The Java Tutorial</em>, for more information. 322 * 323 * @param newHandler the new {@code TransferHandler} 324 * 325 * @see TransferHandler 326 * @see #getTransferHandler 327 * @see java.awt.Component#setDropTarget 328 * @since 1.6 329 * 330 * @beaninfo 331 * bound: true 332 * hidden: true 333 * description: Mechanism for transfer of data into the component 334 */ 335 public void setTransferHandler(TransferHandler newHandler) { 336 TransferHandler oldHandler = transferHandler; 337 transferHandler = newHandler; 338 SwingUtilities.installSwingDropTargetAsNecessary(this, transferHandler); 339 firePropertyChange("transferHandler", oldHandler, newHandler); 340 } 341 342 /** 343 * Gets the <code>transferHandler</code> property. 344 * 345 * @return the value of the <code>transferHandler</code> property 346 * 347 * @see TransferHandler 348 * @see #setTransferHandler 349 * @since 1.6 350 */ 351 public TransferHandler getTransferHandler() { 352 return transferHandler; 353 } 354 355 /** 356 * Calls <code>paint(g)</code>. This method was overridden to 357 * prevent an unnecessary call to clear the background. 358 * 359 * @param g the <code>Graphics</code> context in which to paint 360 */ 361 public void update(Graphics g) { 362 paint(g); 363 } 364 365 /** 366 * Sets whether calls to <code>add</code> and 367 * <code>setLayout</code> are forwarded to the <code>contentPane</code>. 368 * 369 * @param enabled true if <code>add</code> and <code>setLayout</code> 370 * are forwarded, false if they should operate directly on the 371 * <code>JWindow</code>. 372 * 373 * @see #addImpl 374 * @see #setLayout 375 * @see #isRootPaneCheckingEnabled 376 * @see javax.swing.RootPaneContainer 377 * @beaninfo 378 * hidden: true 379 * description: Whether the add and setLayout methods are forwarded 380 */ 381 protected void setRootPaneCheckingEnabled(boolean enabled) { 382 rootPaneCheckingEnabled = enabled; 383 } 384 385 386 /** 387 * Adds the specified child <code>Component</code>. 388 * This method is overridden to conditionally forward calls to the 389 * <code>contentPane</code>. 390 * By default, children are added to the <code>contentPane</code> instead 391 * of the frame, refer to {@link javax.swing.RootPaneContainer} for 392 * details. 393 * 394 * @param comp the component to be enhanced 395 * @param constraints the constraints to be respected 396 * @param index the index 397 * @exception IllegalArgumentException if <code>index</code> is invalid 398 * @exception IllegalArgumentException if adding the container's parent 399 * to itself 400 * @exception IllegalArgumentException if adding a window to a container 401 * 402 * @see #setRootPaneCheckingEnabled 403 * @see javax.swing.RootPaneContainer 404 */ 405 protected void addImpl(Component comp, Object constraints, int index) 406 { 407 if(isRootPaneCheckingEnabled()) { 408 getContentPane().add(comp, constraints, index); 409 } 410 else { 411 super.addImpl(comp, constraints, index); 412 } 413 } 414 415 /** 416 * Removes the specified component from the container. If 417 * <code>comp</code> is not the <code>rootPane</code>, this will forward 418 * the call to the <code>contentPane</code>. This will do nothing if 419 * <code>comp</code> is not a child of the <code>JWindow</code> or 420 * <code>contentPane</code>. 421 * 422 * @param comp the component to be removed 423 * @throws NullPointerException if <code>comp</code> is null 424 * @see #add 425 * @see javax.swing.RootPaneContainer 426 */ 427 public void remove(Component comp) { 428 if (comp == rootPane) { 429 super.remove(comp); 430 } else { 431 getContentPane().remove(comp); 432 } 433 } 434 435 436 /** 437 * Sets the <code>LayoutManager</code>. 438 * Overridden to conditionally forward the call to the 439 * <code>contentPane</code>. 440 * Refer to {@link javax.swing.RootPaneContainer} for 441 * more information. 442 * 443 * @param manager the <code>LayoutManager</code> 444 * @see #setRootPaneCheckingEnabled 445 * @see javax.swing.RootPaneContainer 446 */ 447 public void setLayout(LayoutManager manager) { 448 if(isRootPaneCheckingEnabled()) { 449 getContentPane().setLayout(manager); 450 } 451 else { 452 super.setLayout(manager); 453 } 454 } 455 456 457 /** 458 * Returns the <code>rootPane</code> object for this window. 459 * @return the <code>rootPane</code> property for this window 460 * 461 * @see #setRootPane 462 * @see RootPaneContainer#getRootPane 463 */ 464 public JRootPane getRootPane() { 465 return rootPane; 466 } 467 468 469 /** 470 * Sets the new <code>rootPane</code> object for this window. 471 * This method is called by the constructor. 472 * 473 * @param root the new <code>rootPane</code> property 474 * @see #getRootPane 475 * 476 * @beaninfo 477 * hidden: true 478 * description: the RootPane object for this window. 479 */ 480 protected void setRootPane(JRootPane root) { 481 if(rootPane != null) { 482 remove(rootPane); 483 } 484 rootPane = root; 485 if(rootPane != null) { 486 boolean checkingEnabled = isRootPaneCheckingEnabled(); 487 try { 488 setRootPaneCheckingEnabled(false); 489 add(rootPane, BorderLayout.CENTER); 490 } 491 finally { 492 setRootPaneCheckingEnabled(checkingEnabled); 493 } 494 } 495 } 496 497 498 /** 499 * Returns the <code>Container</code> which is the <code>contentPane</code> 500 * for this window. 501 * 502 * @return the <code>contentPane</code> property 503 * @see #setContentPane 504 * @see RootPaneContainer#getContentPane 505 */ 506 public Container getContentPane() { 507 return getRootPane().getContentPane(); 508 } 509 510 /** 511 * Sets the <code>contentPane</code> property for this window. 512 * This method is called by the constructor. 513 * 514 * @param contentPane the new <code>contentPane</code> 515 * 516 * @exception IllegalComponentStateException (a runtime 517 * exception) if the content pane parameter is <code>null</code> 518 * @see #getContentPane 519 * @see RootPaneContainer#setContentPane 520 * 521 * @beaninfo 522 * hidden: true 523 * description: The client area of the window where child 524 * components are normally inserted. 525 */ 526 public void setContentPane(Container contentPane) { 527 getRootPane().setContentPane(contentPane); 528 } 529 530 /** 531 * Returns the <code>layeredPane</code> object for this window. 532 * 533 * @return the <code>layeredPane</code> property 534 * @see #setLayeredPane 535 * @see RootPaneContainer#getLayeredPane 536 */ 537 public JLayeredPane getLayeredPane() { 538 return getRootPane().getLayeredPane(); 539 } 540 541 /** 542 * Sets the <code>layeredPane</code> property. 543 * This method is called by the constructor. 544 * 545 * @param layeredPane the new <code>layeredPane</code> object 546 * 547 * @exception IllegalComponentStateException (a runtime 548 * exception) if the content pane parameter is <code>null</code> 549 * @see #getLayeredPane 550 * @see RootPaneContainer#setLayeredPane 551 * 552 * @beaninfo 553 * hidden: true 554 * description: The pane which holds the various window layers. 555 */ 556 public void setLayeredPane(JLayeredPane layeredPane) { 557 getRootPane().setLayeredPane(layeredPane); 558 } 559 560 /** 561 * Returns the <code>glassPane Component</code> for this window. 562 * 563 * @return the <code>glassPane</code> property 564 * @see #setGlassPane 565 * @see RootPaneContainer#getGlassPane 566 */ 567 public Component getGlassPane() { 568 return getRootPane().getGlassPane(); 569 } 570 571 /** 572 * Sets the <code>glassPane</code> property. 573 * This method is called by the constructor. 574 * @param glassPane the <code>glassPane</code> object for this window 575 * 576 * @see #getGlassPane 577 * @see RootPaneContainer#setGlassPane 578 * 579 * @beaninfo 580 * hidden: true 581 * description: A transparent pane used for menu rendering. 582 */ 583 public void setGlassPane(Component glassPane) { 584 getRootPane().setGlassPane(glassPane); 585 } 586 587 /** 588 * {@inheritDoc} 589 * 590 * @since 1.6 591 */ 592 public Graphics getGraphics() { 593 JComponent.getGraphicsInvoked(this); 594 return super.getGraphics(); 595 } 596 597 /** 598 * Repaints the specified rectangle of this component within 599 * <code>time</code> milliseconds. Refer to <code>RepaintManager</code> 600 * for details on how the repaint is handled. 601 * 602 * @param time maximum time in milliseconds before update 603 * @param x the <i>x</i> coordinate 604 * @param y the <i>y</i> coordinate 605 * @param width the width 606 * @param height the height 607 * @see RepaintManager 608 * @since 1.6 609 */ 610 public void repaint(long time, int x, int y, int width, int height) { 611 if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) { 612 RepaintManager.currentManager(this).addDirtyRegion( 613 this, x, y, width, height); 614 } 615 else { 616 super.repaint(time, x, y, width, height); 617 } 618 } 619 620 /** 621 * Returns a string representation of this <code>JWindow</code>. 622 * This method 623 * is intended to be used only for debugging purposes, and the 624 * content and format of the returned string may vary between 625 * implementations. The returned string may be empty but may not 626 * be <code>null</code>. 627 * 628 * @return a string representation of this <code>JWindow</code> 629 */ 630 protected String paramString() { 631 String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ? 632 "true" : "false"); 633 634 return super.paramString() + 635 ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString; 636 } 637 638 639 ///////////////// 640 // Accessibility support 641 //////////////// 642 643 /** The accessible context property. */ 644 protected AccessibleContext accessibleContext = null; 645 646 /** 647 * Gets the AccessibleContext associated with this JWindow. 648 * For JWindows, the AccessibleContext takes the form of an 649 * AccessibleJWindow. 650 * A new AccessibleJWindow instance is created if necessary. 651 * 652 * @return an AccessibleJWindow that serves as the 653 * AccessibleContext of this JWindow 654 */ 655 public AccessibleContext getAccessibleContext() { 656 if (accessibleContext == null) { 657 accessibleContext = new AccessibleJWindow(); 658 } 659 return accessibleContext; 660 } 661 662 663 /** 664 * This class implements accessibility support for the 665 * <code>JWindow</code> class. It provides an implementation of the 666 * Java Accessibility API appropriate to window user-interface 667 * elements. 668 */ 669 @SuppressWarnings("serial") 670 protected class AccessibleJWindow extends AccessibleAWTWindow { 671 // everything is in the new parent, AccessibleAWTWindow 672 } 673 674 }