Home » openjdk-7 » javax » swing » [javadoc | source]

    1   /*
    2    * Copyright (c) 1997, 2007, 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://java.sun.com/docs/books/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 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 align="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 hieararchy 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<sup><font size="-2">TM</font></sup>
  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    */
  201   /// PENDING(klobad) Who should be opaque in this component?
  202   public class JRootPane extends JComponent implements Accessible {
  203   
  204       private static final String uiClassID = "RootPaneUI";
  205   
  206       /**
  207        * Whether or not we should dump the stack when true double buffering
  208        * is disabled. Default is false.
  209        */
  210       private static final boolean LOG_DISABLE_TRUE_DOUBLE_BUFFERING;
  211   
  212       /**
  213        * Whether or not we should ignore requests to disable true double
  214        * buffering. Default is false.
  215        */
  216       private static final boolean IGNORE_DISABLE_TRUE_DOUBLE_BUFFERING;
  217   
  218       /**
  219        * Constant used for the windowDecorationStyle property. Indicates that
  220        * the <code>JRootPane</code> should not provide any sort of
  221        * Window decorations.
  222        *
  223        * @since 1.4
  224        */
  225       public static final int NONE = 0;
  226   
  227       /**
  228        * Constant used for the windowDecorationStyle property. Indicates that
  229        * the <code>JRootPane</code> should provide decorations appropriate for
  230        * a Frame.
  231        *
  232        * @since 1.4
  233        */
  234       public static final int FRAME = 1;
  235   
  236       /**
  237        * Constant used for the windowDecorationStyle property. Indicates that
  238        * the <code>JRootPane</code> should provide decorations appropriate for
  239        * a Dialog.
  240        *
  241        * @since 1.4
  242        */
  243       public static final int PLAIN_DIALOG = 2;
  244   
  245       /**
  246        * Constant used for the windowDecorationStyle property. Indicates that
  247        * the <code>JRootPane</code> should provide decorations appropriate for
  248        * a Dialog used to display an informational message.
  249        *
  250        * @since 1.4
  251        */
  252       public static final int INFORMATION_DIALOG = 3;
  253   
  254       /**
  255        * Constant used for the windowDecorationStyle property. Indicates that
  256        * the <code>JRootPane</code> should provide decorations appropriate for
  257        * a Dialog used to display an error message.
  258        *
  259        * @since 1.4
  260        */
  261       public static final int ERROR_DIALOG = 4;
  262   
  263       /**
  264        * Constant used for the windowDecorationStyle property. Indicates that
  265        * the <code>JRootPane</code> should provide decorations appropriate for
  266        * a Dialog used to display a <code>JColorChooser</code>.
  267        *
  268        * @since 1.4
  269        */
  270       public static final int COLOR_CHOOSER_DIALOG = 5;
  271   
  272       /**
  273        * Constant used for the windowDecorationStyle property. Indicates that
  274        * the <code>JRootPane</code> should provide decorations appropriate for
  275        * a Dialog used to display a <code>JFileChooser</code>.
  276        *
  277        * @since 1.4
  278        */
  279       public static final int FILE_CHOOSER_DIALOG = 6;
  280   
  281       /**
  282        * Constant used for the windowDecorationStyle property. Indicates that
  283        * the <code>JRootPane</code> should provide decorations appropriate for
  284        * a Dialog used to present a question to the user.
  285        *
  286        * @since 1.4
  287        */
  288       public static final int QUESTION_DIALOG = 7;
  289   
  290       /**
  291        * Constant used for the windowDecorationStyle property. Indicates that
  292        * the <code>JRootPane</code> should provide decorations appropriate for
  293        * a Dialog used to display a warning message.
  294        *
  295        * @since 1.4
  296        */
  297       public static final int WARNING_DIALOG = 8;
  298   
  299       private int windowDecorationStyle;
  300   
  301       /** The menu bar. */
  302       protected JMenuBar menuBar;
  303   
  304       /** The content pane. */
  305       protected Container contentPane;
  306   
  307       /** The layered pane that manages the menu bar and content pane. */
  308       protected JLayeredPane layeredPane;
  309   
  310       /**
  311        * The glass pane that overlays the menu bar and content pane,
  312        *  so it can intercept mouse movements and such.
  313        */
  314       protected Component glassPane;
  315       /**
  316        * The button that gets activated when the pane has the focus and
  317        * a UI-specific action like pressing the <b>Enter</b> key occurs.
  318        */
  319       protected JButton defaultButton;
  320       /**
  321        * As of Java 2 platform v1.3 this unusable field is no longer used.
  322        * To override the default button you should replace the <code>Action</code>
  323        * in the <code>JRootPane</code>'s <code>ActionMap</code>. Please refer to
  324        * the key bindings specification for further details.
  325        *
  326        * @deprecated As of Java 2 platform v1.3.
  327        *  @see #defaultButton
  328        */
  329       @Deprecated
  330       protected DefaultAction defaultPressAction;
  331       /**
  332        * As of Java 2 platform v1.3 this unusable field is no longer used.
  333        * To override the default button you should replace the <code>Action</code>
  334        * in the <code>JRootPane</code>'s <code>ActionMap</code>. Please refer to
  335        * the key bindings specification for further details.
  336        *
  337        * @deprecated As of Java 2 platform v1.3.
  338        *  @see #defaultButton
  339        */
  340       @Deprecated
  341       protected DefaultAction defaultReleaseAction;
  342   
  343       /**
  344        * Whether or not true double buffering should be used.  This is typically
  345        * true, but may be set to false in special situations.  For example,
  346        * heavy weight popups (backed by a window) set this to false.
  347        */
  348       boolean useTrueDoubleBuffering = true;
  349   
  350       static {
  351           LOG_DISABLE_TRUE_DOUBLE_BUFFERING =
  352               AccessController.doPrivileged(new GetBooleanAction(
  353                                      "swing.logDoubleBufferingDisable"));
  354           IGNORE_DISABLE_TRUE_DOUBLE_BUFFERING =
  355               AccessController.doPrivileged(new GetBooleanAction(
  356                                      "swing.ignoreDoubleBufferingDisable"));
  357       }
  358   
  359       /**
  360        * Creates a <code>JRootPane</code>, setting up its
  361        * <code>glassPane</code>, <code>layeredPane</code>,
  362        * and <code>contentPane</code>.
  363        */
  364       public JRootPane() {
  365           setGlassPane(createGlassPane());
  366           setLayeredPane(createLayeredPane());
  367           setContentPane(createContentPane());
  368           setLayout(createRootLayout());
  369           setDoubleBuffered(true);
  370           updateUI();
  371       }
  372   
  373       /**
  374        * {@inheritDoc}
  375        * @since 1.6
  376        */
  377       public void setDoubleBuffered(boolean aFlag) {
  378           if (isDoubleBuffered() != aFlag) {
  379               super.setDoubleBuffered(aFlag);
  380               RepaintManager.currentManager(this).doubleBufferingChanged(this);
  381           }
  382       }
  383   
  384       /**
  385        * Returns a constant identifying the type of Window decorations the
  386        * <code>JRootPane</code> is providing.
  387        *
  388        * @return One of <code>NONE</code>, <code>FRAME</code>,
  389        *        <code>PLAIN_DIALOG</code>, <code>INFORMATION_DIALOG</code>,
  390        *        <code>ERROR_DIALOG</code>, <code>COLOR_CHOOSER_DIALOG</code>,
  391        *        <code>FILE_CHOOSER_DIALOG</code>, <code>QUESTION_DIALOG</code> or
  392        *        <code>WARNING_DIALOG</code>.
  393        * @see #setWindowDecorationStyle
  394        * @since 1.4
  395        */
  396       public int getWindowDecorationStyle() {
  397           return windowDecorationStyle;
  398       }
  399   
  400       /**
  401        * Sets the type of Window decorations (such as borders, widgets for
  402        * closing a Window, title ...) the <code>JRootPane</code> should
  403        * provide. The default is to provide no Window decorations
  404        * (<code>NONE</code>).
  405        * <p>
  406        * This is only a hint, and some look and feels may not support
  407        * this.
  408        * This is a bound property.
  409        *
  410        * @param windowDecorationStyle Constant identifying Window decorations
  411        *        to provide.
  412        * @see JDialog#setDefaultLookAndFeelDecorated
  413        * @see JFrame#setDefaultLookAndFeelDecorated
  414        * @see LookAndFeel#getSupportsWindowDecorations
  415        * @throws IllegalArgumentException if <code>style</code> is
  416        *        not one of: <code>NONE</code>, <code>FRAME</code>,
  417        *        <code>PLAIN_DIALOG</code>, <code>INFORMATION_DIALOG</code>,
  418        *        <code>ERROR_DIALOG</code>, <code>COLOR_CHOOSER_DIALOG</code>,
  419        *        <code>FILE_CHOOSER_DIALOG</code>, <code>QUESTION_DIALOG</code>, or
  420        *        <code>WARNING_DIALOG</code>.
  421        * @since 1.4
  422        * @beaninfo
  423        *        bound: true
  424        *         enum: NONE                   JRootPane.NONE
  425        *               FRAME                  JRootPane.FRAME
  426        *               PLAIN_DIALOG           JRootPane.PLAIN_DIALOG
  427        *               INFORMATION_DIALOG     JRootPane.INFORMATION_DIALOG
  428        *               ERROR_DIALOG           JRootPane.ERROR_DIALOG
  429        *               COLOR_CHOOSER_DIALOG   JRootPane.COLOR_CHOOSER_DIALOG
  430        *               FILE_CHOOSER_DIALOG    JRootPane.FILE_CHOOSER_DIALOG
  431        *               QUESTION_DIALOG        JRootPane.QUESTION_DIALOG
  432        *               WARNING_DIALOG         JRootPane.WARNING_DIALOG
  433        *       expert: true
  434        *    attribute: visualUpdate true
  435        *  description: Identifies the type of Window decorations to provide
  436        */
  437       public void setWindowDecorationStyle(int windowDecorationStyle) {
  438           if (windowDecorationStyle < 0 ||
  439                     windowDecorationStyle > WARNING_DIALOG) {
  440               throw new IllegalArgumentException("Invalid decoration style");
  441           }
  442           int oldWindowDecorationStyle = getWindowDecorationStyle();
  443           this.windowDecorationStyle = windowDecorationStyle;
  444           firePropertyChange("windowDecorationStyle",
  445                               oldWindowDecorationStyle,
  446                               windowDecorationStyle);
  447       }
  448   
  449       /**
  450        * Returns the L&F object that renders this component.
  451        *
  452        * @return <code>LabelUI</code> object
  453        * @since 1.3
  454        */
  455       public RootPaneUI getUI() {
  456           return (RootPaneUI)ui;
  457       }
  458   
  459       /**
  460        * Sets the L&F object that renders this component.
  461        *
  462        * @param ui  the <code>LabelUI</code> L&F object
  463        * @see UIDefaults#getUI
  464        * @beaninfo
  465        *        bound: true
  466        *       hidden: true
  467        *      expert: true
  468        *    attribute: visualUpdate true
  469        *  description: The UI object that implements the Component's LookAndFeel.
  470        * @since 1.3
  471        */
  472       public void setUI(RootPaneUI ui) {
  473           super.setUI(ui);
  474       }
  475   
  476   
  477       /**
  478        * Resets the UI property to a value from the current look and feel.
  479        *
  480        * @see JComponent#updateUI
  481        */
  482       public void updateUI() {
  483           setUI((RootPaneUI)UIManager.getUI(this));
  484       }
  485   
  486   
  487       /**
  488        * Returns a string that specifies the name of the L&F class
  489        * that renders this component.
  490        *
  491        * @return the string "RootPaneUI"
  492        *
  493        * @see JComponent#getUIClassID
  494        * @see UIDefaults#getUI
  495        */
  496       public String getUIClassID() {
  497           return uiClassID;
  498       }
  499   
  500       /**
  501         * Called by the constructor methods to create the default
  502         * <code>layeredPane</code>.
  503         * Bt default it creates a new <code>JLayeredPane</code>.
  504         * @return the default <code>layeredPane</code>
  505         */
  506       protected JLayeredPane createLayeredPane() {
  507           JLayeredPane p = new JLayeredPane();
  508           p.setName(this.getName()+".layeredPane");
  509           return p;
  510       }
  511   
  512       /**
  513        * Called by the constructor methods to create the default
  514        * <code>contentPane</code>.
  515        * By default this method creates a new <code>JComponent</code> add sets a
  516        * <code>BorderLayout</code> as its <code>LayoutManager</code>.
  517        * @return the default <code>contentPane</code>
  518        */
  519       protected Container createContentPane() {
  520           JComponent c = new JPanel();
  521           c.setName(this.getName()+".contentPane");
  522           c.setLayout(new BorderLayout() {
  523               /* This BorderLayout subclass maps a null constraint to CENTER.
  524                * Although the reference BorderLayout also does this, some VMs
  525                * throw an IllegalArgumentException.
  526                */
  527               public void addLayoutComponent(Component comp, Object constraints) {
  528                   if (constraints == null) {
  529                       constraints = BorderLayout.CENTER;
  530                   }
  531                   super.addLayoutComponent(comp, constraints);
  532               }
  533           });
  534           return c;
  535       }
  536   
  537       /**
  538         * Called by the constructor methods to create the default
  539         * <code>glassPane</code>.
  540         * By default this method creates a new <code>JComponent</code>
  541         * with visibility set to false.
  542         * @return the default <code>glassPane</code>
  543         */
  544       protected Component createGlassPane() {
  545           JComponent c = new JPanel();
  546           c.setName(this.getName()+".glassPane");
  547           c.setVisible(false);
  548           ((JPanel)c).setOpaque(false);
  549           return c;
  550       }
  551   
  552       /**
  553        * Called by the constructor methods to create the default
  554        * <code>layoutManager</code>.
  555        * @return the default <code>layoutManager</code>.
  556        */
  557       protected LayoutManager createRootLayout() {
  558           return new RootLayout();
  559       }
  560   
  561       /**
  562        * Adds or changes the menu bar used in the layered pane.
  563        * @param menu the <code>JMenuBar</code> to add
  564        */
  565       public void setJMenuBar(JMenuBar menu) {
  566           if(menuBar != null && menuBar.getParent() == layeredPane)
  567               layeredPane.remove(menuBar);
  568           menuBar = menu;
  569   
  570           if(menuBar != null)
  571               layeredPane.add(menuBar, JLayeredPane.FRAME_CONTENT_LAYER);
  572       }
  573   
  574       /**
  575        * Specifies the menu bar value.
  576        * @deprecated As of Swing version 1.0.3
  577        *  replaced by <code>setJMenuBar(JMenuBar menu)</code>.
  578        * @param menu the <code>JMenuBar</code> to add.
  579        */
  580       @Deprecated
  581       public void setMenuBar(JMenuBar menu){
  582           if(menuBar != null && menuBar.getParent() == layeredPane)
  583               layeredPane.remove(menuBar);
  584           menuBar = menu;
  585   
  586           if(menuBar != null)
  587               layeredPane.add(menuBar, JLayeredPane.FRAME_CONTENT_LAYER);
  588       }
  589   
  590       /**
  591        * Returns the menu bar from the layered pane.
  592        * @return the <code>JMenuBar</code> used in the pane
  593        */
  594       public JMenuBar getJMenuBar() { return menuBar; }
  595   
  596       /**
  597        * Returns the menu bar value.
  598        * @deprecated As of Swing version 1.0.3
  599        *  replaced by <code>getJMenuBar()</code>.
  600        * @return the <code>JMenuBar</code> used in the pane
  601        */
  602       @Deprecated
  603       public JMenuBar getMenuBar() { return menuBar; }
  604   
  605       /**
  606        * Sets the content pane -- the container that holds the components
  607        * parented by the root pane.
  608        * <p>
  609        * Swing's painting architecture requires an opaque <code>JComponent</code>
  610        * in the containment hiearchy. This is typically provided by the
  611        * content pane. If you replace the content pane it is recommended you
  612        * replace it with an opaque <code>JComponent</code>.
  613        *
  614        * @param content the <code>Container</code> to use for component-contents
  615        * @exception java.awt.IllegalComponentStateException (a runtime
  616        *            exception) if the content pane parameter is <code>null</code>
  617        */
  618       public void setContentPane(Container content) {
  619           if(content == null)
  620               throw new IllegalComponentStateException("contentPane cannot be set to null.");
  621           if(contentPane != null && contentPane.getParent() == layeredPane)
  622               layeredPane.remove(contentPane);
  623           contentPane = content;
  624   
  625           layeredPane.add(contentPane, JLayeredPane.FRAME_CONTENT_LAYER);
  626       }
  627   
  628       /**
  629        * Returns the content pane -- the container that holds the components
  630        * parented by the root pane.
  631        *
  632        * @return the <code>Container</code> that holds the component-contents
  633        */
  634       public Container getContentPane() { return contentPane; }
  635   
  636   // PENDING(klobad) Should this reparent the contentPane and MenuBar?
  637       /**
  638        * Sets the layered pane for the root pane. The layered pane
  639        * typically holds a content pane and an optional <code>JMenuBar</code>.
  640        *
  641        * @param layered  the <code>JLayeredPane</code> to use
  642        * @exception java.awt.IllegalComponentStateException (a runtime
  643        *            exception) if the layered pane parameter is <code>null</code>
  644        */
  645       public void setLayeredPane(JLayeredPane layered) {
  646           if(layered == null)
  647               throw new IllegalComponentStateException("layeredPane cannot be set to null.");
  648           if(layeredPane != null && layeredPane.getParent() == this)
  649               this.remove(layeredPane);
  650           layeredPane = layered;
  651   
  652           this.add(layeredPane, -1);
  653       }
  654       /**
  655        * Gets the layered pane used by the root pane. The layered pane
  656        * typically holds a content pane and an optional <code>JMenuBar</code>.
  657        *
  658        * @return the <code>JLayeredPane</code> currently in use
  659        */
  660       public JLayeredPane getLayeredPane() { return layeredPane; }
  661   
  662       /**
  663        * Sets a specified <code>Component</code> to be the glass pane for this
  664        * root pane.  The glass pane should normally be a lightweight,
  665        * transparent component, because it will be made visible when
  666        * ever the root pane needs to grab input events.
  667        * <p>
  668        * The new glass pane's visibility is changed to match that of
  669        * the current glass pane.  An implication of this is that care
  670        * must be taken when you want to replace the glass pane and
  671        * make it visible.  Either of the following will work:
  672        * <pre>
  673        *   root.setGlassPane(newGlassPane);
  674        *   newGlassPane.setVisible(true);
  675        * </pre>
  676        * or:
  677        * <pre>
  678        *   root.getGlassPane().setVisible(true);
  679        *   root.setGlassPane(newGlassPane);
  680        * </pre>
  681        *
  682        * @param glass the <code>Component</code> to use as the glass pane
  683        *              for this <code>JRootPane</code>
  684        * @exception NullPointerException if the <code>glass</code> parameter is
  685        *          <code>null</code>
  686        */
  687       public void setGlassPane(Component glass) {
  688           if (glass == null) {
  689               throw new NullPointerException("glassPane cannot be set to null.");
  690           }
  691   
  692           AWTAccessor.getComponentAccessor().setMixingCutoutShape(glass,
  693                   new Rectangle());
  694   
  695           boolean visible = false;
  696           if (glassPane != null && glassPane.getParent() == this) {
  697               this.remove(glassPane);
  698               visible = glassPane.isVisible();
  699           }
  700   
  701           glass.setVisible(visible);
  702           glassPane = glass;
  703           this.add(glassPane, 0);
  704           if (visible) {
  705               repaint();
  706           }
  707       }
  708   
  709       /**
  710        * Returns the current glass pane for this <code>JRootPane</code>.
  711        * @return the current glass pane
  712        * @see #setGlassPane
  713        */
  714       public Component getGlassPane() {
  715           return glassPane;
  716       }
  717   
  718       /**
  719        * If a descendant of this <code>JRootPane</code> calls
  720        * <code>revalidate</code>, validate from here on down.
  721        *<p>
  722        * Deferred requests to layout a component and its descendents again.
  723        * For example, calls to <code>revalidate</code>, are pushed upwards to
  724        * either a <code>JRootPane</code> or a <code>JScrollPane</code>
  725        * because both classes override <code>isValidateRoot</code> to return true.
  726        *
  727        * @see JComponent#isValidateRoot
  728        * @see java.awt.Container#isValidateRoot
  729        * @return true
  730        */
  731       @Override
  732       public boolean isValidateRoot() {
  733           return true;
  734       }
  735   
  736       /**
  737        * The <code>glassPane</code> and <code>contentPane</code>
  738        * have the same bounds, which means <code>JRootPane</code>
  739        * does not tiles its children and this should return false.
  740        * On the other hand, the <code>glassPane</code>
  741        * is normally not visible, and so this can return true if the
  742        * <code>glassPane</code> isn't visible. Therefore, the
  743        * return value here depends upon the visiblity of the
  744        * <code>glassPane</code>.
  745        *
  746        * @return true if this component's children don't overlap
  747        */
  748       public boolean isOptimizedDrawingEnabled() {
  749           return !glassPane.isVisible();
  750       }
  751   
  752       /**
  753        * {@inheritDoc}
  754        */
  755       public void addNotify() {
  756           super.addNotify();
  757           enableEvents(AWTEvent.KEY_EVENT_MASK);
  758       }
  759   
  760       /**
  761        * {@inheritDoc}
  762        */
  763       public void removeNotify() {
  764           super.removeNotify();
  765       }
  766   
  767   
  768       /**
  769        * Sets the <code>defaultButton</code> property,
  770        * which determines the current default button for this <code>JRootPane</code>.
  771        * The default button is the button which will be activated
  772        * when a UI-defined activation event (typically the <b>Enter</b> key)
  773        * occurs in the root pane regardless of whether or not the button
  774        * has keyboard focus (unless there is another component within
  775        * the root pane which consumes the activation event,
  776        * such as a <code>JTextPane</code>).
  777        * For default activation to work, the button must be an enabled
  778        * descendent of the root pane when activation occurs.
  779        * To remove a default button from this root pane, set this
  780        * property to <code>null</code>.
  781        *
  782        * @see JButton#isDefaultButton
  783        * @param defaultButton the <code>JButton</code> which is to be the default button
  784        *
  785        * @beaninfo
  786        *  description: The button activated by default in this root pane
  787        */
  788       public void setDefaultButton(JButton defaultButton) {
  789           JButton oldDefault = this.defaultButton;
  790   
  791           if (oldDefault != defaultButton) {
  792               this.defaultButton = defaultButton;
  793   
  794               if (oldDefault != null) {
  795                   oldDefault.repaint();
  796               }
  797               if (defaultButton != null) {
  798                   defaultButton.repaint();
  799               }
  800           }
  801   
  802           firePropertyChange("defaultButton", oldDefault, defaultButton);
  803       }
  804   
  805       /**
  806        * Returns the value of the <code>defaultButton</code> property.
  807        * @return the <code>JButton</code> which is currently the default button
  808        * @see #setDefaultButton
  809        */
  810       public JButton getDefaultButton() {
  811           return defaultButton;
  812       }
  813   
  814       final void setUseTrueDoubleBuffering(boolean useTrueDoubleBuffering) {
  815           this.useTrueDoubleBuffering = useTrueDoubleBuffering;
  816       }
  817   
  818       final boolean getUseTrueDoubleBuffering() {
  819           return useTrueDoubleBuffering;
  820       }
  821   
  822       final void disableTrueDoubleBuffering() {
  823           if (useTrueDoubleBuffering) {
  824               if (!IGNORE_DISABLE_TRUE_DOUBLE_BUFFERING) {
  825                   if (LOG_DISABLE_TRUE_DOUBLE_BUFFERING) {
  826                       System.out.println("Disabling true double buffering for " +
  827                                          this);
  828                       Thread.dumpStack();
  829                   }
  830                   useTrueDoubleBuffering = false;
  831                   RepaintManager.currentManager(this).
  832                           doubleBufferingChanged(this);
  833               }
  834           }
  835       }
  836   
  837       static class DefaultAction extends AbstractAction {
  838           JButton owner;
  839           JRootPane root;
  840           boolean press;
  841           DefaultAction(JRootPane root, boolean press) {
  842               this.root = root;
  843               this.press = press;
  844           }
  845           public void setOwner(JButton owner) {
  846               this.owner = owner;
  847           }
  848           public void actionPerformed(ActionEvent e) {
  849               if (owner != null && SwingUtilities.getRootPane(owner) == root) {
  850                   ButtonModel model = owner.getModel();
  851                   if (press) {
  852                       model.setArmed(true);
  853                       model.setPressed(true);
  854                   } else {
  855                       model.setPressed(false);
  856                   }
  857               }
  858           }
  859           public boolean isEnabled() {
  860               return owner.getModel().isEnabled();
  861           }
  862       }
  863   
  864   
  865       /**
  866        * Overridden to enforce the position of the glass component as
  867        * the zero child.
  868        *
  869        * @param comp the component to be enhanced
  870        * @param constraints the constraints to be respected
  871        * @param index the index
  872        */
  873       protected void addImpl(Component comp, Object constraints, int index) {
  874           super.addImpl(comp, constraints, index);
  875   
  876           /// We are making sure the glassPane is on top.
  877           if(glassPane != null
  878               && glassPane.getParent() == this
  879               && getComponent(0) != glassPane) {
  880               add(glassPane, 0);
  881           }
  882       }
  883   
  884   
  885   ///////////////////////////////////////////////////////////////////////////////
  886   //// Begin Inner Classes
  887   ///////////////////////////////////////////////////////////////////////////////
  888   
  889   
  890       /**
  891        * A custom layout manager that is responsible for the layout of
  892        * layeredPane, glassPane, and menuBar.
  893        * <p>
  894        * <strong>Warning:</strong>
  895        * Serialized objects of this class will not be compatible with
  896        * future Swing releases. The current serialization support is
  897        * appropriate for short term storage or RMI between applications running
  898        * the same version of Swing.  As of 1.4, support for long term storage
  899        * of all JavaBeans<sup><font size="-2">TM</font></sup>
  900        * has been added to the <code>java.beans</code> package.
  901        * Please see {@link java.beans.XMLEncoder}.
  902        */
  903       protected class RootLayout implements LayoutManager2, Serializable
  904       {
  905           /**
  906            * Returns the amount of space the layout would like to have.
  907            *
  908            * @param parent the Container for which this layout manager
  909            * is being used
  910            * @return a Dimension object containing the layout's preferred size
  911            */
  912           public Dimension preferredLayoutSize(Container parent) {
  913               Dimension rd, mbd;
  914               Insets i = getInsets();
  915   
  916               if(contentPane != null) {
  917                   rd = contentPane.getPreferredSize();
  918               } else {
  919                   rd = parent.getSize();
  920               }
  921               if(menuBar != null && menuBar.isVisible()) {
  922                   mbd = menuBar.getPreferredSize();
  923               } else {
  924                   mbd = new Dimension(0, 0);
  925               }
  926               return new Dimension(Math.max(rd.width, mbd.width) + i.left + i.right,
  927                                           rd.height + mbd.height + i.top + i.bottom);
  928           }
  929   
  930           /**
  931            * Returns the minimum amount of space the layout needs.
  932            *
  933            * @param parent the Container for which this layout manager
  934            * is being used
  935            * @return a Dimension object containing the layout's minimum size
  936            */
  937           public Dimension minimumLayoutSize(Container parent) {
  938               Dimension rd, mbd;
  939               Insets i = getInsets();
  940               if(contentPane != null) {
  941                   rd = contentPane.getMinimumSize();
  942               } else {
  943                   rd = parent.getSize();
  944               }
  945               if(menuBar != null && menuBar.isVisible()) {
  946                   mbd = menuBar.getMinimumSize();
  947               } else {
  948                   mbd = new Dimension(0, 0);
  949               }
  950               return new Dimension(Math.max(rd.width, mbd.width) + i.left + i.right,
  951                           rd.height + mbd.height + i.top + i.bottom);
  952           }
  953   
  954           /**
  955            * Returns the maximum amount of space the layout can use.
  956            *
  957            * @param target the Container for which this layout manager
  958            * is being used
  959            * @return a Dimension object containing the layout's maximum size
  960            */
  961           public Dimension maximumLayoutSize(Container target) {
  962               Dimension rd, mbd;
  963               Insets i = getInsets();
  964               if(menuBar != null && menuBar.isVisible()) {
  965                   mbd = menuBar.getMaximumSize();
  966               } else {
  967                   mbd = new Dimension(0, 0);
  968               }
  969               if(contentPane != null) {
  970                   rd = contentPane.getMaximumSize();
  971               } else {
  972                   // This is silly, but should stop an overflow error
  973                   rd = new Dimension(Integer.MAX_VALUE,
  974                           Integer.MAX_VALUE - i.top - i.bottom - mbd.height - 1);
  975               }
  976               return new Dimension(Math.min(rd.width, mbd.width) + i.left + i.right,
  977                                            rd.height + mbd.height + i.top + i.bottom);
  978           }
  979   
  980           /**
  981            * Instructs the layout manager to perform the layout for the specified
  982            * container.
  983            *
  984            * @param parent the Container for which this layout manager
  985            * is being used
  986            */
  987           public void layoutContainer(Container parent) {
  988               Rectangle b = parent.getBounds();
  989               Insets i = getInsets();
  990               int contentY = 0;
  991               int w = b.width - i.right - i.left;
  992               int h = b.height - i.top - i.bottom;
  993   
  994               if(layeredPane != null) {
  995                   layeredPane.setBounds(i.left, i.top, w, h);
  996               }
  997               if(glassPane != null) {
  998                   glassPane.setBounds(i.left, i.top, w, h);
  999               }
 1000               // Note: This is laying out the children in the layeredPane,
 1001               // technically, these are not our children.
 1002               if(menuBar != null && menuBar.isVisible()) {
 1003                   Dimension mbd = menuBar.getPreferredSize();
 1004                   menuBar.setBounds(0, 0, w, mbd.height);
 1005                   contentY += mbd.height;
 1006               }
 1007               if(contentPane != null) {
 1008                   contentPane.setBounds(0, contentY, w, h - contentY);
 1009               }
 1010           }
 1011   
 1012           public void addLayoutComponent(String name, Component comp) {}
 1013           public void removeLayoutComponent(Component comp) {}
 1014           public void addLayoutComponent(Component comp, Object constraints) {}
 1015           public float getLayoutAlignmentX(Container target) { return 0.0f; }
 1016           public float getLayoutAlignmentY(Container target) { return 0.0f; }
 1017           public void invalidateLayout(Container target) {}
 1018       }
 1019   
 1020       /**
 1021        * Returns a string representation of this <code>JRootPane</code>.
 1022        * This method is intended to be used only for debugging purposes,
 1023        * and the content and format of the returned string may vary between
 1024        * implementations. The returned string may be empty but may not
 1025        * be <code>null</code>.
 1026        *
 1027        * @return  a string representation of this <code>JRootPane</code>.
 1028        */
 1029       protected String paramString() {
 1030           return super.paramString();
 1031       }
 1032   
 1033   /////////////////
 1034   // Accessibility support
 1035   ////////////////
 1036   
 1037       /**
 1038        * Gets the <code>AccessibleContext</code> associated with this
 1039        * <code>JRootPane</code>. For root panes, the
 1040        * <code>AccessibleContext</code> takes the form of an
 1041        * <code>AccessibleJRootPane</code>.
 1042        * A new <code>AccessibleJRootPane</code> instance is created if necessary.
 1043        *
 1044        * @return an <code>AccessibleJRootPane</code> that serves as the
 1045        *         <code>AccessibleContext</code> of this <code>JRootPane</code>
 1046        */
 1047       public AccessibleContext getAccessibleContext() {
 1048           if (accessibleContext == null) {
 1049               accessibleContext = new AccessibleJRootPane();
 1050           }
 1051           return accessibleContext;
 1052       }
 1053   
 1054       /**
 1055        * This class implements accessibility support for the
 1056        * <code>JRootPane</code> class.  It provides an implementation of the
 1057        * Java Accessibility API appropriate to root pane user-interface elements.
 1058        * <p>
 1059        * <strong>Warning:</strong>
 1060        * Serialized objects of this class will not be compatible with
 1061        * future Swing releases. The current serialization support is
 1062        * appropriate for short term storage or RMI between applications running
 1063        * the same version of Swing.  As of 1.4, support for long term storage
 1064        * of all JavaBeans<sup><font size="-2">TM</font></sup>
 1065        * has been added to the <code>java.beans</code> package.
 1066        * Please see {@link java.beans.XMLEncoder}.
 1067        */
 1068       protected class AccessibleJRootPane extends AccessibleJComponent {
 1069           /**
 1070            * Get the role of this object.
 1071            *
 1072            * @return an instance of AccessibleRole describing the role of
 1073            * the object
 1074            */
 1075           public AccessibleRole getAccessibleRole() {
 1076               return AccessibleRole.ROOT_PANE;
 1077           }
 1078   
 1079           /**
 1080            * Returns the number of accessible children of the object.
 1081            *
 1082            * @return the number of accessible children of the object.
 1083            */
 1084           public int getAccessibleChildrenCount() {
 1085               return super.getAccessibleChildrenCount();
 1086           }
 1087   
 1088           /**
 1089            * Returns the specified Accessible child of the object.  The Accessible
 1090            * children of an Accessible object are zero-based, so the first child
 1091            * of an Accessible child is at index 0, the second child is at index 1,
 1092            * and so on.
 1093            *
 1094            * @param i zero-based index of child
 1095            * @return the Accessible child of the object
 1096            * @see #getAccessibleChildrenCount
 1097            */
 1098           public Accessible getAccessibleChild(int i) {
 1099               return super.getAccessibleChild(i);
 1100           }
 1101       } // inner class AccessibleJRootPane
 1102   }

Home » openjdk-7 » javax » swing » [javadoc | source]