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

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