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 */ 93 @SuppressWarnings("serial") 94 public class JWindow extends Window implements Accessible, 95 RootPaneContainer, 96 TransferHandler.HasGetTransferHandler 97 { 98 /** 99 * The <code>JRootPane</code> instance that manages the 100 * <code>contentPane</code> 101 * and optional <code>menuBar</code> for this frame, as well as the 102 * <code>glassPane</code>. 103 * 104 * @see #getRootPane 105 * @see #setRootPane 106 */ 107 protected JRootPane rootPane; 108 109 /** 110 * If true then calls to <code>add</code> and <code>setLayout</code> 111 * will be forwarded to the <code>contentPane</code>. This is initially 112 * false, but is set to true when the <code>JWindow</code> is constructed. 113 * 114 * @see #isRootPaneCheckingEnabled 115 * @see #setRootPaneCheckingEnabled 116 * @see javax.swing.RootPaneContainer 117 */ 118 protected boolean rootPaneCheckingEnabled = false; 119 120 /** 121 * The <code>TransferHandler</code> for this window. 122 */ 123 private TransferHandler transferHandler; 124 125 /** 126 * Creates a window with no specified owner. This window will not be 127 * focusable. 128 * <p> 129 * This constructor sets the component's locale property to the value 130 * returned by <code>JComponent.getDefaultLocale</code>. 131 * 132 * @throws HeadlessException if 133 * <code>GraphicsEnvironment.isHeadless()</code> returns true. 134 * @see java.awt.GraphicsEnvironment#isHeadless 135 * @see #isFocusableWindow 136 * @see JComponent#getDefaultLocale 137 */ 138 public JWindow() { 139 this((Frame)null); 140 } 141 142 /** 143 * Creates a window with the specified <code>GraphicsConfiguration</code> 144 * of a screen device. This window will not be focusable. 145 * <p> 146 * This constructor sets the component's locale property to the value 147 * returned by <code>JComponent.getDefaultLocale</code>. 148 * 149 * @param gc the <code>GraphicsConfiguration</code> that is used 150 * to construct the new window with; if gc is <code>null</code>, 151 * the system default <code>GraphicsConfiguration</code> 152 * is assumed 153 * @throws HeadlessException If 154 * <code>GraphicsEnvironment.isHeadless()</code> returns true. 155 * @throws IllegalArgumentException if <code>gc</code> is not from 156 * a screen device. 157 * 158 * @see java.awt.GraphicsEnvironment#isHeadless 159 * @see #isFocusableWindow 160 * @see JComponent#getDefaultLocale 161 * 162 * @since 1.3 163 */ 164 public JWindow(GraphicsConfiguration gc) { 165 this(null, gc); 166 super.setFocusableWindowState(false); 167 } 168 169 /** 170 * Creates a window with the specified owner frame. 171 * If <code>owner</code> is <code>null</code>, the shared owner 172 * will be used and this window will not be focusable. Also, 173 * this window will not be focusable unless its owner is showing 174 * on the screen. 175 * <p> 176 * This constructor sets the component's locale property to the value 177 * returned by <code>JComponent.getDefaultLocale</code>. 178 * 179 * @param owner the frame from which the window is displayed 180 * @throws HeadlessException if GraphicsEnvironment.isHeadless() 181 * returns true. 182 * @see java.awt.GraphicsEnvironment#isHeadless 183 * @see #isFocusableWindow 184 * @see JComponent#getDefaultLocale 185 */ 186 public JWindow(Frame owner) { 187 super(owner == null? SwingUtilities.getSharedOwnerFrame() : owner); 188 if (owner == null) { 189 WindowListener ownerShutdownListener = 190 SwingUtilities.getSharedOwnerFrameShutdownListener(); 191 addWindowListener(ownerShutdownListener); 192 } 193 windowInit(); 194 } 195 196 /** 197 * Creates a window with the specified owner window. This window 198 * will not be focusable unless its owner is showing on the screen. 199 * If <code>owner</code> is <code>null</code>, the shared owner 200 * will be used and this window will not be focusable. 201 * <p> 202 * This constructor sets the component's locale property to the value 203 * returned by <code>JComponent.getDefaultLocale</code>. 204 * 205 * @param owner the window from which the window is displayed 206 * @throws HeadlessException if 207 * <code>GraphicsEnvironment.isHeadless()</code> returns true. 208 * @see java.awt.GraphicsEnvironment#isHeadless 209 * @see #isFocusableWindow 210 * @see JComponent#getDefaultLocale 211 */ 212 public JWindow(Window owner) { 213 super(owner == null ? (Window)SwingUtilities.getSharedOwnerFrame() : 214 owner); 215 if (owner == null) { 216 WindowListener ownerShutdownListener = 217 SwingUtilities.getSharedOwnerFrameShutdownListener(); 218 addWindowListener(ownerShutdownListener); 219 } 220 windowInit(); 221 } 222 223 /** 224 * Creates a window with the specified owner window and 225 * <code>GraphicsConfiguration</code> of a screen device. If 226 * <code>owner</code> is <code>null</code>, the shared owner will be used 227 * and this window will not be focusable. 228 * <p> 229 * This constructor sets the component's locale property to the value 230 * returned by <code>JComponent.getDefaultLocale</code>. 231 * 232 * @param owner the window from which the window is displayed 233 * @param gc the <code>GraphicsConfiguration</code> that is used 234 * to construct the new window with; if gc is <code>null</code>, 235 * the system default <code>GraphicsConfiguration</code> 236 * is assumed, unless <code>owner</code> is also null, in which 237 * case the <code>GraphicsConfiguration</code> from the 238 * shared owner frame will be used. 239 * @throws HeadlessException if 240 * <code>GraphicsEnvironment.isHeadless()</code> returns true. 241 * @throws IllegalArgumentException if <code>gc</code> is not from 242 * a screen device. 243 * 244 * @see java.awt.GraphicsEnvironment#isHeadless 245 * @see #isFocusableWindow 246 * @see JComponent#getDefaultLocale 247 * 248 * @since 1.3 249 */ 250 public JWindow(Window owner, GraphicsConfiguration gc) { 251 super(owner == null ? (Window)SwingUtilities.getSharedOwnerFrame() : 252 owner, gc); 253 if (owner == null) { 254 WindowListener ownerShutdownListener = 255 SwingUtilities.getSharedOwnerFrameShutdownListener(); 256 addWindowListener(ownerShutdownListener); 257 } 258 windowInit(); 259 } 260 261 /** 262 * Called by the constructors to init the <code>JWindow</code> properly. 263 */ 264 protected void windowInit() { 265 setLocale( JComponent.getDefaultLocale() ); 266 setRootPane(createRootPane()); 267 setRootPaneCheckingEnabled(true); 268 sun.awt.SunToolkit.checkAndSetPolicy(this); 269 } 270 271 /** 272 * Called by the constructor methods to create the default 273 * <code>rootPane</code>. 274 */ 275 protected JRootPane createRootPane() { 276 JRootPane rp = new JRootPane(); 277 // NOTE: this uses setOpaque vs LookAndFeel.installProperty as there 278 // is NO reason for the RootPane not to be opaque. For painting to 279 // work the contentPane must be opaque, therefor the RootPane can 280 // also be opaque. 281 rp.setOpaque(true); 282 return rp; 283 } 284 285 /** 286 * Returns whether calls to <code>add</code> and 287 * <code>setLayout</code> are forwarded to the <code>contentPane</code>. 288 * 289 * @return true if <code>add</code> and <code>setLayout</code> 290 * are forwarded; false otherwise 291 * 292 * @see #addImpl 293 * @see #setLayout 294 * @see #setRootPaneCheckingEnabled 295 * @see javax.swing.RootPaneContainer 296 */ 297 protected boolean isRootPaneCheckingEnabled() { 298 return rootPaneCheckingEnabled; 299 } 300 301 /** 302 * Sets the {@code transferHandler} property, which is a mechanism to 303 * support transfer of data into this component. Use {@code null} 304 * if the component does not support data transfer operations. 305 * <p> 306 * If the system property {@code suppressSwingDropSupport} is {@code false} 307 * (the default) and the current drop target on this component is either 308 * {@code null} or not a user-set drop target, this method will change the 309 * drop target as follows: If {@code newHandler} is {@code null} it will 310 * clear the drop target. If not {@code null} it will install a new 311 * {@code DropTarget}. 312 * <p> 313 * Note: When used with {@code JWindow}, {@code TransferHandler} only 314 * provides data import capability, as the data export related methods 315 * are currently typed to {@code JComponent}. 316 * <p> 317 * Please see 318 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html"> 319 * How to Use Drag and Drop and Data Transfer</a>, a section in 320 * <em>The Java Tutorial</em>, for more information. 321 * 322 * @param newHandler the new {@code TransferHandler} 323 * 324 * @see TransferHandler 325 * @see #getTransferHandler 326 * @see java.awt.Component#setDropTarget 327 * @since 1.6 328 * 329 * @beaninfo 330 * bound: true 331 * hidden: true 332 * description: Mechanism for transfer of data into the component 333 */ 334 public void setTransferHandler(TransferHandler newHandler) { 335 TransferHandler oldHandler = transferHandler; 336 transferHandler = newHandler; 337 SwingUtilities.installSwingDropTargetAsNecessary(this, transferHandler); 338 firePropertyChange("transferHandler", oldHandler, newHandler); 339 } 340 341 /** 342 * Gets the <code>transferHandler</code> property. 343 * 344 * @return the value of the <code>transferHandler</code> property 345 * 346 * @see TransferHandler 347 * @see #setTransferHandler 348 * @since 1.6 349 */ 350 public TransferHandler getTransferHandler() { 351 return transferHandler; 352 } 353 354 /** 355 * Calls <code>paint(g)</code>. This method was overridden to 356 * prevent an unnecessary call to clear the background. 357 * 358 * @param g the <code>Graphics</code> context in which to paint 359 */ 360 public void update(Graphics g) { 361 paint(g); 362 } 363 364 /** 365 * Sets whether calls to <code>add</code> and 366 * <code>setLayout</code> are forwarded to the <code>contentPane</code>. 367 * 368 * @param enabled true if <code>add</code> and <code>setLayout</code> 369 * are forwarded, false if they should operate directly on the 370 * <code>JWindow</code>. 371 * 372 * @see #addImpl 373 * @see #setLayout 374 * @see #isRootPaneCheckingEnabled 375 * @see javax.swing.RootPaneContainer 376 * @beaninfo 377 * hidden: true 378 * description: Whether the add and setLayout methods are forwarded 379 */ 380 protected void setRootPaneCheckingEnabled(boolean enabled) { 381 rootPaneCheckingEnabled = enabled; 382 } 383 384 385 /** 386 * Adds the specified child <code>Component</code>. 387 * This method is overridden to conditionally forward calls to the 388 * <code>contentPane</code>. 389 * By default, children are added to the <code>contentPane</code> instead 390 * of the frame, refer to {@link javax.swing.RootPaneContainer} for 391 * details. 392 * 393 * @param comp the component to be enhanced 394 * @param constraints the constraints to be respected 395 * @param index the index 396 * @exception IllegalArgumentException if <code>index</code> is invalid 397 * @exception IllegalArgumentException if adding the container's parent 398 * to itself 399 * @exception IllegalArgumentException if adding a window to a container 400 * 401 * @see #setRootPaneCheckingEnabled 402 * @see javax.swing.RootPaneContainer 403 */ 404 protected void addImpl(Component comp, Object constraints, int index) 405 { 406 if(isRootPaneCheckingEnabled()) { 407 getContentPane().add(comp, constraints, index); 408 } 409 else { 410 super.addImpl(comp, constraints, index); 411 } 412 } 413 414 /** 415 * Removes the specified component from the container. If 416 * <code>comp</code> is not the <code>rootPane</code>, this will forward 417 * the call to the <code>contentPane</code>. This will do nothing if 418 * <code>comp</code> is not a child of the <code>JWindow</code> or 419 * <code>contentPane</code>. 420 * 421 * @param comp the component to be removed 422 * @throws NullPointerException if <code>comp</code> is null 423 * @see #add 424 * @see javax.swing.RootPaneContainer 425 */ 426 public void remove(Component comp) { 427 if (comp == rootPane) { 428 super.remove(comp); 429 } else { 430 getContentPane().remove(comp); 431 } 432 } 433 434 435 /** 436 * Sets the <code>LayoutManager</code>. 437 * Overridden to conditionally forward the call to the 438 * <code>contentPane</code>. 439 * Refer to {@link javax.swing.RootPaneContainer} for 440 * more information. 441 * 442 * @param manager the <code>LayoutManager</code> 443 * @see #setRootPaneCheckingEnabled 444 * @see javax.swing.RootPaneContainer 445 */ 446 public void setLayout(LayoutManager manager) { 447 if(isRootPaneCheckingEnabled()) { 448 getContentPane().setLayout(manager); 449 } 450 else { 451 super.setLayout(manager); 452 } 453 } 454 455 456 /** 457 * Returns the <code>rootPane</code> object for this window. 458 * @return the <code>rootPane</code> property for this window 459 * 460 * @see #setRootPane 461 * @see RootPaneContainer#getRootPane 462 */ 463 public JRootPane getRootPane() { 464 return rootPane; 465 } 466 467 468 /** 469 * Sets the new <code>rootPane</code> object for this window. 470 * This method is called by the constructor. 471 * 472 * @param root the new <code>rootPane</code> property 473 * @see #getRootPane 474 * 475 * @beaninfo 476 * hidden: true 477 * description: the RootPane object for this window. 478 */ 479 protected void setRootPane(JRootPane root) { 480 if(rootPane != null) { 481 remove(rootPane); 482 } 483 rootPane = root; 484 if(rootPane != null) { 485 boolean checkingEnabled = isRootPaneCheckingEnabled(); 486 try { 487 setRootPaneCheckingEnabled(false); 488 add(rootPane, BorderLayout.CENTER); 489 } 490 finally { 491 setRootPaneCheckingEnabled(checkingEnabled); 492 } 493 } 494 } 495 496 497 /** 498 * Returns the <code>Container</code> which is the <code>contentPane</code> 499 * for this window. 500 * 501 * @return the <code>contentPane</code> property 502 * @see #setContentPane 503 * @see RootPaneContainer#getContentPane 504 */ 505 public Container getContentPane() { 506 return getRootPane().getContentPane(); 507 } 508 509 /** 510 * Sets the <code>contentPane</code> property for this window. 511 * This method is called by the constructor. 512 * 513 * @param contentPane the new <code>contentPane</code> 514 * 515 * @exception IllegalComponentStateException (a runtime 516 * exception) if the content pane parameter is <code>null</code> 517 * @see #getContentPane 518 * @see RootPaneContainer#setContentPane 519 * 520 * @beaninfo 521 * hidden: true 522 * description: The client area of the window where child 523 * components are normally inserted. 524 */ 525 public void setContentPane(Container contentPane) { 526 getRootPane().setContentPane(contentPane); 527 } 528 529 /** 530 * Returns the <code>layeredPane</code> object for this window. 531 * 532 * @return the <code>layeredPane</code> property 533 * @see #setLayeredPane 534 * @see RootPaneContainer#getLayeredPane 535 */ 536 public JLayeredPane getLayeredPane() { 537 return getRootPane().getLayeredPane(); 538 } 539 540 /** 541 * Sets the <code>layeredPane</code> property. 542 * This method is called by the constructor. 543 * 544 * @param layeredPane the new <code>layeredPane</code> object 545 * 546 * @exception IllegalComponentStateException (a runtime 547 * exception) if the content pane parameter is <code>null</code> 548 * @see #getLayeredPane 549 * @see RootPaneContainer#setLayeredPane 550 * 551 * @beaninfo 552 * hidden: true 553 * description: The pane which holds the various window layers. 554 */ 555 public void setLayeredPane(JLayeredPane layeredPane) { 556 getRootPane().setLayeredPane(layeredPane); 557 } 558 559 /** 560 * Returns the <code>glassPane Component</code> for this window. 561 * 562 * @return the <code>glassPane</code> property 563 * @see #setGlassPane 564 * @see RootPaneContainer#getGlassPane 565 */ 566 public Component getGlassPane() { 567 return getRootPane().getGlassPane(); 568 } 569 570 /** 571 * Sets the <code>glassPane</code> property. 572 * This method is called by the constructor. 573 * @param glassPane the <code>glassPane</code> object for this window 574 * 575 * @see #getGlassPane 576 * @see RootPaneContainer#setGlassPane 577 * 578 * @beaninfo 579 * hidden: true 580 * description: A transparent pane used for menu rendering. 581 */ 582 public void setGlassPane(Component glassPane) { 583 getRootPane().setGlassPane(glassPane); 584 } 585 586 /** 587 * {@inheritDoc} 588 * 589 * @since 1.6 590 */ 591 public Graphics getGraphics() { 592 JComponent.getGraphicsInvoked(this); 593 return super.getGraphics(); 594 } 595 596 /** 597 * Repaints the specified rectangle of this component within 598 * <code>time</code> milliseconds. Refer to <code>RepaintManager</code> 599 * for details on how the repaint is handled. 600 * 601 * @param time maximum time in milliseconds before update 602 * @param x the <i>x</i> coordinate 603 * @param y the <i>y</i> coordinate 604 * @param width the width 605 * @param height the height 606 * @see RepaintManager 607 * @since 1.6 608 */ 609 public void repaint(long time, int x, int y, int width, int height) { 610 if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) { 611 RepaintManager.currentManager(this).addDirtyRegion( 612 this, x, y, width, height); 613 } 614 else { 615 super.repaint(time, x, y, width, height); 616 } 617 } 618 619 /** 620 * Returns a string representation of this <code>JWindow</code>. 621 * This method 622 * is intended to be used only for debugging purposes, and the 623 * content and format of the returned string may vary between 624 * implementations. The returned string may be empty but may not 625 * be <code>null</code>. 626 * 627 * @return a string representation of this <code>JWindow</code> 628 */ 629 protected String paramString() { 630 String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ? 631 "true" : "false"); 632 633 return super.paramString() + 634 ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString; 635 } 636 637 638 ///////////////// 639 // Accessibility support 640 //////////////// 641 642 /** The accessible context property. */ 643 protected AccessibleContext accessibleContext = null; 644 645 /** 646 * Gets the AccessibleContext associated with this JWindow. 647 * For JWindows, the AccessibleContext takes the form of an 648 * AccessibleJWindow. 649 * A new AccessibleJWindow instance is created if necessary. 650 * 651 * @return an AccessibleJWindow that serves as the 652 * AccessibleContext of this JWindow 653 */ 654 public AccessibleContext getAccessibleContext() { 655 if (accessibleContext == null) { 656 accessibleContext = new AccessibleJWindow(); 657 } 658 return accessibleContext; 659 } 660 661 662 /** 663 * This class implements accessibility support for the 664 * <code>JWindow</code> class. It provides an implementation of the 665 * Java Accessibility API appropriate to window user-interface 666 * elements. 667 */ 668 @SuppressWarnings("serial") 669 protected class AccessibleJWindow extends AccessibleAWTWindow { 670 // everything is in the new parent, AccessibleAWTWindow 671 } 672 673 }