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.applet.Applet;
  28 import java.awt.*;
  29 import java.awt.event.*;
  30 import java.beans.*;
  31 import java.security.AccessController;
  32 import javax.accessibility.*;
  33 import javax.swing.plaf.RootPaneUI;
  34 import java.util.Vector;
  35 import java.io.Serializable;
  36 import javax.swing.border.*;
  37 import sun.awt.AWTAccessor;
  38 import sun.security.action.GetBooleanAction;
  39 
  40 
  41 /**
  42  * A lightweight container used behind the scenes by
  43  * <code>JFrame</code>, <code>JDialog</code>, <code>JWindow</code>,
  44  * <code>JApplet</code>, and <code>JInternalFrame</code>.
  45  * For task-oriented information on functionality provided by root panes
  46  * see <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html">How to Use Root Panes</a>,
  47  * a section in <em>The Java Tutorial</em>.
  48  *
  49  * <p>
  50  * The following image shows the relationships between
  51  * the classes that use root panes.
  52  * <p style="text-align:center"><img src="doc-files/JRootPane-1.gif"
  53  * alt="The following text describes this graphic."
  54  * HEIGHT=484 WIDTH=629></p>
  55  * The &quot;heavyweight&quot; components (those that delegate to a peer, or native
  56  * component on the host system) are shown with a darker, heavier box. The four
  57  * heavyweight JFC/Swing containers (<code>JFrame</code>, <code>JDialog</code>,
  58  * <code>JWindow</code>, and <code>JApplet</code>) are
  59  * shown in relation to the AWT classes they extend.
  60  * These four components are the
  61  * only heavyweight containers in the Swing library. The lightweight container
  62  * <code>JInternalFrame</code> is also shown.
  63  * All five of these JFC/Swing containers implement the
  64  * <code>RootPaneContainer</code> interface,
  65  * and they all delegate their operations to a
  66  * <code>JRootPane</code> (shown with a little "handle" on top).
  67  * <blockquote>
  68  * <b>Note:</b> The <code>JComponent</code> method <code>getRootPane</code>
  69  * can be used to obtain the <code>JRootPane</code> that contains
  70  * a given component.
  71  * </blockquote>
  72  * <table style="float:right" border="0" summary="layout">
  73  * <tr>
  74  * <td align="center">
  75  * <img src="doc-files/JRootPane-2.gif"
  76  * alt="The following text describes this graphic." HEIGHT=386 WIDTH=349>
  77  * </td>
  78  * </tr>
  79  * </table>
  80  * The diagram at right shows the structure of a <code>JRootPane</code>.
  81  * A <code>JRootpane</code> is made up of a <code>glassPane</code>,
  82  * an optional <code>menuBar</code>, and a <code>contentPane</code>.
  83  * (The <code>JLayeredPane</code> manages the <code>menuBar</code>
  84  * and the <code>contentPane</code>.)
  85  * The <code>glassPane</code> sits over the top of everything,
  86  * where it is in a position to intercept mouse movements.
  87  * Since the <code>glassPane</code> (like the <code>contentPane</code>)
  88  * can be an arbitrary component, it is also possible to set up the
  89  * <code>glassPane</code> for drawing. Lines and images on the
  90  * <code>glassPane</code> can then range
  91  * over the frames underneath without being limited by their boundaries.
  92  * <p>
  93  * Although the <code>menuBar</code> component is optional,
  94  * the <code>layeredPane</code>, <code>contentPane</code>,
  95  * and <code>glassPane</code> always exist.
  96  * Attempting to set them to <code>null</code> generates an exception.
  97  * <p>
  98  * To add components to the <code>JRootPane</code> (other than the
  99  * optional menu bar), you add the object to the <code>contentPane</code>
 100  * of the <code>JRootPane</code>, like this:
 101  * <pre>
 102  *       rootPane.getContentPane().add(child);
 103  * </pre>
 104  * The same principle holds true for setting layout managers, removing
 105  * components, listing children, etc. All these methods are invoked on
 106  * the <code>contentPane</code> instead of on the <code>JRootPane</code>.
 107  * <blockquote>
 108  * <b>Note:</b> The default layout manager for the <code>contentPane</code> is
 109  *  a <code>BorderLayout</code> manager. However, the <code>JRootPane</code>
 110  *  uses a custom <code>LayoutManager</code>.
 111  *  So, when you want to change the layout manager for the components you added
 112  *  to a <code>JRootPane</code>, be sure to use code like this:
 113  * <pre>
 114  *    rootPane.getContentPane().setLayout(new BoxLayout());
 115  * </pre></blockquote>
 116  * If a <code>JMenuBar</code> component is set on the <code>JRootPane</code>,
 117  * it is positioned along the upper edge of the frame.
 118  * The <code>contentPane</code> is adjusted in location and size to
 119  * fill the remaining area.
 120  * (The <code>JMenuBar</code> and the <code>contentPane</code> are added to the
 121  * <code>layeredPane</code> component at the
 122  * <code>JLayeredPane.FRAME_CONTENT_LAYER</code> layer.)
 123  * <p>
 124  * The <code>layeredPane</code> is the parent of all children in the
 125  * <code>JRootPane</code> -- both as the direct parent of the menu and
 126  * the grandparent of all components added to the <code>contentPane</code>.
 127  * It is an instance of <code>JLayeredPane</code>,
 128  * which provides the ability to add components at several layers.
 129  * This capability is very useful when working with menu popups,
 130  * dialog boxes, and dragging -- situations in which you need to place
 131  * a component on top of all other components in the pane.
 132  * <p>
 133  * The <code>glassPane</code> sits on top of all other components in the
 134  * <code>JRootPane</code>.
 135  * That provides a convenient place to draw above all other components,
 136  * and makes it possible to intercept mouse events,
 137  * which is useful both for dragging and for drawing.
 138  * Developers can use <code>setVisible</code> on the <code>glassPane</code>
 139  * to control when the <code>glassPane</code> displays over the other children.
 140  * By default the <code>glassPane</code> is not visible.
 141  * <p>
 142  * The custom <code>LayoutManager</code> used by <code>JRootPane</code>
 143  * ensures that:
 144  * <OL>
 145  * <LI>The <code>glassPane</code> fills the entire viewable
 146  *     area of the <code>JRootPane</code> (bounds - insets).
 147  * <LI>The <code>layeredPane</code> fills the entire viewable area of the
 148  *     <code>JRootPane</code>. (bounds - insets)
 149  * <LI>The <code>menuBar</code> is positioned at the upper edge of the
 150  *     <code>layeredPane</code>.
 151  * <LI>The <code>contentPane</code> fills the entire viewable area,
 152  *     minus the <code>menuBar</code>, if present.
 153  * </OL>
 154  * Any other views in the <code>JRootPane</code> view hierarchy are ignored.
 155  * <p>
 156  * If you replace the <code>LayoutManager</code> of the <code>JRootPane</code>,
 157  * you are responsible for managing all of these views.
 158  * So ordinarily you will want to be sure that you
 159  * change the layout manager for the <code>contentPane</code> rather than
 160  * for the <code>JRootPane</code> itself!
 161  * <p>
 162  * The painting architecture of Swing requires an opaque
 163  * <code>JComponent</code>
 164  * to exist in the containment hierarchy above all other components. This is
 165  * typically provided by way of the content pane. If you replace the content
 166  * pane, it is recommended that you make the content pane opaque
 167  * by way of <code>setOpaque(true)</code>. Additionally, if the content pane
 168  * overrides <code>paintComponent</code>, it
 169  * will need to completely fill in the background in an opaque color in
 170  * <code>paintComponent</code>.
 171  * <p>
 172  * <strong>Warning:</strong> Swing is not thread safe. For more
 173  * information see <a
 174  * href="package-summary.html#threading">Swing's Threading
 175  * Policy</a>.
 176  * <p>
 177  * <strong>Warning:</strong>
 178  * Serialized objects of this class will not be compatible with
 179  * future Swing releases. The current serialization support is
 180  * appropriate for short term storage or RMI between applications running
 181  * the same version of Swing.  As of 1.4, support for long term storage
 182  * of all JavaBeans&trade;
 183  * has been added to the <code>java.beans</code> package.
 184  * Please see {@link java.beans.XMLEncoder}.
 185  *
 186  * @see JLayeredPane
 187  * @see JMenuBar
 188  * @see JWindow
 189  * @see JFrame
 190  * @see JDialog
 191  * @see JApplet
 192  * @see JInternalFrame
 193  * @see JComponent
 194  * @see BoxLayout
 195  *
 196  * @see <a href="http://java.sun.com/products/jfc/tsc/articles/mixing/">
 197  * Mixing Heavy and Light Components</a>
 198  *
 199  * @author David Kloba
 200  * @since 1.2
 201  */
 202 /// PENDING(klobad) Who should be opaque in this component?
 203 @SuppressWarnings("serial")
 204 public class JRootPane extends JComponent implements Accessible {
 205 
 206     private static final String uiClassID = "RootPaneUI";
 207 
 208     /**
 209      * Whether or not we should dump the stack when true double buffering
 210      * is disabled. Default is false.
 211      */
 212     private static final boolean LOG_DISABLE_TRUE_DOUBLE_BUFFERING;
 213 
 214     /**
 215      * Whether or not we should ignore requests to disable true double
 216      * buffering. Default is false.
 217      */
 218     private static final boolean IGNORE_DISABLE_TRUE_DOUBLE_BUFFERING;
 219 
 220     /**
 221      * Constant used for the windowDecorationStyle property. Indicates that
 222      * the <code>JRootPane</code> should not provide any sort of
 223      * Window decorations.
 224      *
 225      * @since 1.4
 226      */
 227     public static final int NONE = 0;
 228 
 229     /**
 230      * Constant used for the windowDecorationStyle property. Indicates that
 231      * the <code>JRootPane</code> should provide decorations appropriate for
 232      * a Frame.
 233      *
 234      * @since 1.4
 235      */
 236     public static final int FRAME = 1;
 237 
 238     /**
 239      * Constant used for the windowDecorationStyle property. Indicates that
 240      * the <code>JRootPane</code> should provide decorations appropriate for
 241      * a Dialog.
 242      *
 243      * @since 1.4
 244      */
 245     public static final int PLAIN_DIALOG = 2;
 246 
 247     /**
 248      * Constant used for the windowDecorationStyle property. Indicates that
 249      * the <code>JRootPane</code> should provide decorations appropriate for
 250      * a Dialog used to display an informational message.
 251      *
 252      * @since 1.4
 253      */
 254     public static final int INFORMATION_DIALOG = 3;
 255 
 256     /**
 257      * Constant used for the windowDecorationStyle property. Indicates that
 258      * the <code>JRootPane</code> should provide decorations appropriate for
 259      * a Dialog used to display an error message.
 260      *
 261      * @since 1.4
 262      */
 263     public static final int ERROR_DIALOG = 4;
 264 
 265     /**
 266      * Constant used for the windowDecorationStyle property. Indicates that
 267      * the <code>JRootPane</code> should provide decorations appropriate for
 268      * a Dialog used to display a <code>JColorChooser</code>.
 269      *
 270      * @since 1.4
 271      */
 272     public static final int COLOR_CHOOSER_DIALOG = 5;
 273 
 274     /**
 275      * Constant used for the windowDecorationStyle property. Indicates that
 276      * the <code>JRootPane</code> should provide decorations appropriate for
 277      * a Dialog used to display a <code>JFileChooser</code>.
 278      *
 279      * @since 1.4
 280      */
 281     public static final int FILE_CHOOSER_DIALOG = 6;
 282 
 283     /**
 284      * Constant used for the windowDecorationStyle property. Indicates that
 285      * the <code>JRootPane</code> should provide decorations appropriate for
 286      * a Dialog used to present a question to the user.
 287      *
 288      * @since 1.4
 289      */
 290     public static final int QUESTION_DIALOG = 7;
 291 
 292     /**
 293      * Constant used for the windowDecorationStyle property. Indicates that
 294      * the <code>JRootPane</code> should provide decorations appropriate for
 295      * a Dialog used to display a warning message.
 296      *
 297      * @since 1.4
 298      */
 299     public static final int WARNING_DIALOG = 8;
 300 
 301     private int windowDecorationStyle;
 302 
 303     /** The menu bar. */
 304     protected JMenuBar menuBar;
 305 
 306     /** The content pane. */
 307     protected Container contentPane;
 308 
 309     /** The layered pane that manages the menu bar and content pane. */
 310     protected JLayeredPane layeredPane;
 311 
 312     /**
 313      * The glass pane that overlays the menu bar and content pane,
 314      *  so it can intercept mouse movements and such.
 315      */
 316     protected Component glassPane;
 317     /**
 318      * The button that gets activated when the pane has the focus and
 319      * a UI-specific action like pressing the <b>Enter</b> key occurs.
 320      */
 321     protected JButton defaultButton;
 322     /**
 323      * As of Java 2 platform v1.3 this unusable field is no longer used.
 324      * To override the default button you should replace the <code>Action</code>
 325      * in the <code>JRootPane</code>'s <code>ActionMap</code>. Please refer to
 326      * the key bindings specification for further details.
 327      *
 328      * @deprecated As of Java 2 platform v1.3.
 329      *  @see #defaultButton
 330      */
 331     @Deprecated
 332     protected DefaultAction defaultPressAction;
 333     /**
 334      * As of Java 2 platform v1.3 this unusable field is no longer used.
 335      * To override the default button you should replace the <code>Action</code>
 336      * in the <code>JRootPane</code>'s <code>ActionMap</code>. Please refer to
 337      * the key bindings specification for further details.
 338      *
 339      * @deprecated As of Java 2 platform v1.3.
 340      *  @see #defaultButton
 341      */
 342     @Deprecated
 343     protected DefaultAction defaultReleaseAction;
 344 
 345     /**
 346      * Whether or not true double buffering should be used.  This is typically
 347      * true, but may be set to false in special situations.  For example,
 348      * heavy weight popups (backed by a window) set this to false.
 349      */
 350     boolean useTrueDoubleBuffering = true;
 351 
 352     static {
 353         LOG_DISABLE_TRUE_DOUBLE_BUFFERING =
 354             AccessController.doPrivileged(new GetBooleanAction(
 355                                    "swing.logDoubleBufferingDisable"));
 356         IGNORE_DISABLE_TRUE_DOUBLE_BUFFERING =
 357             AccessController.doPrivileged(new GetBooleanAction(
 358                                    "swing.ignoreDoubleBufferingDisable"));
 359     }
 360 
 361     /**
 362      * Creates a <code>JRootPane</code>, setting up its
 363      * <code>glassPane</code>, <code>layeredPane</code>,
 364      * and <code>contentPane</code>.
 365      */
 366     public JRootPane() {
 367         setGlassPane(createGlassPane());
 368         setLayeredPane(createLayeredPane());
 369         setContentPane(createContentPane());
 370         setLayout(createRootLayout());
 371         setDoubleBuffered(true);
 372         updateUI();
 373     }
 374 
 375     /**
 376      * {@inheritDoc}
 377      * @since 1.6
 378      */
 379     public void setDoubleBuffered(boolean aFlag) {
 380         if (isDoubleBuffered() != aFlag) {
 381             super.setDoubleBuffered(aFlag);
 382             RepaintManager.currentManager(this).doubleBufferingChanged(this);
 383         }
 384     }
 385 
 386     /**
 387      * Returns a constant identifying the type of Window decorations the
 388      * <code>JRootPane</code> is providing.
 389      *
 390      * @return One of <code>NONE</code>, <code>FRAME</code>,
 391      *        <code>PLAIN_DIALOG</code>, <code>INFORMATION_DIALOG</code>,
 392      *        <code>ERROR_DIALOG</code>, <code>COLOR_CHOOSER_DIALOG</code>,
 393      *        <code>FILE_CHOOSER_DIALOG</code>, <code>QUESTION_DIALOG</code> or
 394      *        <code>WARNING_DIALOG</code>.
 395      * @see #setWindowDecorationStyle
 396      * @since 1.4
 397      */
 398     public int getWindowDecorationStyle() {
 399         return windowDecorationStyle;
 400     }
 401 
 402     /**
 403      * Sets the type of Window decorations (such as borders, widgets for
 404      * closing a Window, title ...) the <code>JRootPane</code> should
 405      * provide. The default is to provide no Window decorations
 406      * (<code>NONE</code>).
 407      * <p>
 408      * This is only a hint, and some look and feels may not support
 409      * this.
 410      * This is a bound property.
 411      *
 412      * @param windowDecorationStyle Constant identifying Window decorations
 413      *        to provide.
 414      * @see JDialog#setDefaultLookAndFeelDecorated
 415      * @see JFrame#setDefaultLookAndFeelDecorated
 416      * @see LookAndFeel#getSupportsWindowDecorations
 417      * @throws IllegalArgumentException if <code>style</code> is
 418      *        not one of: <code>NONE</code>, <code>FRAME</code>,
 419      *        <code>PLAIN_DIALOG</code>, <code>INFORMATION_DIALOG</code>,
 420      *        <code>ERROR_DIALOG</code>, <code>COLOR_CHOOSER_DIALOG</code>,
 421      *        <code>FILE_CHOOSER_DIALOG</code>, <code>QUESTION_DIALOG</code>, or
 422      *        <code>WARNING_DIALOG</code>.
 423      * @since 1.4
 424      * @beaninfo
 425      *        bound: true
 426      *         enum: NONE                   JRootPane.NONE
 427      *               FRAME                  JRootPane.FRAME
 428      *               PLAIN_DIALOG           JRootPane.PLAIN_DIALOG
 429      *               INFORMATION_DIALOG     JRootPane.INFORMATION_DIALOG
 430      *               ERROR_DIALOG           JRootPane.ERROR_DIALOG
 431      *               COLOR_CHOOSER_DIALOG   JRootPane.COLOR_CHOOSER_DIALOG
 432      *               FILE_CHOOSER_DIALOG    JRootPane.FILE_CHOOSER_DIALOG
 433      *               QUESTION_DIALOG        JRootPane.QUESTION_DIALOG
 434      *               WARNING_DIALOG         JRootPane.WARNING_DIALOG
 435      *       expert: true
 436      *    attribute: visualUpdate true
 437      *  description: Identifies the type of Window decorations to provide
 438      */
 439     public void setWindowDecorationStyle(int windowDecorationStyle) {
 440         if (windowDecorationStyle < 0 ||
 441                   windowDecorationStyle > WARNING_DIALOG) {
 442             throw new IllegalArgumentException("Invalid decoration style");
 443         }
 444         int oldWindowDecorationStyle = getWindowDecorationStyle();
 445         this.windowDecorationStyle = windowDecorationStyle;
 446         firePropertyChange("windowDecorationStyle",
 447                             oldWindowDecorationStyle,
 448                             windowDecorationStyle);
 449     }
 450 
 451     /**
 452      * Returns the L&amp;F object that renders this component.
 453      *
 454      * @return <code>LabelUI</code> object
 455      * @since 1.3
 456      */
 457     public RootPaneUI getUI() {
 458         return (RootPaneUI)ui;
 459     }
 460 
 461     /**
 462      * Sets the L&amp;F object that renders this component.
 463      *
 464      * @param ui  the <code>LabelUI</code> L&amp;F object
 465      * @see UIDefaults#getUI
 466      * @beaninfo
 467      *        bound: true
 468      *       hidden: true
 469      *      expert: true
 470      *    attribute: visualUpdate true
 471      *  description: The UI object that implements the Component's LookAndFeel.
 472      * @since 1.3
 473      */
 474     public void setUI(RootPaneUI ui) {
 475         super.setUI(ui);
 476     }
 477 
 478 
 479     /**
 480      * Resets the UI property to a value from the current look and feel.
 481      *
 482      * @see JComponent#updateUI
 483      */
 484     public void updateUI() {
 485         setUI((RootPaneUI)UIManager.getUI(this));
 486     }
 487 
 488 
 489     /**
 490      * Returns a string that specifies the name of the L&amp;F class
 491      * that renders this component.
 492      *
 493      * @return the string "RootPaneUI"
 494      *
 495      * @see JComponent#getUIClassID
 496      * @see UIDefaults#getUI
 497      */
 498     public String getUIClassID() {
 499         return uiClassID;
 500     }
 501 
 502     /**
 503       * Called by the constructor methods to create the default
 504       * <code>layeredPane</code>.
 505       * Bt default it creates a new <code>JLayeredPane</code>.
 506       * @return the default <code>layeredPane</code>
 507       */
 508     protected JLayeredPane createLayeredPane() {
 509         JLayeredPane p = new JLayeredPane();
 510         p.setName(this.getName()+".layeredPane");
 511         return p;
 512     }
 513 
 514     /**
 515      * Called by the constructor methods to create the default
 516      * <code>contentPane</code>.
 517      * By default this method creates a new <code>JComponent</code> add sets a
 518      * <code>BorderLayout</code> as its <code>LayoutManager</code>.
 519      * @return the default <code>contentPane</code>
 520      */
 521     protected Container createContentPane() {
 522         JComponent c = new JPanel();
 523         c.setName(this.getName()+".contentPane");
 524         c.setLayout(new BorderLayout() {
 525             /* This BorderLayout subclass maps a null constraint to CENTER.
 526              * Although the reference BorderLayout also does this, some VMs
 527              * throw an IllegalArgumentException.
 528              */
 529             public void addLayoutComponent(Component comp, Object constraints) {
 530                 if (constraints == null) {
 531                     constraints = BorderLayout.CENTER;
 532                 }
 533                 super.addLayoutComponent(comp, constraints);
 534             }
 535         });
 536         return c;
 537     }
 538 
 539     /**
 540       * Called by the constructor methods to create the default
 541       * <code>glassPane</code>.
 542       * By default this method creates a new <code>JComponent</code>
 543       * with visibility set to false.
 544       * @return the default <code>glassPane</code>
 545       */
 546     protected Component createGlassPane() {
 547         JComponent c = new JPanel();
 548         c.setName(this.getName()+".glassPane");
 549         c.setVisible(false);
 550         ((JPanel)c).setOpaque(false);
 551         return c;
 552     }
 553 
 554     /**
 555      * Called by the constructor methods to create the default
 556      * <code>layoutManager</code>.
 557      * @return the default <code>layoutManager</code>.
 558      */
 559     protected LayoutManager createRootLayout() {
 560         return new RootLayout();
 561     }
 562 
 563     /**
 564      * Adds or changes the menu bar used in the layered pane.
 565      * @param menu the <code>JMenuBar</code> to add
 566      */
 567     public void setJMenuBar(JMenuBar menu) {
 568         if(menuBar != null && menuBar.getParent() == layeredPane)
 569             layeredPane.remove(menuBar);
 570         menuBar = menu;
 571 
 572         if(menuBar != null)
 573             layeredPane.add(menuBar, JLayeredPane.FRAME_CONTENT_LAYER);
 574     }
 575 
 576     /**
 577      * Specifies the menu bar value.
 578      * @deprecated As of Swing version 1.0.3
 579      *  replaced by <code>setJMenuBar(JMenuBar menu)</code>.
 580      * @param menu the <code>JMenuBar</code> to add.
 581      */
 582     @Deprecated
 583     public void setMenuBar(JMenuBar menu){
 584         if(menuBar != null && menuBar.getParent() == layeredPane)
 585             layeredPane.remove(menuBar);
 586         menuBar = menu;
 587 
 588         if(menuBar != null)
 589             layeredPane.add(menuBar, JLayeredPane.FRAME_CONTENT_LAYER);
 590     }
 591 
 592     /**
 593      * Returns the menu bar from the layered pane.
 594      * @return the <code>JMenuBar</code> used in the pane
 595      */
 596     public JMenuBar getJMenuBar() { return menuBar; }
 597 
 598     /**
 599      * Returns the menu bar value.
 600      * @deprecated As of Swing version 1.0.3
 601      *  replaced by <code>getJMenuBar()</code>.
 602      * @return the <code>JMenuBar</code> used in the pane
 603      */
 604     @Deprecated
 605     public JMenuBar getMenuBar() { return menuBar; }
 606 
 607     /**
 608      * Sets the content pane -- the container that holds the components
 609      * parented by the root pane.
 610      * <p>
 611      * Swing's painting architecture requires an opaque <code>JComponent</code>
 612      * in the containment hierarchy. This is typically provided by the
 613      * content pane. If you replace the content pane it is recommended you
 614      * replace it with an opaque <code>JComponent</code>.
 615      *
 616      * @param content the <code>Container</code> to use for component-contents
 617      * @exception java.awt.IllegalComponentStateException (a runtime
 618      *            exception) if the content pane parameter is <code>null</code>
 619      */
 620     public void setContentPane(Container content) {
 621         if(content == null)
 622             throw new IllegalComponentStateException("contentPane cannot be set to null.");
 623         if(contentPane != null && contentPane.getParent() == layeredPane)
 624             layeredPane.remove(contentPane);
 625         contentPane = content;
 626 
 627         layeredPane.add(contentPane, JLayeredPane.FRAME_CONTENT_LAYER);
 628     }
 629 
 630     /**
 631      * Returns the content pane -- the container that holds the components
 632      * parented by the root pane.
 633      *
 634      * @return the <code>Container</code> that holds the component-contents
 635      */
 636     public Container getContentPane() { return contentPane; }
 637 
 638 // PENDING(klobad) Should this reparent the contentPane and MenuBar?
 639     /**
 640      * Sets the layered pane for the root pane. The layered pane
 641      * typically holds a content pane and an optional <code>JMenuBar</code>.
 642      *
 643      * @param layered  the <code>JLayeredPane</code> to use
 644      * @exception java.awt.IllegalComponentStateException (a runtime
 645      *            exception) if the layered pane parameter is <code>null</code>
 646      */
 647     public void setLayeredPane(JLayeredPane layered) {
 648         if(layered == null)
 649             throw new IllegalComponentStateException("layeredPane cannot be set to null.");
 650         if(layeredPane != null && layeredPane.getParent() == this)
 651             this.remove(layeredPane);
 652         layeredPane = layered;
 653 
 654         this.add(layeredPane, -1);
 655     }
 656     /**
 657      * Gets the layered pane used by the root pane. The layered pane
 658      * typically holds a content pane and an optional <code>JMenuBar</code>.
 659      *
 660      * @return the <code>JLayeredPane</code> currently in use
 661      */
 662     public JLayeredPane getLayeredPane() { return layeredPane; }
 663 
 664     /**
 665      * Sets a specified <code>Component</code> to be the glass pane for this
 666      * root pane.  The glass pane should normally be a lightweight,
 667      * transparent component, because it will be made visible when
 668      * ever the root pane needs to grab input events.
 669      * <p>
 670      * The new glass pane's visibility is changed to match that of
 671      * the current glass pane.  An implication of this is that care
 672      * must be taken when you want to replace the glass pane and
 673      * make it visible.  Either of the following will work:
 674      * <pre>
 675      *   root.setGlassPane(newGlassPane);
 676      *   newGlassPane.setVisible(true);
 677      * </pre>
 678      * or:
 679      * <pre>
 680      *   root.getGlassPane().setVisible(true);
 681      *   root.setGlassPane(newGlassPane);
 682      * </pre>
 683      *
 684      * @param glass the <code>Component</code> to use as the glass pane
 685      *              for this <code>JRootPane</code>
 686      * @exception NullPointerException if the <code>glass</code> parameter is
 687      *          <code>null</code>
 688      */
 689     public void setGlassPane(Component glass) {
 690         if (glass == null) {
 691             throw new NullPointerException("glassPane cannot be set to null.");
 692         }
 693 
 694         AWTAccessor.getComponentAccessor().setMixingCutoutShape(glass,
 695                 new Rectangle());
 696 
 697         boolean visible = false;
 698         if (glassPane != null && glassPane.getParent() == this) {
 699             this.remove(glassPane);
 700             visible = glassPane.isVisible();
 701         }
 702 
 703         glass.setVisible(visible);
 704         glassPane = glass;
 705         this.add(glassPane, 0);
 706         if (visible) {
 707             repaint();
 708         }
 709     }
 710 
 711     /**
 712      * Returns the current glass pane for this <code>JRootPane</code>.
 713      * @return the current glass pane
 714      * @see #setGlassPane
 715      */
 716     public Component getGlassPane() {
 717         return glassPane;
 718     }
 719 
 720     /**
 721      * If a descendant of this <code>JRootPane</code> calls
 722      * <code>revalidate</code>, validate from here on down.
 723      *<p>
 724      * Deferred requests to layout a component and its descendents again.
 725      * For example, calls to <code>revalidate</code>, are pushed upwards to
 726      * either a <code>JRootPane</code> or a <code>JScrollPane</code>
 727      * because both classes override <code>isValidateRoot</code> to return true.
 728      *
 729      * @see JComponent#isValidateRoot
 730      * @see java.awt.Container#isValidateRoot
 731      * @return true
 732      */
 733     @Override
 734     public boolean isValidateRoot() {
 735         return true;
 736     }
 737 
 738     /**
 739      * The <code>glassPane</code> and <code>contentPane</code>
 740      * have the same bounds, which means <code>JRootPane</code>
 741      * does not tiles its children and this should return false.
 742      * On the other hand, the <code>glassPane</code>
 743      * is normally not visible, and so this can return true if the
 744      * <code>glassPane</code> isn't visible. Therefore, the
 745      * return value here depends upon the visibility of the
 746      * <code>glassPane</code>.
 747      *
 748      * @return true if this component's children don't overlap
 749      */
 750     public boolean isOptimizedDrawingEnabled() {
 751         return !glassPane.isVisible();
 752     }
 753 
 754     /**
 755      * {@inheritDoc}
 756      */
 757     public void addNotify() {
 758         super.addNotify();
 759         enableEvents(AWTEvent.KEY_EVENT_MASK);
 760     }
 761 
 762     /**
 763      * {@inheritDoc}
 764      */
 765     public void removeNotify() {
 766         super.removeNotify();
 767     }
 768 
 769 
 770     /**
 771      * Sets the <code>defaultButton</code> property,
 772      * which determines the current default button for this <code>JRootPane</code>.
 773      * The default button is the button which will be activated
 774      * when a UI-defined activation event (typically the <b>Enter</b> key)
 775      * occurs in the root pane regardless of whether or not the button
 776      * has keyboard focus (unless there is another component within
 777      * the root pane which consumes the activation event,
 778      * such as a <code>JTextPane</code>).
 779      * For default activation to work, the button must be an enabled
 780      * descendent of the root pane when activation occurs.
 781      * To remove a default button from this root pane, set this
 782      * property to <code>null</code>.
 783      *
 784      * @see JButton#isDefaultButton
 785      * @param defaultButton the <code>JButton</code> which is to be the default button
 786      *
 787      * @beaninfo
 788      *  description: The button activated by default in this root pane
 789      */
 790     public void setDefaultButton(JButton defaultButton) {
 791         JButton oldDefault = this.defaultButton;
 792 
 793         if (oldDefault != defaultButton) {
 794             this.defaultButton = defaultButton;
 795 
 796             if (oldDefault != null) {
 797                 oldDefault.repaint();
 798             }
 799             if (defaultButton != null) {
 800                 defaultButton.repaint();
 801             }
 802         }
 803 
 804         firePropertyChange("defaultButton", oldDefault, defaultButton);
 805     }
 806 
 807     /**
 808      * Returns the value of the <code>defaultButton</code> property.
 809      * @return the <code>JButton</code> which is currently the default button
 810      * @see #setDefaultButton
 811      */
 812     public JButton getDefaultButton() {
 813         return defaultButton;
 814     }
 815 
 816     final void setUseTrueDoubleBuffering(boolean useTrueDoubleBuffering) {
 817         this.useTrueDoubleBuffering = useTrueDoubleBuffering;
 818     }
 819 
 820     final boolean getUseTrueDoubleBuffering() {
 821         return useTrueDoubleBuffering;
 822     }
 823 
 824     final void disableTrueDoubleBuffering() {
 825         if (useTrueDoubleBuffering) {
 826             if (!IGNORE_DISABLE_TRUE_DOUBLE_BUFFERING) {
 827                 if (LOG_DISABLE_TRUE_DOUBLE_BUFFERING) {
 828                     System.out.println("Disabling true double buffering for " +
 829                                        this);
 830                     Thread.dumpStack();
 831                 }
 832                 useTrueDoubleBuffering = false;
 833                 RepaintManager.currentManager(this).
 834                         doubleBufferingChanged(this);
 835             }
 836         }
 837     }
 838 
 839     @SuppressWarnings("serial")
 840     static class DefaultAction extends AbstractAction {
 841         JButton owner;
 842         JRootPane root;
 843         boolean press;
 844         DefaultAction(JRootPane root, boolean press) {
 845             this.root = root;
 846             this.press = press;
 847         }
 848         public void setOwner(JButton owner) {
 849             this.owner = owner;
 850         }
 851         public void actionPerformed(ActionEvent e) {
 852             if (owner != null && SwingUtilities.getRootPane(owner) == root) {
 853                 ButtonModel model = owner.getModel();
 854                 if (press) {
 855                     model.setArmed(true);
 856                     model.setPressed(true);
 857                 } else {
 858                     model.setPressed(false);
 859                 }
 860             }
 861         }
 862         public boolean isEnabled() {
 863             return owner.getModel().isEnabled();
 864         }
 865     }
 866 
 867 
 868     /**
 869      * Overridden to enforce the position of the glass component as
 870      * the zero child.
 871      *
 872      * @param comp the component to be enhanced
 873      * @param constraints the constraints to be respected
 874      * @param index the index
 875      */
 876     protected void addImpl(Component comp, Object constraints, int index) {
 877         super.addImpl(comp, constraints, index);
 878 
 879         /// We are making sure the glassPane is on top.
 880         if(glassPane != null
 881             && glassPane.getParent() == this
 882             && getComponent(0) != glassPane) {
 883             add(glassPane, 0);
 884         }
 885     }
 886 
 887 
 888 ///////////////////////////////////////////////////////////////////////////////
 889 //// Begin Inner Classes
 890 ///////////////////////////////////////////////////////////////////////////////
 891 
 892 
 893     /**
 894      * A custom layout manager that is responsible for the layout of
 895      * layeredPane, glassPane, and menuBar.
 896      * <p>
 897      * <strong>Warning:</strong>
 898      * Serialized objects of this class will not be compatible with
 899      * future Swing releases. The current serialization support is
 900      * appropriate for short term storage or RMI between applications running
 901      * the same version of Swing.  As of 1.4, support for long term storage
 902      * of all JavaBeans&trade;
 903      * has been added to the <code>java.beans</code> package.
 904      * Please see {@link java.beans.XMLEncoder}.
 905      */
 906     @SuppressWarnings("serial")
 907     protected class RootLayout implements LayoutManager2, Serializable
 908     {
 909         /**
 910          * Returns the amount of space the layout would like to have.
 911          *
 912          * @param parent the Container for which this layout manager
 913          * is being used
 914          * @return a Dimension object containing the layout's preferred size
 915          */
 916         public Dimension preferredLayoutSize(Container parent) {
 917             Dimension rd, mbd;
 918             Insets i = getInsets();
 919 
 920             if(contentPane != null) {
 921                 rd = contentPane.getPreferredSize();
 922             } else {
 923                 rd = parent.getSize();
 924             }
 925             if(menuBar != null && menuBar.isVisible()) {
 926                 mbd = menuBar.getPreferredSize();
 927             } else {
 928                 mbd = new Dimension(0, 0);
 929             }
 930             return new Dimension(Math.max(rd.width, mbd.width) + i.left + i.right,
 931                                         rd.height + mbd.height + i.top + i.bottom);
 932         }
 933 
 934         /**
 935          * Returns the minimum amount of space the layout needs.
 936          *
 937          * @param parent the Container for which this layout manager
 938          * is being used
 939          * @return a Dimension object containing the layout's minimum size
 940          */
 941         public Dimension minimumLayoutSize(Container parent) {
 942             Dimension rd, mbd;
 943             Insets i = getInsets();
 944             if(contentPane != null) {
 945                 rd = contentPane.getMinimumSize();
 946             } else {
 947                 rd = parent.getSize();
 948             }
 949             if(menuBar != null && menuBar.isVisible()) {
 950                 mbd = menuBar.getMinimumSize();
 951             } else {
 952                 mbd = new Dimension(0, 0);
 953             }
 954             return new Dimension(Math.max(rd.width, mbd.width) + i.left + i.right,
 955                         rd.height + mbd.height + i.top + i.bottom);
 956         }
 957 
 958         /**
 959          * Returns the maximum amount of space the layout can use.
 960          *
 961          * @param target the Container for which this layout manager
 962          * is being used
 963          * @return a Dimension object containing the layout's maximum size
 964          */
 965         public Dimension maximumLayoutSize(Container target) {
 966             Dimension rd, mbd;
 967             Insets i = getInsets();
 968             if(menuBar != null && menuBar.isVisible()) {
 969                 mbd = menuBar.getMaximumSize();
 970             } else {
 971                 mbd = new Dimension(0, 0);
 972             }
 973             if(contentPane != null) {
 974                 rd = contentPane.getMaximumSize();
 975             } else {
 976                 // This is silly, but should stop an overflow error
 977                 rd = new Dimension(Integer.MAX_VALUE,
 978                         Integer.MAX_VALUE - i.top - i.bottom - mbd.height - 1);
 979             }
 980             return new Dimension(Math.min(rd.width, mbd.width) + i.left + i.right,
 981                                          rd.height + mbd.height + i.top + i.bottom);
 982         }
 983 
 984         /**
 985          * Instructs the layout manager to perform the layout for the specified
 986          * container.
 987          *
 988          * @param parent the Container for which this layout manager
 989          * is being used
 990          */
 991         public void layoutContainer(Container parent) {
 992             Rectangle b = parent.getBounds();
 993             Insets i = getInsets();
 994             int contentY = 0;
 995             int w = b.width - i.right - i.left;
 996             int h = b.height - i.top - i.bottom;
 997 
 998             if(layeredPane != null) {
 999                 layeredPane.setBounds(i.left, i.top, w, h);
1000             }
1001             if(glassPane != null) {
1002                 glassPane.setBounds(i.left, i.top, w, h);
1003             }
1004             // Note: This is laying out the children in the layeredPane,
1005             // technically, these are not our children.
1006             if(menuBar != null && menuBar.isVisible()) {
1007                 Dimension mbd = menuBar.getPreferredSize();
1008                 menuBar.setBounds(0, 0, w, mbd.height);
1009                 contentY += mbd.height;
1010             }
1011             if(contentPane != null) {
1012                 contentPane.setBounds(0, contentY, w, h - contentY);
1013             }
1014         }
1015 
1016         public void addLayoutComponent(String name, Component comp) {}
1017         public void removeLayoutComponent(Component comp) {}
1018         public void addLayoutComponent(Component comp, Object constraints) {}
1019         public float getLayoutAlignmentX(Container target) { return 0.0f; }
1020         public float getLayoutAlignmentY(Container target) { return 0.0f; }
1021         public void invalidateLayout(Container target) {}
1022     }
1023 
1024     /**
1025      * Returns a string representation of this <code>JRootPane</code>.
1026      * This method is intended to be used only for debugging purposes,
1027      * and the content and format of the returned string may vary between
1028      * implementations. The returned string may be empty but may not
1029      * be <code>null</code>.
1030      *
1031      * @return  a string representation of this <code>JRootPane</code>.
1032      */
1033     protected String paramString() {
1034         return super.paramString();
1035     }
1036 
1037 /////////////////
1038 // Accessibility support
1039 ////////////////
1040 
1041     /**
1042      * Gets the <code>AccessibleContext</code> associated with this
1043      * <code>JRootPane</code>. For root panes, the
1044      * <code>AccessibleContext</code> takes the form of an
1045      * <code>AccessibleJRootPane</code>.
1046      * A new <code>AccessibleJRootPane</code> instance is created if necessary.
1047      *
1048      * @return an <code>AccessibleJRootPane</code> that serves as the
1049      *         <code>AccessibleContext</code> of this <code>JRootPane</code>
1050      */
1051     public AccessibleContext getAccessibleContext() {
1052         if (accessibleContext == null) {
1053             accessibleContext = new AccessibleJRootPane();
1054         }
1055         return accessibleContext;
1056     }
1057 
1058     /**
1059      * This class implements accessibility support for the
1060      * <code>JRootPane</code> class.  It provides an implementation of the
1061      * Java Accessibility API appropriate to root pane user-interface elements.
1062      * <p>
1063      * <strong>Warning:</strong>
1064      * Serialized objects of this class will not be compatible with
1065      * future Swing releases. The current serialization support is
1066      * appropriate for short term storage or RMI between applications running
1067      * the same version of Swing.  As of 1.4, support for long term storage
1068      * of all JavaBeans&trade;
1069      * has been added to the <code>java.beans</code> package.
1070      * Please see {@link java.beans.XMLEncoder}.
1071      */
1072     @SuppressWarnings("serial")
1073     protected class AccessibleJRootPane extends AccessibleJComponent {
1074         /**
1075          * Get the role of this object.
1076          *
1077          * @return an instance of AccessibleRole describing the role of
1078          * the object
1079          */
1080         public AccessibleRole getAccessibleRole() {
1081             return AccessibleRole.ROOT_PANE;
1082         }
1083 
1084         /**
1085          * Returns the number of accessible children of the object.
1086          *
1087          * @return the number of accessible children of the object.
1088          */
1089         public int getAccessibleChildrenCount() {
1090             return super.getAccessibleChildrenCount();
1091         }
1092 
1093         /**
1094          * Returns the specified Accessible child of the object.  The Accessible
1095          * children of an Accessible object are zero-based, so the first child
1096          * of an Accessible child is at index 0, the second child is at index 1,
1097          * and so on.
1098          *
1099          * @param i zero-based index of child
1100          * @return the Accessible child of the object
1101          * @see #getAccessibleChildrenCount
1102          */
1103         public Accessible getAccessibleChild(int i) {
1104             return super.getAccessibleChild(i);
1105         }
1106     } // inner class AccessibleJRootPane
1107 }