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