KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > JInternalFrame


1 /*
2  * @(#)JInternalFrame.java 1.147 04/05/18
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.swing;
9  
10 import java.awt.*;
11 import java.awt.event.*;
12
13 import java.beans.PropertyVetoException JavaDoc;
14 import java.beans.PropertyChangeEvent JavaDoc;
15 import java.util.EventListener JavaDoc;
16
17 import javax.swing.border.Border JavaDoc;
18 import javax.swing.event.InternalFrameEvent JavaDoc;
19 import javax.swing.event.InternalFrameListener JavaDoc;
20 import javax.swing.plaf.*;
21
22 import javax.accessibility.*;
23
24 import java.io.ObjectOutputStream JavaDoc;
25 import java.io.ObjectInputStream JavaDoc;
26 import java.io.IOException JavaDoc;
27
28
29 /**
30  * A lightweight object that provides many of the features of
31  * a native frame, including dragging, closing, becoming an icon,
32  * resizing, title display, and support for a menu bar.
33  * For task-oriented documentation and examples of using internal frames,
34  * see <a
35  href="http://java.sun.com/docs/books/tutorial/uiswing/components/internalframe.html" target="_top">How to Use Internal Frames</a>,
36  * a section in <em>The Java Tutorial</em>.
37  *
38  * <p>
39  *
40  * Generally,
41  * you add <code>JInternalFrame</code>s to a <code>JDesktopPane</code>. The UI
42  * delegates the look-and-feel-specific actions to the
43  * <code>DesktopManager</code>
44  * object maintained by the <code>JDesktopPane</code>.
45  * <p>
46  * The <code>JInternalFrame</code> content pane
47  * is where you add child components.
48  * As a conveniance <code>add</code> and its variants, <code>remove</code> and
49  * <code>setLayout</code> have been overridden to forward to the
50  * <code>contentPane</code> as necessary. This means you can write:
51  * <pre>
52  * internalFrame.add(child);
53  * </pre>
54  * And the child will be added to the contentPane.
55  * The content pane is actually managed by an instance of
56  * <code>JRootPane</code>,
57  * which also manages a layout pane, glass pane, and
58  * optional menu bar for the internal frame. Please see the
59  * <code>JRootPane</code>
60  * documentation for a complete description of these components.
61  * Refer to {@link javax.swing.RootPaneContainer}
62  * for details on adding, removing and setting the <code>LayoutManager</code>
63  * of a <code>JInternalFrame</code>.
64  * <p>
65  * <strong>Warning:</strong>
66  * Serialized objects of this class will not be compatible with
67  * future Swing releases. The current serialization support is
68  * appropriate for short term storage or RMI between applications running
69  * the same version of Swing. As of 1.4, support for long term storage
70  * of all JavaBeans<sup><font size="-2">TM</font></sup>
71  * has been added to the <code>java.beans</code> package.
72  * Please see {@link java.beans.XMLEncoder}.
73  *
74  * @see InternalFrameEvent
75  * @see JDesktopPane
76  * @see DesktopManager
77  * @see JInternalFrame.JDesktopIcon
78  * @see JRootPane
79  * @see javax.swing.RootPaneContainer
80  *
81  * @version 1.147 05/18/04
82  * @author David Kloba
83  * @author Rich Schiavi
84  * @beaninfo
85  * attribute: isContainer true
86  * attribute: containerDelegate getContentPane
87  * description: A frame container which is contained within
88  * another window.
89  */

90 public class JInternalFrame extends JComponent JavaDoc implements
91         Accessible, WindowConstants JavaDoc,
92         RootPaneContainer JavaDoc
93 {
94     /**
95      * @see #getUIClassID
96      * @see #readObject
97      */

98     private static final String JavaDoc uiClassID = "InternalFrameUI";
99
100     /**
101      * The <code>JRootPane</code> instance that manages the
102      * content pane
103      * and optional menu bar for this internal frame, as well as the
104      * glass pane.
105      *
106      * @see JRootPane
107      * @see RootPaneContainer
108      */

109     protected JRootPane JavaDoc rootPane;
110
111     /**
112      * If true then calls to <code>add</code> and <code>setLayout</code>
113      * will be forwarded to the <code>contentPane</code>. This is initially
114      * false, but is set to true when the <code>JInternalFrame</code> is
115      * constructed.
116      *
117      * @see #isRootPaneCheckingEnabled
118      * @see #setRootPaneCheckingEnabled
119      * @see javax.swing.RootPaneContainer
120      */

121     protected boolean rootPaneCheckingEnabled = false;
122
123     /** The frame can be closed. */
124     protected boolean closable;
125     /** The frame has been closed. */
126     protected boolean isClosed;
127     /** The frame can be expanded to the size of the desktop pane. */
128     protected boolean maximizable;
129     /**
130      * The frame has been expanded to its maximum size.
131      * @see #maximizable
132      */

133     protected boolean isMaximum;
134     /**
135      * The frame can "iconified" (shrunk down and displayed as
136      * an icon-image).
137      * @see JInternalFrame.JDesktopIcon
138      * @see #setIconifiable
139      */

140     protected boolean iconable;
141     /**
142      * The frame has been iconified.
143      * @see #isIcon()
144      */

145     protected boolean isIcon;
146     /** The frame's size can be changed. */
147     protected boolean resizable;
148     /** The frame is currently selected. */
149     protected boolean isSelected;
150     /** The icon shown in the top-left corner of this internal frame. */
151     protected Icon JavaDoc frameIcon;
152     /** The title displayed in this internal frame's title bar. */
153     protected String JavaDoc title;
154     /**
155      * The icon that is displayed when this internal frame is iconified.
156      * @see #iconable
157      */

158     protected JDesktopIcon desktopIcon;
159
160     private boolean opened;
161   
162     private Rectangle normalBounds = null;
163
164     private int defaultCloseOperation = DISPOSE_ON_CLOSE;
165
166     /**
167      * Contains the Component that focus is to go when
168      * <code>restoreSubcomponentFocus</code> is invoked, that is,
169      * <code>restoreSubcomponentFocus</code> sets this to the value returned
170      * from <code>getMostRecentFocusOwner</code>.
171      */

172     private Component lastFocusOwner;
173
174     /** Bound property name. */
175     public final static String JavaDoc CONTENT_PANE_PROPERTY = "contentPane";
176     /** Bound property name. */
177     public final static String JavaDoc MENU_BAR_PROPERTY = "JMenuBar";
178     /** Bound property name. */
179     public final static String JavaDoc TITLE_PROPERTY = "title";
180     /** Bound property name. */
181     public final static String JavaDoc LAYERED_PANE_PROPERTY = "layeredPane";
182     /** Bound property name. */
183     public final static String JavaDoc ROOT_PANE_PROPERTY = "rootPane";
184     /** Bound property name. */
185     public final static String JavaDoc GLASS_PANE_PROPERTY = "glassPane";
186     /** Bound property name. */
187     public final static String JavaDoc FRAME_ICON_PROPERTY = "frameIcon";
188
189     /**
190      * Constrained property name indicated that this frame has
191      * selected status.
192      */

193     public final static String JavaDoc IS_SELECTED_PROPERTY = "selected";
194     /** Constrained property name indicating that the internal frame is closed. */
195     public final static String JavaDoc IS_CLOSED_PROPERTY = "closed";
196     /** Constrained property name indicating that the internal frame is maximized. */
197     public final static String JavaDoc IS_MAXIMUM_PROPERTY = "maximum";
198     /** Constrained property name indicating that the internal frame is iconified. */
199     public final static String JavaDoc IS_ICON_PROPERTY = "icon";
200
201
202     /**
203      * Creates a non-resizable, non-closable, non-maximizable,
204      * non-iconifiable <code>JInternalFrame</code> with no title.
205      */

206     public JInternalFrame() {
207         this("", false, false, false, false);
208     }
209
210     /**
211      * Creates a non-resizable, non-closable, non-maximizable,
212      * non-iconifiable <code>JInternalFrame</code> with the specified title.
213      * Note that passing in a <code>null</code> <code>title</code> results in
214      * unspecified behavior and possibly an exception.
215      *
216      * @param title the non-<code>null</code> <code>String</code>
217      * to display in the title bar
218      */

219     public JInternalFrame(String JavaDoc title) {
220         this(title, false, false, false, false);
221     }
222
223     /**
224      * Creates a non-closable, non-maximizable, non-iconifiable
225      * <code>JInternalFrame</code> with the specified title
226      * and resizability.
227      *
228      * @param title the <code>String</code> to display in the title bar
229      * @param resizable if <code>true</code>, the internal frame can be resized
230      */

231     public JInternalFrame(String JavaDoc title, boolean resizable) {
232         this(title, resizable, false, false, false);
233     }
234
235     /**
236      * Creates a non-maximizable, non-iconifiable <code>JInternalFrame</code>
237      * with the specified title, resizability, and
238      * closability.
239      *
240      * @param title the <code>String</code> to display in the title bar
241      * @param resizable if <code>true</code>, the internal frame can be resized
242      * @param closable if <code>true</code>, the internal frame can be closed
243      */

244     public JInternalFrame(String JavaDoc title, boolean resizable, boolean closable) {
245         this(title, resizable, closable, false, false);
246     }
247
248     /**
249      * Creates a non-iconifiable <code>JInternalFrame</code>
250      * with the specified title,
251      * resizability, closability, and maximizability.
252      *
253      * @param title the <code>String</code> to display in the title bar
254      * @param resizable if <code>true</code>, the internal frame can be resized
255      * @param closable if <code>true</code>, the internal frame can be closed
256      * @param maximizable if <code>true</code>, the internal frame can be maximized
257      */

258     public JInternalFrame(String JavaDoc title, boolean resizable, boolean closable,
259                           boolean maximizable) {
260         this(title, resizable, closable, maximizable, false);
261     }
262
263     /**
264      * Creates a <code>JInternalFrame</code> with the specified title,
265      * resizability, closability, maximizability, and iconifiability.
266      * All <code>JInternalFrame</code> constructors use this one.
267      *
268      * @param title the <code>String</code> to display in the title bar
269      * @param resizable if <code>true</code>, the internal frame can be resized
270      * @param closable if <code>true</code>, the internal frame can be closed
271      * @param maximizable if <code>true</code>, the internal frame can be maximized
272      * @param iconifiable if <code>true</code>, the internal frame can be iconified
273      */

274     public JInternalFrame(String JavaDoc title, boolean resizable, boolean closable,
275                                 boolean maximizable, boolean iconifiable) {
276         
277         setRootPane(createRootPane());
278     getGlassPane().setVisible(true);
279         setLayout(new BorderLayout());
280         this.title = title;
281         this.resizable = resizable;
282         this.closable = closable;
283         this.maximizable = maximizable;
284         isMaximum = false;
285         this.iconable = iconifiable;
286         isIcon = false;
287     setVisible(false);
288         setRootPaneCheckingEnabled(true);
289         desktopIcon = new JDesktopIcon(this);
290     updateUI();
291         sun.awt.SunToolkit.checkAndSetPolicy(this, true);
292     }
293
294     /**
295      * Called by the constructor to set up the <code>JRootPane</code>.
296      * @return a new <code>JRootPane</code>
297      * @see JRootPane
298      */

299     protected JRootPane JavaDoc createRootPane() {
300         return new JRootPane JavaDoc();
301     }
302
303     /**
304      * Returns the look-and-feel object that renders this component.
305      *
306      * @return the <code>InternalFrameUI</code> object that renders
307      * this component
308      */

309     public InternalFrameUI getUI() {
310         return (InternalFrameUI)ui;
311     }
312
313     /**
314      * Sets the UI delegate for this <code>JInternalFrame</code>.
315      * @param ui the UI delegate
316      * @beaninfo
317      * bound: true
318      * hidden: true
319      * attribute: visualUpdate true
320      * description: The UI object that implements the Component's LookAndFeel.
321      */

322     public void setUI(InternalFrameUI ui) {
323         boolean checkingEnabled = isRootPaneCheckingEnabled();
324         try {
325             setRootPaneCheckingEnabled(false);
326             super.setUI(ui);
327         }
328         finally {
329             setRootPaneCheckingEnabled(checkingEnabled);
330         }
331     }
332
333     /**
334      * Notification from the <code>UIManager</code> that the look and feel
335      * has changed.
336      * Replaces the current UI object with the latest version from the
337      * <code>UIManager</code>.
338      *
339      * @see JComponent#updateUI
340      */

341     public void updateUI() {
342         setUI((InternalFrameUI)UIManager.getUI(this));
343         invalidate();
344         if (desktopIcon != null) {
345             desktopIcon.updateUIWhenHidden();
346         }
347     }
348
349     /* This method is called if <code>updateUI</code> was called
350      * on the associated
351      * JDesktopIcon. It's necessary to avoid infinite recursion.
352      */

353     void updateUIWhenHidden() {
354         setUI((InternalFrameUI)UIManager.getUI(this));
355         invalidate();
356         Component[] children = getComponents();
357         if (children != null) {
358             for(int i = 0; i < children.length; i++) {
359                 SwingUtilities.updateComponentTreeUI(children[i]);
360             }
361         }
362     }
363
364
365     /**
366      * Returns the name of the look-and-feel
367      * class that renders this component.
368      *
369      * @return the string "InternalFrameUI"
370      *
371      * @see JComponent#getUIClassID
372      * @see UIDefaults#getUI
373      *
374      * @beaninfo
375      * description: UIClassID
376      */

377     public String JavaDoc getUIClassID() {
378         return uiClassID;
379     }
380
381     /**
382      * Returns whether calls to <code>add</code> and
383      * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
384      *
385      * @return true if <code>add</code> and <code>setLayout</code>
386      * are fowarded; false otherwise
387      *
388      * @see #addImpl
389      * @see #setLayout
390      * @see #setRootPaneCheckingEnabled
391      * @see javax.swing.RootPaneContainer
392      */

393     protected boolean isRootPaneCheckingEnabled() {
394         return rootPaneCheckingEnabled;
395     }
396
397     /**
398      * Sets whether calls to <code>add</code> and
399      * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
400      *
401      * @param enabled true if <code>add</code> and <code>setLayout</code>
402      * are forwarded, false if they should operate directly on the
403      * <code>JInternalFrame</code>.
404      *
405      * @see #addImpl
406      * @see #setLayout
407      * @see #isRootPaneCheckingEnabled
408      * @see javax.swing.RootPaneContainer
409      * @beaninfo
410      * hidden: true
411      * description: Whether the add and setLayout methods are forwarded
412      */

413     protected void setRootPaneCheckingEnabled(boolean enabled) {
414         rootPaneCheckingEnabled = enabled;
415     }
416
417     /**
418      * Adds the specified child <code>Component</code>.
419      * This method is overridden to conditionally forwad calls to the
420      * <code>contentPane</code>.
421      * By default, children are added to the <code>contentPane</code> instead
422      * of the frame, refer to {@link javax.swing.RootPaneContainer} for
423      * details.
424      *
425      * @param comp the component to be enhanced
426      * @param constraints the constraints to be respected
427      * @param index the index
428      * @exception IllegalArgumentException if <code>index</code> is invalid
429      * @exception IllegalArgumentException if adding the container's parent
430      * to itself
431      * @exception IllegalArgumentException if adding a window to a container
432      *
433      * @see #setRootPaneCheckingEnabled
434      * @see javax.swing.RootPaneContainer
435      */

436     protected void addImpl(Component comp, Object JavaDoc constraints, int index) {
437         if(isRootPaneCheckingEnabled()) {
438             getContentPane().add(comp, constraints, index);
439         }
440         else {
441             super.addImpl(comp, constraints, index);
442         }
443     }
444
445     /**
446      * Removes the specified component from the container. If
447      * <code>comp</code> is not a child of the <code>JInternalFrame</code>
448      * this will forward the call to the <code>contentPane</code>.
449      *
450      * @param comp the component to be removed
451      * @throws NullPointerException if <code>comp</code> is null
452      * @see #add
453      * @see javax.swing.RootPaneContainer
454      */

455     public void remove(Component comp) {
456     int oldCount = getComponentCount();
457     super.remove(comp);
458     if (oldCount == getComponentCount()) {
459         getContentPane().remove(comp);
460     }
461     }
462
463
464     /**
465      * Ensures that, by default, the layout of this component cannot be set.
466      * Overridden to conditionally forward the call to the
467      * <code>contentPane</code>.
468      * Refer to {@link javax.swing.RootPaneContainer} for
469      * more information.
470      *
471      * @param manager the <code>LayoutManager</code>
472      * @see #setRootPaneCheckingEnabled
473      */

474     public void setLayout(LayoutManager manager) {
475         if(isRootPaneCheckingEnabled()) {
476             getContentPane().setLayout(manager);
477         }
478         else {
479             super.setLayout(manager);
480         }
481     }
482
483
484 //////////////////////////////////////////////////////////////////////////
485
/// Property Methods
486
//////////////////////////////////////////////////////////////////////////
487

488     /**
489      * Returns the current <code>JMenuBar</code> for this
490      * <code>JInternalFrame</code>, or <code>null</code>
491      * if no menu bar has been set.
492      * @return the current menu bar, or <code>null</code> if none has been set
493      *
494      * @deprecated As of Swing version 1.0.3,
495      * replaced by <code>getJMenuBar()</code>.
496      */

497     @Deprecated JavaDoc
498     public JMenuBar JavaDoc getMenuBar() {
499       return getRootPane().getMenuBar();
500     }
501
502     /**
503      * Returns the current <code>JMenuBar</code> for this
504      * <code>JInternalFrame</code>, or <code>null</code>
505      * if no menu bar has been set.
506      *
507      * @return the <code>JMenuBar</code> used by this internal frame
508      * @see #setJMenuBar
509      */

510     public JMenuBar JavaDoc getJMenuBar() {
511     return getRootPane().getJMenuBar();
512     }
513     
514     /**
515      * Sets the <code>menuBar</code> property for this <code>JInternalFrame</code>.
516      *
517      * @param m the <code>JMenuBar</code> to use in this internal frame
518      * @see #getJMenuBar
519      * @deprecated As of Swing version 1.0.3
520      * replaced by <code>setJMenuBar(JMenuBar m)</code>.
521      */

522     @Deprecated JavaDoc
523     public void setMenuBar(JMenuBar JavaDoc m) {
524         JMenuBar JavaDoc oldValue = getMenuBar();
525         getRootPane().setJMenuBar(m);
526         firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
527     }
528
529     /**
530      * Sets the <code>menuBar</code> property for this <code>JInternalFrame</code>.
531      *
532      * @param m the <code>JMenuBar</code> to use in this internal frame
533      * @see #getJMenuBar
534      * @beaninfo
535      * bound: true
536      * preferred: true
537      * description: The menu bar for accessing pulldown menus
538      * from this internal frame.
539      */

540     public void setJMenuBar(JMenuBar JavaDoc m){
541         JMenuBar JavaDoc oldValue = getMenuBar();
542         getRootPane().setJMenuBar(m);
543         firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
544     }
545
546     // implements javax.swing.RootPaneContainer
547
/**
548      * Returns the content pane for this internal frame.
549      * @return the content pane
550      */

551     public Container getContentPane() {
552         return getRootPane().getContentPane();
553     }
554
555
556     /**
557      * Sets this <code>JInternalFrame</code>'s <code>contentPane</code>
558      * property.
559      *
560      * @param c the content pane for this internal frame
561      *
562      * @exception java.awt.IllegalComponentStateException (a runtime
563      * exception) if the content pane parameter is <code>null</code>
564      * @see RootPaneContainer#getContentPane
565      * @beaninfo
566      * bound: true
567      * hidden: true
568      * description: The client area of the internal frame where child
569      * components are normally inserted.
570      */

571     public void setContentPane(Container c) {
572         Container oldValue = getContentPane();
573         getRootPane().setContentPane(c);
574         firePropertyChange(CONTENT_PANE_PROPERTY, oldValue, c);
575     }
576
577     /**
578      * Returns the layered pane for this internal frame.
579      *
580      * @return a <code>JLayeredPane</code> object
581      * @see RootPaneContainer#setLayeredPane
582      * @see RootPaneContainer#getLayeredPane
583      */

584     public JLayeredPane JavaDoc getLayeredPane() {
585         return getRootPane().getLayeredPane();
586     }
587
588     /**
589      * Sets this <code>JInternalFrame</code>'s
590      * <code>layeredPane</code> property.
591      *
592      * @param layered the <code>JLayeredPane</code> for this internal frame
593      *
594      * @exception java.awt.IllegalComponentStateException (a runtime
595      * exception) if the layered pane parameter is <code>null</code>
596      * @see RootPaneContainer#setLayeredPane
597      * @beaninfo
598      * hidden: true
599      * bound: true
600      * description: The pane which holds the various desktop layers.
601      */

602     public void setLayeredPane(JLayeredPane JavaDoc layered) {
603         JLayeredPane JavaDoc oldValue = getLayeredPane();
604         getRootPane().setLayeredPane(layered);
605         firePropertyChange(LAYERED_PANE_PROPERTY, oldValue, layered);
606     }
607
608     /**
609      * Returns the glass pane for this internal frame.
610      *
611      * @return the glass pane
612      * @see RootPaneContainer#setGlassPane
613      */

614     public Component getGlassPane() {
615         return getRootPane().getGlassPane();
616     }
617
618     /**
619      * Sets this <code>JInternalFrame</code>'s
620      * <code>glassPane</code> property.
621      *
622      * @param glass the glass pane for this internal frame
623      * @see RootPaneContainer#getGlassPane
624      * @beaninfo
625      * bound: true
626      * hidden: true
627      * description: A transparent pane used for menu rendering.
628      */

629     public void setGlassPane(Component glass) {
630         Component oldValue = getGlassPane();
631         getRootPane().setGlassPane(glass);
632         firePropertyChange(GLASS_PANE_PROPERTY, oldValue, glass);
633     }
634
635     /**
636      * Returns the <code>rootPane</code> object for this internal frame.
637      *
638      * @return the <code>rootPane</code> property
639      * @see RootPaneContainer#getRootPane
640      */

641     public JRootPane JavaDoc getRootPane() {
642         return rootPane;
643     }
644
645
646     /**
647      * Sets the <code>rootPane</code> property
648      * for this <code>JInternalFrame</code>.
649      * This method is called by the constructor.
650      *
651      * @param root the new <code>JRootPane</code> object
652      * @beaninfo
653      * bound: true
654      * hidden: true
655      * description: The root pane used by this internal frame.
656      */

657     protected void setRootPane(JRootPane JavaDoc root) {
658         if(rootPane != null) {
659             remove(rootPane);
660         }
661         JRootPane JavaDoc oldValue = getRootPane();
662         rootPane = root;
663         if(rootPane != null) {
664             boolean checkingEnabled = isRootPaneCheckingEnabled();
665             try {
666                 setRootPaneCheckingEnabled(false);
667                 add(rootPane, BorderLayout.CENTER);
668             }
669             finally {
670                 setRootPaneCheckingEnabled(checkingEnabled);
671             }
672         }
673         firePropertyChange(ROOT_PANE_PROPERTY, oldValue, root);
674     }
675
676     /**
677      * Sets whether this <code>JInternalFrame</code> can be closed by
678      * some user action.
679      * @param b a boolean value, where <code>true</code> means this internal frame can be closed
680      * @beaninfo
681      * preferred: true
682      * bound: true
683      * description: Indicates whether this internal frame can be closed.
684      */

685     public void setClosable(boolean b) {
686         Boolean JavaDoc oldValue = closable ? Boolean.TRUE : Boolean.FALSE;
687         Boolean JavaDoc newValue = b ? Boolean.TRUE : Boolean.FALSE;
688         closable = b;
689         firePropertyChange("closable", oldValue, newValue);
690     }
691  
692     /**
693      * Returns whether this <code>JInternalFrame</code> can be closed by
694      * some user action.
695      * @return <code>true</code> if this internal frame can be closed
696      */

697     public boolean isClosable() {
698         return closable;
699     }
700
701     /**
702      * Returns whether this <code>JInternalFrame</code> is currently closed.
703      * @return <code>true</code> if this internal frame is closed, <code>false</code> otherwise
704      */

705     public boolean isClosed() {
706         return isClosed;
707     }
708
709     /**
710      * Closes this internal frame if the argument is <code>true</code>.
711      * Do not invoke this method with a <code>false</code> argument;
712      * the result of invoking <code>setClosed(false)</code>
713      * is unspecified.
714      *
715      * <p>
716      *
717      * If the internal frame is already closed,
718      * this method does nothing and returns immediately.
719      * Otherwise,
720      * this method begins by firing
721      * an <code>INTERNAL_FRAME_CLOSING</code> event.
722      * Then this method sets the <code>closed</code> property to <code>true</code>
723      * unless a listener vetoes the property change.
724      * This method finishes by making the internal frame
725      * invisible and unselected,
726      * and then firing an <code>INTERNAL_FRAME_CLOSED</code> event.
727      *
728      * <p>
729      *
730      * <b>Note:</b>
731      * To reuse an internal frame that has been closed,
732      * you must add it to a container
733      * (even if you never removed it from its previous container).
734      * Typically, this container will be the <code>JDesktopPane</code>
735      * that previously contained the internal frame.
736      *
737      * @param b must be <code>true</code>
738      *
739      * @exception PropertyVetoException when the attempt to set the
740      * property is vetoed by the <code>JInternalFrame</code>
741      *
742      * @see #isClosed()
743      * @see #setDefaultCloseOperation
744      * @see #dispose
745      * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSING
746      *
747      * @beaninfo
748      * bound: true
749      * constrained: true
750      * description: Indicates whether this internal frame has been closed.
751      */

752     public void setClosed(boolean b) throws PropertyVetoException JavaDoc {
753         if (isClosed == b) {
754             return;
755         }
756
757         Boolean JavaDoc oldValue = isClosed ? Boolean.TRUE : Boolean.FALSE;
758         Boolean JavaDoc newValue = b ? Boolean.TRUE : Boolean.FALSE;
759     if (b) {
760       fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
761     }
762         fireVetoableChange(IS_CLOSED_PROPERTY, oldValue, newValue);
763         isClosed = b;
764     firePropertyChange(IS_CLOSED_PROPERTY, oldValue, newValue);
765         if (isClosed) {
766       dispose();
767         } else if (!opened) {
768       /* this bogus -- we haven't defined what
769          setClosed(false) means. */

770       // fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
771
// opened = true;
772
}
773     }
774
775     /**
776      * Sets whether the <code>JInternalFrame</code> can be resized by some
777      * user action.
778      *
779      * @param b a boolean, where <code>true</code> means this internal frame can be resized
780      * @beaninfo
781      * preferred: true
782      * bound: true
783      * description: Determines whether this internal frame can be resized
784      * by the user.
785      */

786     public void setResizable(boolean b) {
787         Boolean JavaDoc oldValue = resizable ? Boolean.TRUE : Boolean.FALSE;
788         Boolean JavaDoc newValue = b ? Boolean.TRUE : Boolean.FALSE;
789         resizable = b;
790         firePropertyChange("resizable", oldValue, newValue);
791     }
792  
793     /**
794      * Returns whether the <code>JInternalFrame</code> can be resized
795      * by some user action.
796      *
797      * @return <code>true</code> if this internal frame can be resized, <code>false</code> otherwise
798      */

799     public boolean isResizable() {
800         // don't allow resizing when maximized.
801
return isMaximum ? false : resizable;
802     }
803
804     /**
805      * Sets the <code>iconable</code> property,
806      * which must be <code>true</code>
807      * for the user to be able to
808      * make the <code>JInternalFrame</code> an icon.
809      * Some look and feels might not implement iconification;
810      * they will ignore this property.
811      *
812      * @param b a boolean, where <code>true</code> means this internal frame can be iconified
813      * @beaninfo
814      * preferred: true
815                bound: true
816      * description: Determines whether this internal frame can be iconified.
817      */

818     public void setIconifiable(boolean b) {
819         Boolean JavaDoc oldValue = iconable ? Boolean.TRUE : Boolean.FALSE;
820         Boolean JavaDoc newValue = b ? Boolean.TRUE : Boolean.FALSE;
821         iconable = b;
822         firePropertyChange("iconable", oldValue, newValue);
823     }
824  
825     /**
826      * Gets the <code>iconable</code> property,
827      * which by default is <code>false</code>.
828      *
829      * @return the value of the <code>iconable</code> property.
830      *
831      * @see #setIconifiable
832      */

833     public boolean isIconifiable() {
834         return iconable;
835     }
836
837     /**
838      * Returns whether the <code>JInternalFrame</code> is currently iconified.
839      *
840      * @return <code>true</code> if this internal frame is iconified
841      */

842     public boolean isIcon() {
843         return isIcon;
844     }
845
846     /**
847      * Iconifies or de-iconifies this internal frame,
848      * if the look and feel supports iconification.
849      * If the internal frame's state changes to iconified,
850      * this method fires an <code>INTERNAL_FRAME_ICONIFIED</code> event.
851      * If the state changes to de-iconified,
852      * an <code>INTERNAL_FRAME_DEICONIFIED</code> event is fired.
853      *
854      * @param b a boolean, where <code>true</code> means to iconify this internal frame and
855      * <code>false</code> means to de-iconify it
856      * @exception PropertyVetoException when the attempt to set the
857      * property is vetoed by the <code>JInternalFrame</code>
858      *
859      * @see InternalFrameEvent#INTERNAL_FRAME_ICONIFIED
860      * @see InternalFrameEvent#INTERNAL_FRAME_DEICONIFIED
861      *
862      * @beaninfo
863      * bound: true
864      * constrained: true
865      * description: The image displayed when this internal frame is minimized.
866      */

867     public void setIcon(boolean b) throws PropertyVetoException JavaDoc {
868         if (isIcon == b) {
869             return;
870         }
871
872     /* If an internal frame is being iconified before it has a
873        parent, (e.g., client wants it to start iconic), create the
874        parent if possible so that we can place the icon in its
875        proper place on the desktop. I am not sure the call to
876        validate() is necessary, since we are not going to display
877        this frame yet */

878         firePropertyChange("ancestor", null, getParent());
879
880         Boolean JavaDoc oldValue = isIcon ? Boolean.TRUE : Boolean.FALSE;
881         Boolean JavaDoc newValue = b ? Boolean.TRUE : Boolean.FALSE;
882         fireVetoableChange(IS_ICON_PROPERTY, oldValue, newValue);
883         isIcon = b;
884         firePropertyChange(IS_ICON_PROPERTY, oldValue, newValue);
885     if (b)
886       fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
887     else
888       fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
889     }
890
891     /**
892      * Sets the <code>maximizable</code> property,
893      * which determines whether the <code>JInternalFrame</code>
894      * can be maximized by
895      * some user action.
896      * Some look and feels might not support maximizing internal frames;
897      * they will ignore this property.
898      *
899      * @param b <code>true</code> to specify that this internal frame should be maximizable; <code>false</code> to specify that it should not be
900      * @beaninfo
901      * bound: true
902      * preferred: true
903      * description: Determines whether this internal frame can be maximized.
904      */

905     public void setMaximizable(boolean b) {
906         Boolean JavaDoc oldValue = maximizable ? Boolean.TRUE : Boolean.FALSE;
907         Boolean JavaDoc newValue = b ? Boolean.TRUE : Boolean.FALSE;
908         maximizable = b;
909         firePropertyChange("maximizable", oldValue, newValue);
910     }
911  
912     /**
913      * Gets the value of the <code>maximizable</code> property.
914      *
915      * @return the value of the <code>maximizable</code> property
916      * @see #setMaximizable
917      */

918     public boolean isMaximizable() {
919         return maximizable;
920     }
921
922     /**
923      * Returns whether the <code>JInternalFrame</code> is currently maximized.
924      *
925      * @return <code>true</code> if this internal frame is maximized, <code>false</code> otherwise
926      */

927     public boolean isMaximum() {
928         return isMaximum;
929     }
930
931     /**
932      * Maximizes and restores this internal frame. A maximized frame is resized to
933      * fully fit the <code>JDesktopPane</code> area associated with the
934      * <code>JInternalFrame</code>.
935      * A restored frame's size is set to the <code>JInternalFrame</code>'s
936      * actual size.
937      *
938      * @param b a boolean, where <code>true</code> maximizes this internal frame and <code>false</code>
939      * restores it
940      * @exception PropertyVetoException when the attempt to set the
941      * property is vetoed by the <code>JInternalFrame</code>
942      * @beaninfo
943      * bound: true
944      * constrained: true
945      * description: Indicates whether this internal frame is maximized.
946      */

947     public void setMaximum(boolean b) throws PropertyVetoException JavaDoc {
948         if (isMaximum == b) {
949             return;
950         }
951
952         Boolean JavaDoc oldValue = isMaximum ? Boolean.TRUE : Boolean.FALSE;
953         Boolean JavaDoc newValue = b ? Boolean.TRUE : Boolean.FALSE;
954         fireVetoableChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
955     /* setting isMaximum above the event firing means that
956        property listeners that, for some reason, test it will
957        get it wrong... See, for example, getNormalBounds() */

958         isMaximum = b;
959         firePropertyChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
960     }
961
962     /**
963      * Returns the title of the <code>JInternalFrame</code>.
964      *
965      * @return a <code>String</code> containing this internal frame's title
966      * @see #setTitle
967      */

968     public String JavaDoc getTitle() {
969         return title;
970     }
971
972     /**
973      * Sets the <code>JInternalFrame</code> title. <code>title</code>
974      * may have a <code>null</code> value.
975      * @see #getTitle
976      *
977      * @param title the <code>String</code> to display in the title bar
978      * @beaninfo
979      * preferred: true
980      * bound: true
981      * description: The text displayed in the title bar.
982      */

983     public void setTitle(String JavaDoc title) {
984         String JavaDoc oldValue = this.title;
985         this.title = title;
986         firePropertyChange(TITLE_PROPERTY, oldValue, title);
987     }
988
989     /**
990      * Selects or deselects the internal frame
991      * if it's showing.
992      * A <code>JInternalFrame</code> normally draws its title bar
993      * differently if it is
994      * the selected frame, which indicates to the user that this
995      * internal frame has the focus.
996      * When this method changes the state of the internal frame
997      * from deselected to selected, it fires an
998      * <code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code> event.
999      * If the change is from selected to deselected,
1000     * an <code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code> event
1001     * is fired.
1002     *
1003     * @param selected a boolean, where <code>true</code> means this internal frame
1004     * s