KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > JRootPane


1 /*
2  * @(#)JRootPane.java 1.88 05/05/27
3  *
4  * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package javax.swing;
8
9 import java.awt.*;
10 import java.awt.event.*;
11 import java.beans.*;
12 import javax.accessibility.*;
13 import javax.swing.plaf.RootPaneUI JavaDoc;
14 import java.util.Vector JavaDoc;
15 import java.io.Serializable JavaDoc;
16 import javax.swing.border.*;
17
18
19 /**
20  * A lightweight container used behind the scenes by
21  * <code>JFrame</code>, <code>JDialog</code>, <code>JWindow</code>,
22  * <code>JApplet</code>, and <code>JInternalFrame</code>.
23  * For task-oriented information on functionality provided by root panes
24  * see <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/components/rootpane.html">How to Use Root Panes</a>,
25  * a section in <em>The Java Tutorial</em>.
26  *
27  * <p>
28  * The following image shows the relationships between
29  * the classes that use root panes.
30  * <p align=center><img SRC="doc-files/JRootPane-1.gif"
31  * alt="The following text describes this graphic."
32  * HEIGHT=484 WIDTH=629></p>
33  * The &quot;heavyweight&quot; components (those that delegate to a peer, or native
34  * component on the host system) are shown with a darker, heavier box. The four
35  * heavyweight JFC/Swing containers (<code>JFrame</code>, <code>JDialog</code>,
36  * <code>JWindow</code>, and <code>JApplet</code>) are
37  * shown in relation to the AWT classes they extend.
38  * These four components are the
39  * only heavyweight containers in the Swing library. The lightweight container
40  * <code>JInternalPane</code> is also shown.
41  * All five of these JFC/Swing containers implement the
42  * <code>RootPaneContainer</code> interface,
43  * and they all delegate their operations to a
44  * <code>JRootPane</code> (shown with a little "handle" on top).
45  * <blockquote>
46  * <b>Note:</b> The <code>JComponent</code> method <code>getRootPane</code>
47  * can be used to obtain the <code>JRootPane</code> that contains
48  * a given component.
49  * </blockquote>
50  * <table align="right" border="0" summary="layout">
51  * <tr>
52  * <td align="center">
53  * <img SRC="doc-files/JRootPane-2.gif"
54  * alt="The following text describes this graphic." HEIGHT=386 WIDTH=349>
55  * </td>
56  * </tr>
57  * </table>
58  * The diagram at right shows the structure of a <code>JRootPane</code>.
59  * A <code>JRootpane</code> is made up of a <code>glassPane</code>,
60  * an optional <code>menuBar</code>, and a <code>contentPane</code>.
61  * (The <code>JLayeredPane</code> manages the <code>menuBar</code>
62  * and the <code>contentPane</code>.)
63  * The <code>glassPane</code> sits over the top of everything,
64  * where it is in a position to intercept mouse movements.
65  * Since the <code>glassPane</code> (like the <code>contentPane</code>)
66  * can be an arbitrary component, it is also possible to set up the
67  * <code>glassPane</code> for drawing. Lines and images on the
68  * <code>glassPane</code> can then range
69  * over the frames underneath without being limited by their boundaries.
70  * <p>
71  * Although the <code>menuBar</code> component is optional,
72  * the <code>layeredPane</code>, <code>contentPane</code>,
73  * and <code>glassPane</code> always exist.
74  * Attempting to set them to <code>null</code> generates an exception.
75  * <p>
76  * To add components to the <code>JRootPane</code> (other than the
77  * optional menu bar), you add the object to the <code>contentPane</code>
78  * of the <code>JRootPane</code>, like this:
79  * <pre>
80  * rootPane.getContentPane().add(child);
81  * </pre>
82  * The same principle holds true for setting layout managers, removing
83  * components, listing children, etc. All these methods are invoked on
84  * the <code>contentPane</code> instead of on the <code>JRootPane</code>.
85  * <blockquote>
86  * <b>Note:</b> The default layout manager for the <code>contentPane</code> is
87  * a <code>BorderLayout</code> manager. However, the <code>JRootPane</code>
88  * uses a custom <code>LayoutManager</code>.
89  * So, when you want to change the layout manager for the components you added
90  * to a <code>JRootPane</code>, be sure to use code like this:
91  * <pre>
92  * rootPane.getContentPane().setLayout(new BoxLayout());
93  * </pre></blockquote>
94  * If a <code>JMenuBar</code> component is set on the <code>JRootPane</code>,
95  * it is positioned along the upper edge of the frame.
96  * The <code>contentPane</code> is adjusted in location and size to
97  * fill the remaining area.
98  * (The <code>JMenuBar</code> and the <code>contentPane</code> are added to the
99  * <code>layeredPane</code> component at the
100  * <code>JLayeredPane.FRAME_CONTENT_LAYER</code> layer.)
101  * <p>
102  * The <code>layeredPane</code> is the parent of all children in the
103  * <code>JRootPane</code> -- both as the direct parent of the menu and
104  * the grandparent of all components added to the <code>contentPane</code>.
105  * It is an instance of <code>JLayeredPane</code>,
106  * which provides the ability to add components at several layers.
107  * This capability is very useful when working with menu popups,
108  * dialog boxes, and dragging -- situations in which you need to place
109  * a component on top of all other components in the pane.
110  * <p>
111  * The <code>glassPane</code> sits on top of all other components in the
112  * <code>JRootPane</code>.
113  * That provides a convenient place to draw above all other components,
114  * and makes it possible to intercept mouse events,
115  * which is useful both for dragging and for drawing.
116  * Developers can use <code>setVisible</code> on the <code>glassPane</code>
117  * to control when the <code>glassPane</code> displays over the other children.
118  * By default the <code>glassPane</code> is not visible.
119  * <p>
120  * The custom <code>LayoutManager</code> used by <code>JRootPane</code>
121  * ensures that:
122  * <OL>
123  * <LI>The <code>glassPane</code> fills the entire viewable
124  * area of the <code>JRootPane</code> (bounds - insets).
125  * <LI>The <code>layeredPane</code> fills the entire viewable area of the
126  * <code>JRootPane</code>. (bounds - insets)
127  * <LI>The <code>menuBar</code> is positioned at the upper edge of the
128  * <code>layeredPane</code>.
129  * <LI>The <code>contentPane</code> fills the entire viewable area,
130  * minus the <code>menuBar</code>, if present.
131  * </OL>
132  * Any other views in the <code>JRootPane</code> view hierarchy are ignored.
133  * <p>
134  * If you replace the <code>LayoutManager</code> of the <code>JRootPane</code>,
135  * you are responsible for managing all of these views.
136  * So ordinarily you will want to be sure that you
137  * change the layout manager for the <code>contentPane</code> rather than
138  * for the <code>JRootPane</code> itself!
139  * <p>
140  * The painting architecture of Swing requires an opaque
141  * <code>JComponent</code>
142  * to exist in the containment hieararchy above all other components. This is
143  * typically provided by way of the content pane. If you replace the content
144  * pane, it is recommended that you make the content pane opaque
145  * by way of <code>setOpaque(true)</code>. Additionally, if the content pane
146  * overrides <code>paintComponent</code>, it
147  * will need to completely fill in the background in an opaque color in
148  * <code>paintComponent</code>.
149  * <p>
150  * <strong>Warning:</strong>
151  * Serialized objects of this class will not be compatible with
152  * future Swing releases. The current serialization support is
153  * appropriate for short term storage or RMI between applications running
154  * the same version of Swing. As of 1.4, support for long term storage
155  * of all JavaBeans<sup><font size="-2">TM</font></sup>
156  * has been added to the <code>java.beans</code> package.
157  * Please see {@link java.beans.XMLEncoder}.
158  *
159  * @see JLayeredPane
160  * @see JMenuBar
161  * @see JWindow
162  * @see JFrame
163  * @see JDialog
164  * @see JApplet
165  * @see JInternalFrame
166  * @see JComponent
167  * @see BoxLayout
168  *
169  * @see <a HREF="http://java.sun.com/products/jfc/swingdoc-archive/mixing.html">
170  * Mixing Heavy and Light Components</a>
171  *
172  * @version 1.88 05/27/05
173  * @author David Kloba
174  */

175 /// PENDING(klobad) Who should be opaque in this component?
176
public class JRootPane extends JComponent JavaDoc implements Accessible {
177
178     private static final String JavaDoc uiClassID = "RootPaneUI";
179
180     /**
181      * Constant used for the windowDecorationStyle property. Indicates that
182      * the <code>JRootPane</code> should not provide any sort of
183      * Window decorations.
184      *
185      * @since 1.4
186      */

187     public static final int NONE = 0;
188
189     /**
190      * Constant used for the windowDecorationStyle property. Indicates that
191      * the <code>JRootPane</code> should provide decorations appropriate for
192      * a Frame.
193      *
194      * @since 1.4
195      */

196     public static final int FRAME = 1;
197
198     /**
199      * Constant used for the windowDecorationStyle property. Indicates that
200      * the <code>JRootPane</code> should provide decorations appropriate for
201      * a Dialog.
202      *
203      * @since 1.4
204      */

205     public static final int PLAIN_DIALOG = 2;
206
207     /**
208      * Constant used for the windowDecorationStyle property. Indicates that
209      * the <code>JRootPane</code> should provide decorations appropriate for
210      * a Dialog used to display an informational message.
211      *
212      * @since 1.4
213      */

214     public static final int INFORMATION_DIALOG = 3;
215
216     /**
217      * Constant used for the windowDecorationStyle property. Indicates that
218      * the <code>JRootPane</code> should provide decorations appropriate for
219      * a Dialog used to display an error message.
220      *
221      * @since 1.4
222      */

223     public static final int ERROR_DIALOG = 4;
224
225     /**
226      * Constant used for the windowDecorationStyle property. Indicates that
227      * the <code>JRootPane</code> should provide decorations appropriate for
228      * a Dialog used to display a <code>JColorChooser</code>.
229      *
230      * @since 1.4
231      */

232     public static final int COLOR_CHOOSER_DIALOG = 5;
233
234     /**
235      * Constant used for the windowDecorationStyle property. Indicates that
236      * the <code>JRootPane</code> should provide decorations appropriate for
237      * a Dialog used to display a <code>JFileChooser</code>.
238      *
239      * @since 1.4
240      */

241     public static final int FILE_CHOOSER_DIALOG = 6;
242
243     /**
244      * Constant used for the windowDecorationStyle property. Indicates that
245      * the <code>JRootPane</code> should provide decorations appropriate for
246      * a Dialog used to present a question to the user.
247      *
248      * @since 1.4
249      */

250     public static final int QUESTION_DIALOG = 7;
251
252     /**
253      * Constant used for the windowDecorationStyle property. Indicates that
254      * the <code>JRootPane</code> should provide decorations appropriate for
255      * a Dialog used to display a warning message.
256      *
257      * @since 1.4
258      */

259     public static final int WARNING_DIALOG = 8;
260
261     private Component mostRecentFocusOwner;
262
263     private int windowDecorationStyle;
264
265     /** The menu bar. */
266     protected JMenuBar JavaDoc menuBar;
267
268     /** The content pane. */
269     protected Container contentPane;
270
271     /** The layered pane that manages the menu bar and content pane. */
272     protected JLayeredPane JavaDoc layeredPane;
273
274     /**
275      * The glass pane that overlays the menu bar and content pane,
276      * so it can intercept mouse movements and such.
277      */

278     protected Component glassPane;
279     /**
280      * The button that gets activated when the pane has the focus and
281      * a UI-specific action like pressing the <b>Enter</b> key occurs.
282      */

283     protected JButton JavaDoc defaultButton;
284     /**
285      * As of Java 2 platform v1.3 this unusable field is no longer used.
286      * To override the default button you should replace the <code>Action</code>
287      * in the <code>JRootPane</code>'s <code>ActionMap</code>. Please refer to
288      * the key bindings specification for further details.
289      *
290      * @deprecated As of Java 2 platform v1.3.
291      * @see #defaultButton
292      */

293     @Deprecated JavaDoc
294     protected DefaultAction defaultPressAction;
295     /**
296      * As of Java 2 platform v1.3 this unusable field is no longer used.
297      * To override the default button you should replace the <code>Action</code>
298      * in the <code>JRootPane</code>'s <code>ActionMap</code>. Please refer to
299      * the key bindings specification for further details.
300      *
301      * @deprecated As of Java 2 platform v1.3.
302      * @see #defaultButton
303      */

304     @Deprecated JavaDoc
305     protected DefaultAction defaultReleaseAction;
306
307     /**
308      * Creates a <code>JRootPane</code>, setting up its
309      * <code>glassPane</code>, <code>layeredPane</code>,
310      * and <code>contentPane</code>.
311      */

312     public JRootPane() {
313         setGlassPane(createGlassPane());
314         setLayeredPane(createLayeredPane());
315         setContentPane(createContentPane());
316         setLayout(createRootLayout());
317         setDoubleBuffered(true);
318     updateUI();
319     }
320
321     /**
322      * Returns a constant identifying the type of Window decorations the
323      * <code>JRootPane</code> is providing.
324      *
325      * @return One of <code>NONE</code>, <code>FRAME</code>,
326      * <code>PLAIN_DIALOG</code>, <code>INFORMATION_DIALOG</code>,
327      * <code>ERROR_DIALOG</code>, <code>COLOR_CHOOSER_DIALOG</code>,
328      * <code>FILE_CHOOSER_DIALOG</code>, <code>QUESTION_DIALOG</code> or
329      * <code>WARNING_DIALOG</code>.
330      * @see #setWindowDecorationStyle
331      * @since 1.4
332      */

333     public int getWindowDecorationStyle() {
334         return windowDecorationStyle;
335     }
336
337     /**
338      * Sets the type of Window decorations (such as borders, widgets for
339      * closing a Window, title ...) the <code>JRootPane</code> should
340      * provide. The default is to provide no Window decorations
341      * (<code>NONE</code>).
342      * <p>
343      * This is only a hint, and some look and feels may not support
344      * this.
345      * This is a bound property.
346      *
347      * @param windowDecorationStyle Constant identifying Window decorations
348      * to provide.
349      * @see JDialog#setDefaultLookAndFeelDecorated
350      * @see JFrame#setDefaultLookAndFeelDecorated
351      * @see LookAndFeel#getSupportsWindowDecorations
352      * @throws IllegalArgumentException if <code>style</code> is
353      * not one of: <code>NONE</code>, <code>FRAME</code>,
354      * <code>PLAIN_DIALOG</code>, <code>INFORMATION_DIALOG</code>,
355      * <code>ERROR_DIALOG</code>, <code>COLOR_CHOOSER_DIALOG</code>,
356      * <code>FILE_CHOOSER_DIALOG</code>, <code>QUESTION_DIALOG</code>, or
357      * <code>WARNING_DIALOG</code>.
358      * @since 1.4
359      * @beaninfo
360      * bound: true
361      * enum: NONE JRootPane.NONE
362      * FRAME JRootPane.FRAME
363      * PLAIN_DIALOG JRootPane.PLAIN_DIALOG
364      * INFORMATION_DIALOG JRootPane.INFORMATION_DIALOG
365      * ERROR_DIALOG JRootPane.ERROR_DIALOG
366      * COLOR_CHOOSER_DIALOG JRootPane.COLOR_CHOOSER_DIALOG
367      * FILE_CHOOSER_DIALOG JRootPane.FILE_CHOOSER_DIALOG
368      * QUESTION_DIALOG JRootPane.QUESTION_DIALOG
369      * WARNING_DIALOG JRootPane.WARNING_DIALOG
370      * expert: true
371      * attribute: visualUpdate true
372      * description: Identifies the type of Window decorations to provide
373      */

374     public void setWindowDecorationStyle(int windowDecorationStyle) {
375         if (windowDecorationStyle < 0 ||
376                   windowDecorationStyle > WARNING_DIALOG) {
377             throw new IllegalArgumentException JavaDoc("Invalid decoration style");
378         }
379         int oldWindowDecorationStyle = getWindowDecorationStyle();
380         this.windowDecorationStyle = windowDecorationStyle;
381         firePropertyChange("windowDecorationStyle",
382                             oldWindowDecorationStyle,
383                             windowDecorationStyle);
384     }
385
386     /**
387      * Returns the L&F object that renders this component.
388      *
389      * @return <code>LabelUI</code> object
390      * @since 1.3
391      */

392     public RootPaneUI JavaDoc getUI() {
393         return (RootPaneUI JavaDoc)ui;
394     }
395
396     /**
397      * Sets the L&F object that renders this component.
398      *
399      * @param ui the <code>LabelUI</code> L&F object
400      * @see UIDefaults#getUI
401      * @beaninfo
402      * bound: true
403      * hidden: true
404      * expert: true
405      * attribute: visualUpdate true
406      * description: The UI object that implements the Component's LookAndFeel.
407      * @since 1.3
408      */

409     public void setUI(RootPaneUI JavaDoc ui) {
410         super.setUI(ui);
411     }
412
413
414     /**
415      * Resets the UI property to a value from the current look and feel.
416      *
417      * @see JComponent#updateUI
418      */

419     public void updateUI() {
420         setUI((RootPaneUI JavaDoc)UIManager.getUI(this));
421     }
422
423
424     /**
425      * Returns a string that specifies the name of the L&F class
426      * that renders this component.
427      *
428      * @return the string "RootPaneUI"
429      *
430      * @see JComponent#getUIClassID
431      * @see UIDefaults#getUI
432      */

433     public String JavaDoc getUIClassID() {
434         return uiClassID;
435     }
436
437     /**
438       * Called by the constructor methods to create the default
439       * <code>layeredPane</code>.
440       * Bt default it creates a new <code>JLayeredPane</code>.
441       * @return the default <code>layeredPane</code>
442       */

443     protected JLayeredPane JavaDoc createLayeredPane() {
444         JLayeredPane JavaDoc p = new JLayeredPane JavaDoc();
445         p.setName(this.getName()+".layeredPane");
446         return p;
447     }
448
449     /**
450      * Called by the constructor methods to create the default
451      * <code>contentPane</code>.
452      * By default this method creates a new <code>JComponent</code> add sets a
453      * <code>BorderLayout</code> as its <code>LayoutManager</code>.
454      * @return the default <code>contentPane</code>
455      */

456     protected Container createContentPane() {
457         JComponent JavaDoc c = new JPanel JavaDoc();
458         c.setName(this.getName()+".contentPane");
459         c.setLayout(new BorderLayout() {
460             /* This BorderLayout subclass maps a null constraint to CENTER.
461              * Although the reference BorderLayout also does this, some VMs
462              * throw an IllegalArgumentException.
463              */

464             public void addLayoutComponent(Component comp, Object JavaDoc constraints) {
465                 if (constraints == null) {
466                     constraints = BorderLayout.CENTER;
467                 }
468                 super.addLayoutComponent(comp, constraints);
469             }
470         });
471         return c;
472     }
473
474     /**
475       * Called by the constructor methods to create the default
476       * <code>glassPane</code>.
477       * By default this method creates a new <code>JComponent</code>
478       * with visibility set to false.
479       * @return the default <code>glassPane</code>
480       */

481     protected Component createGlassPane() {
482         JComponent JavaDoc c = new JPanel JavaDoc();
483         c.setName(this.getName()+".glassPane");
484         c.setVisible(false);
485         ((JPanel JavaDoc)c).setOpaque(false);
486         return c;
487     }
488
489     /**
490      * Called by the constructor methods to create the default
491      * <code>layoutManager</code>.
492      * @return the default <code>layoutManager</code>.
493      */

494     protected LayoutManager createRootLayout() {
495         return new RootLayout();
496     }
497
498     /**
499      * Adds or changes the menu bar used in the layered pane.
500      * @param menu the <code>JMenuBar</code> to add
501      */

502     public void setJMenuBar(JMenuBar JavaDoc menu) {
503         if(menuBar != null && menuBar.getParent() == layeredPane)
504             layeredPane.remove(menuBar);
505         menuBar = menu;
506
507         if(menuBar != null)
508             layeredPane.add(menuBar, JLayeredPane.FRAME_CONTENT_LAYER);
509     }
510
511     /**
512      * Specifies the menu bar value.
513      * @deprecated As of Swing version 1.0.3
514      * replaced by <code>setJMenuBar(JMenuBar menu)</code>.
515      * @param menu the <code>JMenuBar</code> to add.
516      */

517     @Deprecated JavaDoc
518     public void setMenuBar(JMenuBar JavaDoc menu){
519         if(menuBar != null && menuBar.getParent() == layeredPane)
520             layeredPane.remove(menuBar);
521         menuBar = menu;
522
523         if(menuBar != null)
524             layeredPane.add(menuBar, JLayeredPane.FRAME_CONTENT_LAYER);
525     }
526     
527     /**
528      * Returns the menu bar from the layered pane.
529      * @return the <code>JMenuBar</code> used in the pane
530      */

531     public JMenuBar JavaDoc getJMenuBar() { return menuBar; }
532
533     /**
534      * Returns the menu bar value.
535      * @deprecated As of Swing version 1.0.3
536      * replaced by <code>getJMenubar()</code>.
537      * @return the <code>JMenuBar</code> used in the pane
538      */

539     @Deprecated JavaDoc
540     public JMenuBar JavaDoc getMenuBar() { return menuBar; }
541
542     /**
543      * Sets the content pane -- the container that holds the components
544      * parented by the root pane.
545      * <p>
546      * Swing's painting architecture requires an opaque <code>JComponent</code>
547      * in the containment hiearchy. This is typically provided by the
548      * content pane. If you replace the content pane it is recommended you
549      * replace it with an opaque <code>JComponent</code>.
550      *
551      * @param content the <code>Container</code> to use for component-contents
552      * @exception java.awt.IllegalComponentStateException (a runtime
553      * exception) if the content pane parameter is <code>null</code>
554      */

555     public void setContentPane(Container content) {
556         if(content == null)
557             throw new IllegalComponentStateException("contentPane cannot be set to null.");
558         if(contentPane != null && contentPane.getParent() == layeredPane)
559             layeredPane.remove(contentPane);
560         contentPane = content;
561
562         layeredPane.add(contentPane, JLayeredPane.FRAME_CONTENT_LAYER);
563     }
564
565     /**
566      * Returns the content pane -- the container that holds the components
567      * parented by the root pane.
568      *
569      * @return the <code>Container</code> that holds the component-contents
570      */

571     public Container getContentPane() { return contentPane; }
572
573 // PENDING(klobad) Should this reparent the contentPane and MenuBar?
574
/**
575      * Sets the layered pane for the root pane. The layered pane
576      * typically holds a content pane and an optional <code>JMenuBar</code>.
577      *
578      * @param layered the <code>JLayeredPane</code> to use
579      * @exception java.awt.IllegalComponentStateException (a runtime
580      * exception) if the layered pane parameter is <code>null</code>
581      */

582     public void setLayeredPane(JLayeredPane JavaDoc layered) {
583         if(layered == null)
584             throw new IllegalComponentStateException("layeredPane cannot be set to null.");
585         if(layeredPane != null && layeredPane.getParent() == this)
586             this.remove(layeredPane);
587         layeredPane = layered;
588
589         this.add(layeredPane, -1);
590     }
591     /**
592      * Gets the layered pane used by the root pane. The layered pane
593      * typically holds a content pane and an optional <code>JMenuBar</code>.
594      *
595      * @return the <code>JLayeredPane</code> currently in use
596      */

597     public JLayeredPane JavaDoc getLayeredPane() { return layeredPane; }
598
599     /**
600      * Sets a specified <code>Component</code> to be the glass pane for this
601      * root pane. The glass pane should normally be a lightweight,
602      * transparent component, because it will be made visible when
603      * ever the root pane needs to grab input events. For example,
604      * only one <code>JInternalFrame</code> is ever active when using a
605      * DefaultDesktop, and any inactive <code>JInternalFrame</code>s'
606      * glass panes are made visible so that clicking anywhere within
607      * an inactive <code>JInternalFrame</code> can activate it.
608      *
609      * @param glass the <code>Component</code> to use as the glass pane
610      * for this <code>JRootPane</code>
611      * @exception NullPointerException if the <code>glass</code> parameter is
612      * <code>null</code>
613      */

614     public void setGlassPane(Component glass) {
615         if (glass == null) {
616             throw new NullPointerException JavaDoc("glassPane cannot be set to null.");
617         }
618
619         boolean visible = false;
620         if (glassPane != null && glassPane.getParent() == this) {
621             this.remove(glassPane);
622             visible = glassPane.isVisible();
623         }
624
625         glass.setVisible(visible);
626         glassPane = glass;
627         this.add(glassPane, 0);
628         if (visible) {
629             repaint();
630         }
631     }
632
633     /**
634      * Returns the current glass pane for this <code>JRootPane</code>.
635      * @return the current glass pane
636      * @see #setGlassPane
637      */

638     public Component getGlassPane() {
639         return glassPane;
640     }
641
642     /**
643      * If a descendant of this <code>JRootPane</code> calls
644      * <code>revalidate</code>, validate from here on down.
645      *<p>
646      * Deferred requests to layout a component and its descendents again.
647      * For example, calls to <code>revalidate</code>, are pushed upwards to
648      * either a <code>JRootPane</code> or a <code>JScrollPane</code>
649      * because both classes override <code>isValidateRoot</code> to return true.
650      *
651      * @see JComponent#isValidateRoot
652      * @return true
653      */

654     public boolean isValidateRoot() {
655     return true;
656     }
657
658     /**
659      * The <code>glassPane</code> and <code>contentPane</code>
660      * have the same bounds, which means <code>JRootPane</code>
661      * does not tiles its children and this should return false.
662      * On the other hand, the <code>glassPane</code>
663      * is normally not visible, and so this can return true if the
664      * <code>glassPane</code> isn't visible. Therefore, the
665      * return value here depends upon the visiblity of the
666      * <code>glassPane</code>.
667      *
668      * @return true if this component's children don't overlap
669      */

670     public boolean isOptimizedDrawingEnabled() {
671         return !glassPane.isVisible();
672     }
673
674     /**
675      * Register ourselves with the <code>SystemEventQueueUtils</code> as a new
676      * root pane.
677      */

678     public void addNotify() {
679     SystemEventQueueUtilities.addRunnableCanvas(this);
680         super.addNotify();
681         enableEvents(AWTEvent.KEY_EVENT_MASK);
682     }
683
684     // Note: These links don't work because the target
685
// class is package private
686
// @see SystemEventQueueUtilities#addRunnableCanvas
687
// @see SystemEventQueueUtilities#removeRunnableCanvas
688

689     /**
690      * Unregister ourselves from <code>SystemEventQueueUtils</code>.
691      * @see #addNotify
692      */

693     public void removeNotify() {
694     SystemEventQueueUtilities.removeRunnableCanvas(this);
695         super.removeNotify();
696     }
697
698
699     /**
700      * Sets the <code>defaultButton</code> property,
701      * which determines the current default button for this <code>JRootPane</code>.
702      * The default button is the button which will be activated
703      * when a UI-defined activation event (typically the <b>Enter</b> key)
704      * occurs in the root pane regardless of whether or not the button
705      * has keyboard focus (unless there is another component within
706      * the root pane which consumes the activation event,
707      * such as a <code>JTextPane</code>).
708      * For default activation to work, the button must be an enabled
709      * descendent of the root pane when activation occurs.
710      * To remove a default button from this root pane, set this
711      * property to <code>null</code>.
712      *
713      * @see JButton#isDefaultButton
714      * @param defaultButton the <code>JButton</code> which is to be the default button
715      *
716      * @beaninfo
717      * description: The button activated by default in this root pane
718      */

719     public void setDefaultButton(JButton JavaDoc defaultButton) {
720         JButton JavaDoc oldDefault = this.defaultButton;
721
722         if (oldDefault != defaultButton) {
723             this.defaultButton = defaultButton;
724
725             if (oldDefault != null) {
726                 oldDefault.repaint();
727             }
728             if (defaultButton != null) {
729                 defaultButton.repaint();
730             }
731         }
732
733         firePropertyChange("defaultButton", oldDefault, defaultButton);
734     }
735
736     /**
737      * Returns the value of the <code>defaultButton</code> property.
738      * @return the <code>JButton</code> which is currently the default button
739      * @see #setDefaultButton
740      */

741     public JButton JavaDoc getDefaultButton() {
742         return defaultButton;
743     }
744
745     static class DefaultAction extends AbstractAction JavaDoc {
746         JButton JavaDoc owner;
747         JRootPane JavaDoc root;
748         boolean press;
749         DefaultAction(JRootPane JavaDoc root, boolean press) {
750             this.root = root;
751             this.press = press;
752         }
753         public void setOwner(JButton JavaDoc owner) {
754             this.owner = owner;
755         }
756         public void actionPerformed(ActionEvent e) {
757             if (owner != null && SwingUtilities.getRootPane(owner) == root) {
758                 ButtonModel JavaDoc model = owner.getModel();
759                 if (press) {
760                     model.setArmed(true);
761                     model.setPressed(true);
762                 } else {
763                     model.setPressed(false);
764                 }
765             }
766         }
767         public boolean isEnabled() {
768             return owner.getModel().isEnabled();
769         }
770     }
771
772
773     /**
774      * Overridden to enforce the position of the glass component as
775      * the zero child.
776      *
777      * @param comp the component to be enhanced
778      * @param constraints the constraints to be respected
779      * @param index the index
780      */

781     protected void addImpl(Component comp, Object JavaDoc constraints, int index) {
782         super.addImpl(comp, constraints, index);
783         
784         /// We are making sure the glassPane is on top.
785
if(glassPane != null
786             && glassPane.getParent() == this
787             && getComponent(0) != glassPane) {
788             add(glassPane, 0);
789         }
790     }
791
792 ///////////////////////////////////////////////////////////////////////////////
793
//// Begin Inner Classes
794
///////////////////////////////////////////////////////////////////////////////
795

796
797     /**
798      * A custom layout manager that is responsible for the layout of
799      * layeredPane, glassPane, and menuBar.
800      * <p>
801      * <strong>Warning:</strong>
802      * Serialized objects of this class will not be compatible with
803      * future Swing releases. The current serialization support is
804      * appropriate for short term storage or RMI between applications running
805      * the same version of Swing. As of 1.4, support for long term storage
806      * of all JavaBeans<sup><font size="-2">TM</font></sup>
807      * has been added to the <code>java.beans</code> package.
808      * Please see {@link java.beans.XMLEncoder}.
809      */

810     protected class RootLayout implements LayoutManager2, Serializable JavaDoc
811     {
812         /**
813          * Returns the amount of space the layout would like to have.
814          *
815          * @param parent the Container for which this layout manager
816          * is being used
817          * @return a Dimension object containing the layout's preferred size
818          */

819         public Dimension preferredLayoutSize(Container parent) {
820             Dimension rd, mbd;
821             Insets i = getInsets();
822         
823             if(contentPane != null) {
824                 rd = contentPane.getPreferredSize();
825             } else {
826                 rd = parent.getSize();
827             }
828             if(menuBar != null && menuBar.isVisible()) {
829                 mbd = menuBar.getPreferredSize();
830             } else {
831                 mbd = new Dimension(0, 0);
832             }
833             return new Dimension(Math.max(rd.width, mbd.width) + i.left + i.right,
834                                         rd.height + mbd.height + i.top + i.bottom);
835         }
836
837         /**
838          * Returns the minimum amount of space the layout needs.
839          *
840          * @param parent the Container for which this layout manager
841          * is being used
842          * @return a Dimension object containing the layout's minimum size
843          */

844         public Dimension minimumLayoutSize(Container parent) {
845             Dimension rd, mbd;
846             Insets i = getInsets();
847             if(contentPane != null) {
848                 rd = contentPane.getMinimumSize();
849             } else {
850                 rd = parent.getSize();
851             }
852             if(menuBar != null && menuBar.isVisible()) {
853                 mbd = menuBar.getMinimumSize();
854             } else {
855                 mbd = new Dimension(0, 0);
856             }
857             return new Dimension(Math.max(rd.width, mbd.width) + i.left + i.right,
858                         rd.height + mbd.height + i.top + i.bottom);
859         }
860
861         /**
862          * Returns the maximum amount of space the layout can use.
863          *
864          * @param target the Container for which this layout manager
865          * is being used
866          * @return a Dimension object containing the layout's maximum size
867          */

868         public Dimension maximumLayoutSize(Container target) {
869             Dimension rd, mbd;
870             Insets i = getInsets();
871             if(menuBar != null && menuBar.isVisible()) {
872                 mbd = menuBar.getMaximumSize();
873             } else {
874                 mbd = new Dimension(0, 0);
875             }
876             if(contentPane != null) {
877                 rd = contentPane.getMaximumSize();
878             } else {
879                 // This is silly, but should stop an overflow error
880
rd = new Dimension(Integer.MAX_VALUE,
881                         Integer.MAX_VALUE - i.top - i.bottom - mbd.height - 1);
882             }
883             return new Dimension(Math.min(rd.width, mbd.width) + i.left + i.right,
884                                          rd.height + mbd.height + i.top + i.bottom);
885         }
886         
887         /**
888          * Instructs the layout manager to perform the layout for the specified
889          * container.
890          *
891          * @param parent the Container for which this layout manager
892          * is being used
893          */

894         public void layoutContainer(Container parent) {
895             Rectangle b = parent.getBounds();
896             Insets i = getInsets();
897             int contentY = 0;
898             int w = b.width - i.right - i.left;
899             int h = b.height - i.top - i.bottom;
900         
901             if(layeredPane != null) {
902                 layeredPane.setBounds(i.left, i.top, w, h);
903             }
904             if(glassPane != null) {
905                 glassPane.setBounds(i.left, i.top, w, h);
906             }
907             // Note: This is laying out the children in the layeredPane,
908
// technically, these are not our children.
909
if(menuBar != null && menuBar.isVisible()) {
910                 Dimension mbd = menuBar.getPreferredSize();
911                 menuBar.setBounds(0, 0, w, mbd.height);
912                 contentY += mbd.height;
913             }
914             if(contentPane != null) {
915                 contentPane.setBounds(0, contentY, w, h - contentY);
916             }
917         }
918         
919         public void addLayoutComponent(String JavaDoc name, Component comp) {}
920         public void removeLayoutComponent(Component comp) {}
921         public void addLayoutComponent(Component comp, Object JavaDoc constraints) {}
922         public float getLayoutAlignmentX(Container target) { return 0.0f; }
923         public float getLayoutAlignmentY(Container target) { return 0.0f; }
924         public void invalidateLayout(Container target) {}
925     }
926
927     void setMostRecentFocusOwner(Component focusOwner) {
928     mostRecentFocusOwner = focusOwner;
929     }
930   
931     Component getMostRecentFocusOwner() {
932     return mostRecentFocusOwner;
933     }
934
935     /**
936      * Returns a string representation of this <code>JRootPane</code>.
937      * This method is intended to be used only for debugging purposes,
938      * and the content and format of the returned string may vary between
939      * implementations. The returned string may be empty but may not
940      * be <code>null</code>.
941      *
942      * @return a string representation of this <code>JRootPane</code>.
943      */

944     protected String JavaDoc paramString() {
945     return super.paramString();
946     }
947
948 /////////////////
949
// Accessibility support
950
////////////////
951

952     /**
953      * Gets the <code>AccessibleContext</code> associated with this
954      * <code>JRootPane</code>. For root panes, the
955      * <code>AccessibleContext</code> takes the form of an
956      * <code>AccessibleJRootPane</code>.
957      * A new <code>AccessibleJRootPane</code> instance is created if necessary.
958      *
959      * @return an <code>AccessibleJRootPane</code> that serves as the
960      * <code>AccessibleContext</code> of this <code>JRootPane</code>
961      */

962     public AccessibleContext getAccessibleContext() {
963         if (accessibleContext == null) {
964             accessibleContext = new AccessibleJRootPane();
965         }
966         return accessibleContext;
967     }
968
969     /**
970      * This class implements accessibility support for the
971      * <code>JRootPane</code> class. It provides an implementation of the
972      * Java Accessibility API appropriate to root pane user-interface elements.
973      * <p>
974      * <strong>Warning:</strong>
975      * Serialized objects of this class will not be compatible with
976      * future Swing releases. The current serialization support is
977      * appropriate for short term storage or RMI between applications running
978      * the same version of Swing. As of 1.4, support for long term storage
979      * of all JavaBeans<sup><font size="-2">TM</font></sup>
980      * has been added to the <code>java.beans</code> package.
981      * Please see {@link java.beans.XMLEncoder}.
982      */

983     protected class AccessibleJRootPane extends AccessibleJComponent {
984         /**
985          * Get the role of this object.
986          *
987          * @return an instance of AccessibleRole describing the role of
988          * the object
989          */

990         public AccessibleRole getAccessibleRole() {
991             return AccessibleRole.ROOT_PANE;
992         }
993
994         /**
995          * Returns the number of accessible children of the object.
996          *
997          * @return the number of accessible children of the object.
998          */

999         public int getAccessibleChildrenCount() {
1000            return super.getAccessibleChildrenCount();
1001        }
1002
1003        /**
1004         * Returns the specified Accessible child of the object. The Accessible
1005         * children of an Accessible object are zero-based, so the first child
1006         * of an Accessible child is at index 0, the second child is at index 1,
1007         * and so on.
1008         *
1009         * @param i zero-based index of child
1010         * @return the Accessible child of the object
1011         * @see #getAccessibleChildrenCount
1012         */

1013        public Accessible getAccessibleChild(int i) {
1014            return super.getAccessibleChild(i);
1015        }
1016    } // inner class AccessibleJRootPane
1017
}
1018
Popular Tags