OSDN Git Service

GNU Classpath import (libgcj-snapshot-20100921).
[pf3gnuchains/gcc-fork.git] / libjava / classpath / javax / swing / JInternalFrame.java
1 /* JInternalFrame.java --
2    Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package javax.swing;
40
41 import java.awt.BorderLayout;
42 import java.awt.Component;
43 import java.awt.Container;
44 import java.awt.Graphics;
45 import java.awt.IllegalComponentStateException;
46 import java.awt.KeyboardFocusManager;
47 import java.awt.LayoutManager;
48 import java.awt.Rectangle;
49 import java.beans.PropertyChangeEvent;
50 import java.beans.PropertyVetoException;
51
52 import javax.accessibility.Accessible;
53 import javax.accessibility.AccessibleContext;
54 import javax.accessibility.AccessibleRole;
55 import javax.accessibility.AccessibleValue;
56 import javax.swing.event.InternalFrameEvent;
57 import javax.swing.event.InternalFrameListener;
58 import javax.swing.plaf.DesktopIconUI;
59 import javax.swing.plaf.InternalFrameUI;
60
61 /**
62  * This class implements a Swing widget that looks and acts like a native
63  * frame. The frame can be dragged, resized, closed, etc. Typically,
64  * JInternalFrames are placed in JDesktopPanes. The actions that the
65  * JInternalFrame performs (maximizing, minimizing, etc.) are performed by a
66  * DesktopManager. As with regular frames, components are added by calling
67  * frame.getContentPane().add.
68  */
69 public class JInternalFrame extends JComponent implements Accessible,
70                                                           WindowConstants,
71                                                           RootPaneContainer
72 {
73
74   private static final long serialVersionUID = -5425177187760785402L;
75
76   /**
77    * Provides the accessibility features for the <code>JInternalFrame</code>
78    * component.
79    */
80   protected class AccessibleJInternalFrame extends AccessibleJComponent
81     implements AccessibleValue
82   {
83     private static final long serialVersionUID = 5931936924175476797L;
84
85     /**
86      * Creates a new <code>AccessibleJInternalFrame</code> instance.
87      */
88     protected AccessibleJInternalFrame()
89     {
90       super();
91     }
92
93     /**
94      * Returns the frame title.
95      *
96      * @return The frame title.
97      */
98     public String getAccessibleName()
99     {
100       return getTitle();
101     }
102
103     /**
104      * Returns the accessible role for the <code>JInternalFrame</code> 
105      * component.
106      *
107      * @return {@link AccessibleRole#INTERNAL_FRAME}.
108      */
109     public AccessibleRole getAccessibleRole()
110     {
111       return AccessibleRole.INTERNAL_FRAME;
112     }
113
114     /**
115      * Returns an object that provides access to the current, minimum and 
116      * maximum values for the {@link JInternalFrame}.  Since this class 
117      * implements {@link AccessibleValue}, it returns itself.
118      *
119      * @return The accessible value.
120      */
121     public AccessibleValue getAccessibleValue()
122     {
123       return this;
124     }
125
126     /**
127      * Returns the current layer for the {@link JInternalFrame} component, 
128      * as an {@link Integer}.
129      *
130      * @return The layer for the {@link JInternalFrame} component.
131      */
132     public Number getCurrentAccessibleValue()
133     {
134       return new Integer(getLayer());
135     }
136
137     /**
138      * Returns the maximum permitted accessible value.
139      *
140      * @return <code>Integer(Integer.MAX_VALUE)</code>.
141      */
142     public Number getMaximumAccessibleValue()
143     {
144       return new Integer(Integer.MAX_VALUE);
145     }
146
147     /**
148      * Returns the minimum permitted accessible value.
149      *
150      * @return <code>Integer(Integer.MIN_VALUE)</code>.
151      */
152     public Number getMinimumAccessibleValue()
153     {
154       return new Integer(Integer.MIN_VALUE);
155     }
156
157     /**
158      * Sets the layer for the internal frame.
159      *
160      * @param n  the layer (see the constants defined in {@link JLayeredPane}).
161      *
162      * @return <code>true</code> if the value is set, and <code>false</code>
163      *         if it was not set.
164      */
165     public boolean setCurrentAccessibleValue(Number n)
166     {
167       if (n == null)
168         return false;
169       setLayer(n.intValue());
170       return true;
171     }
172   }
173
174   /**
175    * This class represents the JInternalFrame while it is iconified.
176    */
177   public static class JDesktopIcon extends JComponent implements Accessible
178   {
179     /**
180      * Provides the accessibility features for the <code>JDesktopIcon</code>
181      * component.
182      */
183     protected class AccessibleJDesktopIcon extends AccessibleJComponent
184       implements AccessibleValue
185     {
186       private static final long serialVersionUID = 5035560458941637802L;
187
188       /**
189        * Creates a new <code>AccessibleJDesktopIcon</code> instance.
190        */
191       protected AccessibleJDesktopIcon()
192       {
193         super();
194       }
195
196       /**
197        * Returns the accessible role for the <code>JDesktopIcon</code> 
198        * component.
199        *
200        * @return {@link AccessibleRole#DESKTOP_ICON}.
201        */
202       public AccessibleRole getAccessibleRole()
203       {
204         return AccessibleRole.DESKTOP_ICON;
205       }
206
207       /**
208        * Returns an object that provides access to the current, minimum and 
209        * maximum values for the {@link JDesktopIcon}.  Since this class 
210        * implements {@link AccessibleValue}, it returns itself.
211        *
212        * @return The accessible value.
213        */
214       public AccessibleValue getAccessibleValue()
215       {
216         return this;
217       }
218
219       /**
220        * Returns the current layer for the {@link JInternalFrame} component
221        * represented by this <code>JDesktopIcon</code>, as an {@link Integer}.
222        *
223        * @return The layer.
224        */
225       public Number getCurrentAccessibleValue()
226       {
227         return new Integer(frame.getLayer());
228       }
229
230       /**
231        * Returns the maximum permitted accessible value.
232        *
233        * @return <code>Integer(Integer.MAX_VALUE)</code>.
234        */
235       public Number getMaximumAccessibleValue()
236       {
237         return new Integer(Integer.MAX_VALUE);
238       }
239
240       /**
241        * Returns the minimum permitted accessible value.
242        *
243        * @return <code>Integer(Integer.MIN_VALUE)</code>.
244        */
245       public Number getMinimumAccessibleValue()
246       {
247         return new Integer(Integer.MIN_VALUE);
248       }
249
250       /**
251        * Sets the layer for the internal frame represented by this 
252        * <code>JDesktopIcon</code> component.
253        *
254        * @param n  the layer (see the constants defined in 
255        *           {@link JLayeredPane}).
256        *
257        * @return <code>true</code> if the value is set, and <code>false</code>
258        *         if it was not set.
259        */
260       public boolean setCurrentAccessibleValue(Number n)
261       {
262         if (n == null)
263           return false;
264         frame.setLayer(n.intValue());
265         return true;
266       }
267     }
268
269     private static final long serialVersionUID = 4672973344731387687L;
270
271     /** The JInternalFrame this DesktopIcon represents. */
272     JInternalFrame frame;
273
274     /**
275      * Creates a new JDesktopIcon object for representing the given frame.
276      *
277      * @param f The JInternalFrame to represent.
278      */
279     public JDesktopIcon(JInternalFrame f)
280     {
281       frame = f;
282       updateUI();
283     }
284
285   /**
286    * Returns the object that provides accessibility features for this
287    * <code>JDesktopIcon</code> component.
288    *
289    * @return The accessible context (an instance of 
290    *         {@link AccessibleJDesktopIcon}).
291    */
292     public AccessibleContext getAccessibleContext()
293     {
294       if (accessibleContext == null)
295         accessibleContext = new AccessibleJDesktopIcon();
296       return accessibleContext;
297     }
298
299     /**
300      * This method returns the JDesktopPane this JDesktopIcon is in.
301      *
302      * @return The JDesktopPane this JDesktopIcon is in.
303      */
304     public JDesktopPane getDesktopPane()
305     {
306       JDesktopPane p = (JDesktopPane) SwingUtilities.getAncestorOfClass(JDesktopPane.class,
307                                                                         this);
308       return p;
309     }
310
311     /**
312      * This method returns the JInternalFrame this JDesktopIcon represents.
313      *
314      * @return The JInternalFrame this JDesktopIcon represents.
315      */
316     public JInternalFrame getInternalFrame()
317     {
318       return frame;
319     }
320
321     /**
322      * This method returns the UI that is responsible for the JDesktopIcon.
323      *
324      * @return The UI that is responsible for the JDesktopIcon.
325      */
326     public DesktopIconUI getUI()
327     {
328       return (DesktopIconUI) ui;
329     }
330
331     /**
332      * This method returns the String identifier that is used to determine
333      * which class is used for JDesktopIcon's UI.
334      *
335      * @return A String identifier for the UI class.
336      */
337     public String getUIClassID()
338     {
339       return "DesktopIconUI";
340     }
341
342     /**
343      * This method sets the JInternalFrame that this JDesktopIcon represents.
344      *
345      * @param f The JInternalFrame that this JDesktopIcon represents.
346      */
347     public void setInternalFrame(JInternalFrame f)
348     {
349       frame = f;
350     }
351
352     /**
353      * This method sets the UI used for this JDesktopIcon.
354      *
355      * @param ui The UI to use.
356      */
357     public void setUI(DesktopIconUI ui)
358     {
359       super.setUI(ui);
360     }
361
362     /**
363      * This method restores the UI property to the defaults.
364      */
365     public void updateUI()
366     {
367       setUI((DesktopIconUI) UIManager.getUI(this));
368     }
369   }
370
371   /**
372    * The property fired in a PropertyChangeEvent when the contentPane property
373    * changes.
374    */
375   public static final String CONTENT_PANE_PROPERTY = "contentPane";
376
377   /**
378    * The property fired in a PropertyChangeEvent when the frameIcon property
379    * changes.
380    */
381   public static final String FRAME_ICON_PROPERTY = "frameIcon";
382
383   /**
384    * The property fired in a PropertyChangeEvent when the glassPane property
385    * changes.
386    */
387   public static final String GLASS_PANE_PROPERTY = "glassPane";
388
389   /**
390    * The property fired in a PropertyChangeEvent when the closed property
391    * changes.
392    */
393   public static final String IS_CLOSED_PROPERTY = "closed";
394
395   /**
396    * The property fired in a PropertyChangeEvent when the icon property
397    * changes.
398    */
399   public static final String IS_ICON_PROPERTY = "icon";
400
401   /**
402    * The property fired in a PropertyChangeEvent when the maximum property
403    * changes.
404    */
405   public static final String IS_MAXIMUM_PROPERTY = "maximum";
406
407   /**
408    * The property fired in a PropertyChangeEvent when the selected property
409    * changes.
410    */
411   public static final String IS_SELECTED_PROPERTY = "selected";
412
413   /**
414    * The property fired in a PropertyChangeEvent when the layeredPane property
415    * changes.
416    */
417   public static final String LAYERED_PANE_PROPERTY = "layeredPane";
418
419   /**
420    * The property fired in a PropertyChangeEvent when the jMenuBar property
421    * changes.
422    */
423   public static final String MENU_BAR_PROPERTY = "JMenuBar";
424
425   /**
426    * The property fired in a PropertyChangeEvent when the rootPane property
427    * changes.
428    */
429   public static final String ROOT_PANE_PROPERTY = "rootPane";
430
431   /**
432    * The property fired in a PropertyChangeEvent when the title property
433    * changes.
434    */
435   public static final String TITLE_PROPERTY = "title";
436
437   /** Whether the JInternalFrame is closable. */
438   protected boolean closable;
439
440   /** Whether the JInternalFrame can be iconified. */
441   protected boolean iconable;
442
443   /** Whether the JInternalFrame is closed. */
444   protected boolean isClosed;
445
446   /** Whether the JInternalFrame has been iconified. */
447   protected boolean isIcon;
448
449   /** Whether the JInternalFrame has been maximized. */
450   protected boolean isMaximum;
451
452   /** Whether the JInternalFrame is the active frame. */
453   protected boolean isSelected;
454
455   /** Whether the JInternalFrame can be maximized. */
456   protected boolean maximizable;
457
458   /**
459    * Whether the JInternalFrame has rootPaneChecking enabled.
460    *
461    * @specnote Should be false to comply with J2SE 5.0
462    */
463   protected boolean rootPaneCheckingEnabled = false;
464
465   /** Whether the JInternalFrame is resizable. */
466   protected boolean resizable;
467
468   /**
469    * The JDesktopIcon that represents the JInternalFrame while it is
470    * iconified.
471    */
472   protected JDesktopIcon desktopIcon;
473
474   /** The icon used in the JMenuBar in the TitlePane. */
475   protected Icon frameIcon;
476
477   /** The rootPane of the JInternalFrame. */
478   protected JRootPane rootPane;
479
480   /** The title on the TitlePane of the JInternalFrame. */
481   protected String title;
482
483   /** The bounds of the JInternalFrame before it was maximized. */
484   private transient Rectangle storedBounds;
485
486   /** The Component that receives focus by default. */
487   private transient Component defaultFocus;
488
489   /** The default close action taken, */
490   private transient int defaultCloseOperation = DISPOSE_ON_CLOSE;
491
492   /** Whether the JInternalFrame has become visible for the very first time. */
493   private transient boolean isFirstTimeVisible = true;
494
495   /** DOCUMENT ME! */
496   private transient boolean wasIcon = false;
497
498   /**
499    * Creates a new JInternalFrame object that has an empty string for its 
500    * title, and is non-resizable, non-maximizable, non-iconifiable, and 
501    * non-closable.
502    */
503   public JInternalFrame()
504   {
505     this("", false, false, false, false);
506   }
507
508   /**
509    * Creates a new JInternalFrame object with the given title and is
510    * non-resizable, non-maximizable, non-iconifiable, and non-closable.
511    *
512    * @param title The title displayed in the JInternalFrame.
513    */
514   public JInternalFrame(String title)
515   {
516     this(title, false, false, false, false);
517   }
518
519   /**
520    * Creates a new JInternalFrame object with the given title and resizable
521    * properties. The JInternalFrame is non-maximizable, non-iconifiable, and
522    * non-closable.
523    *
524    * @param title The title displayed in the JInternalFrame.
525    * @param resizable Whether the JInternalFrame is resizable.
526    */
527   public JInternalFrame(String title, boolean resizable)
528   {
529     this(title, resizable, false, false, false);
530   }
531
532   /**
533    * Creates a new JInternalFrame object with the given title, resizable, and
534    * closable properties. The JInternalFrame is non-maximizable and
535    * non-iconifiable.
536    *
537    * @param title The title displayed in the JInternalFrame.
538    * @param resizable Whether the JInternalFrame is resizable.
539    * @param closable Whether the JInternalFrame is closable.
540    */
541   public JInternalFrame(String title, boolean resizable, boolean closable)
542   {
543     this(title, resizable, closable, false, false);
544   }
545
546   /**
547    * Creates a new JInternalFrame object with the given title, resizable,
548    * closable and maximizable properties. The JInternalFrame is
549    * non-iconifiable.
550    *
551    * @param title The title displayed in the JInternalFrame.
552    * @param resizable Whether the JInternalFrame is resizable.
553    * @param closable Whether the JInternalFrame is closable.
554    * @param maximizable Whether the JInternalFrame is maximizable.
555    */
556   public JInternalFrame(String title, boolean resizable, boolean closable,
557                         boolean maximizable)
558   {
559     this(title, resizable, closable, maximizable, false);
560   }
561
562   /**
563    * Creates a new JInternalFrame object with the given title, resizable,
564    * closable, maximizable and iconifiable properties.
565    *
566    * @param title The title displayed in the JInternalFrame.
567    * @param resizable Whether the JInternalFrame is resizable.
568    * @param closable Whether the JInternalFrame is closable.
569    * @param maximizable Whether the JInternalFrame is maximizable.
570    * @param iconifiable Whether the JInternalFrame is iconifiable.
571    */
572   public JInternalFrame(String title, boolean resizable, boolean closable,
573                         boolean maximizable, boolean iconifiable)
574   {
575     this.title = title;
576     this.resizable = resizable;
577     this.closable = closable;
578     this.maximizable = maximizable;
579     this.iconable = iconifiable;
580     isMaximum = false;
581     setRootPane(createRootPane());
582     // JInternalFrames are invisible and opaque by default.
583     setVisible(false);
584     setOpaque(true);
585     desktopIcon = new JDesktopIcon(this);
586     updateUI();
587     setRootPaneCheckingEnabled(true); // Done the init stage, now adds go to content pane.
588   }
589
590   /**
591    * This method adds Components to this Container. For JInternalFrames,
592    * instead of calling add directly on the JInternalFrame, it should be
593    * called with JInternalFrame.getContentPane().add. If root pane checking
594    * is enabled, calling this method will cause an exception to be thrown.
595    *
596    * @param comp The Component to add.
597    * @param constraints The constraints on the Component added.
598    * @param index The position to place the Component.
599    *
600    * @throws Error DOCUMENT ME!
601    */
602   protected void addImpl(Component comp, Object constraints, int index)
603   {
604     // If we're in the initialization stage use super.add. Here we add the
605     // rootPane as well as the title bar and other stuff.
606     // Otherwise pass the add onto the content pane.
607     if (isRootPaneCheckingEnabled())
608       getContentPane().add(comp, constraints, index);
609     else
610       super.addImpl(comp,constraints, index);
611   }
612
613   /**
614    * This method adds an InternalFrameListener to this JInternalFrame.
615    *
616    * @param l The listener to add.
617    */
618   public void addInternalFrameListener(InternalFrameListener l)
619   {
620     listenerList.add(InternalFrameListener.class, l);
621   }
622
623   /**
624    * This method is used to create a root pane for the JInternalFrame. This
625    * method is called by the constructors.
626    *
627    * @return A root pane for the JInternalFrame to use.
628    */
629   protected JRootPane createRootPane()
630   {
631     return new JRootPane();
632   }
633
634   /**
635    * This method makes this JInternalFrame invisible, unselected and closed.
636    * If this JInternalFrame is not closed already, it will fire an
637    * INTERNAL_FRAME_CLoSED event. This method is similar to setClosed but it
638    * doesn't give vetoable listeners a chance to veto and it will not fire an
639    * INTERNAL_FRAME_CLOSING event.
640    */
641   public void dispose()
642   {
643     if (isVisible())
644       setVisible(false);
645     if (isSelected())
646       {
647         try
648           {
649             setSelected(false);
650           }
651         catch (PropertyVetoException e)
652           {
653             // Do nothing if they don't want to be unselected.
654           }
655       }
656     if (! isClosed)
657       {
658         firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE, Boolean.TRUE);
659         isClosed = true;
660       }
661     fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
662   }
663
664   /**
665    * This method is used for closing this JInternalFrame. It fires an
666    * INTERNAL_FRAME_CLOSING event and then performs the action specified by
667    * the default close operation.
668    */
669   public void doDefaultCloseAction()
670   {
671     fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
672     switch (getDefaultCloseOperation())
673       {
674       case HIDE_ON_CLOSE:
675             setVisible(false);
676             break;
677       case DISPOSE_ON_CLOSE:
678             dispose();
679             break;
680       }
681   }
682
683   /**
684    * This method fires an InternalFrameEvent to the listeners.
685    *
686    * @param id The type of event being fired. See InternalFrameEvent.
687    */
688   protected void fireInternalFrameEvent(int id)
689   {
690     Object[] ifListeners = listenerList.getListenerList();
691     InternalFrameEvent evt = new InternalFrameEvent(this, id);
692     switch (id)
693       {
694       case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
695         for (int i = ifListeners.length - 2; i >= 0; i -= 2)
696           {
697             if (ifListeners[i] == InternalFrameListener.class)
698               ((InternalFrameListener) ifListeners[i + 1])
699               .internalFrameClosing(evt);
700           }
701         break;
702       case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
703         for (int i = ifListeners.length - 2; i >= 0; i -= 2)
704           {
705             if (ifListeners[i] == InternalFrameListener.class)
706               ((InternalFrameListener) ifListeners[i + 1])
707               .internalFrameActivated(evt);
708           }
709         break;
710       case InternalFrameEvent.INTERNAL_FRAME_CLOSED:
711         for (int i = ifListeners.length - 2; i >= 0; i -= 2)
712           {
713             if (ifListeners[i] == InternalFrameListener.class)
714               ((InternalFrameListener) ifListeners[i + 1]).internalFrameClosed(evt);
715           }
716         break;
717       case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
718         for (int i = ifListeners.length - 2; i >= 0; i -= 2)
719           {
720             if (ifListeners[i] == InternalFrameListener.class)
721               ((InternalFrameListener) ifListeners[i + 1])
722               .internalFrameDeactivated(evt);
723           }
724         break;
725       case InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED:
726         for (int i = ifListeners.length - 2; i >= 0; i -= 2)
727           {
728             if (ifListeners[i] == InternalFrameListener.class)
729               ((InternalFrameListener) ifListeners[i + 1])
730               .internalFrameDeiconified(evt);
731           }
732         break;
733       case InternalFrameEvent.INTERNAL_FRAME_ICONIFIED:
734         for (int i = ifListeners.length - 2; i >= 0; i -= 2)
735           {
736             if (ifListeners[i] == InternalFrameListener.class)
737               ((InternalFrameListener) ifListeners[i + 1])
738               .internalFrameIconified(evt);
739           }
740         break;
741       case InternalFrameEvent.INTERNAL_FRAME_OPENED:
742         for (int i = ifListeners.length - 2; i >= 0; i -= 2)
743           {
744             if (ifListeners[i] == InternalFrameListener.class)
745               ((InternalFrameListener) ifListeners[i + 1]).internalFrameOpened(evt);
746           }
747         break;
748       }
749   }
750
751   /**
752    * Returns the object that provides accessibility features for this
753    * <code>JInternalFrame</code> component.
754    *
755    * @return The accessible context (an instance of 
756    *     {@link AccessibleJInternalFrame}).
757    */
758   public AccessibleContext getAccessibleContext()
759   {
760     if (accessibleContext == null)
761       accessibleContext = new AccessibleJInternalFrame();
762     return accessibleContext;
763   }
764
765   /**
766    * This method returns the Content Pane for this JInternalFrame.
767    *
768    * @return The Content Pane for this JInternalFrame.
769    */
770   public Container getContentPane()
771   {
772     return getRootPane().getContentPane();
773   }
774
775   /**
776    * Returns a code for the default action taken when this 
777    * <code>JInternalFrame</code> is closed.
778    *
779    * @return The action code (usually one of 
780    *     {@link WindowConstants#DO_NOTHING_ON_CLOSE}, 
781    *     {@link WindowConstants#HIDE_ON_CLOSE}, or 
782    *     {@link WindowConstants#DISPOSE_ON_CLOSE}).
783    * 
784    * @see #setDefaultCloseOperation(int)
785    * @see #doDefaultCloseAction()
786    */
787   public int getDefaultCloseOperation()
788   {
789     return defaultCloseOperation;
790   }
791
792   /**
793    * Returns the <code>JDesktopIcon</code> that represents this 
794    * <code>JInternalFrame</code> while it is iconified.
795    *
796    * @return The desktop icon component.
797    */
798   public JDesktopIcon getDesktopIcon()
799   {
800     return desktopIcon;
801   }
802
803   /**
804    * This method searches this JInternalFrame ancestors for an instance of
805    * JDesktopPane. If one is found, it is returned. If none is found, then it
806    * will search the JDesktopIcon for a JDesktopPane.
807    *
808    * @return The JDesktopPane that this JInternalFrame belongs to.
809    */
810   public JDesktopPane getDesktopPane()
811   {
812     JDesktopPane value = (JDesktopPane) SwingUtilities.getAncestorOfClass(JDesktopPane.class,
813                                                                           this);
814     if (value == null && desktopIcon != null)
815       value = desktopIcon.getDesktopPane();
816     return value;
817   }
818
819   /**
820    * This method returns null because this must always be the root of a focus
821    * traversal.
822    *
823    * @return always null
824    *
825    * @since 1.4
826    */
827   public final Container getFocusCycleRootAncestor()
828   {
829     // as defined.
830     return null;
831   }
832
833   /**
834    * This method returns the child Component that will receive focus if this
835    * JInternalFrame is selected.
836    *
837    * @return The child Component that will receive focus.
838    */
839   public Component getFocusOwner()
840   {
841     if (isSelected())
842       {
843         Component focus = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
844         if (SwingUtilities.isDescendingFrom(focus, this))
845           {
846             defaultFocus = focus;
847             return focus;
848           }
849       }
850     return null;
851   }
852
853   /**
854    * This method returns the Frame Icon (the icon used in the JInternalFrame
855    * TitlePane and iconified frame).
856    *
857    * @return The Frame Icon.
858    */
859   public Icon getFrameIcon()
860   {
861     return frameIcon;
862   }
863
864   /**
865    * This method returns the Glass Pane used with this JInternalFrame.
866    *
867    * @return The Glass Pane used with this JInternalFrame.
868    */
869   public Component getGlassPane()
870   {
871     return getRootPane().getGlassPane();
872   }
873
874   /**
875    * This method returns an array of InternalFrameListeners that are listening
876    * to this JInternalFrame.
877    *
878    * @return An array of InternalFrameListeners that are listening to this
879    *         JInternalFrame.
880    */
881   public InternalFrameListener[] getInternalFrameListeners()
882   {
883     return (InternalFrameListener[]) listenerList.getListeners(InternalFrameListener.class);
884   }
885
886   /**
887    * This method returns the JMenuBar for this JInternalFrame.
888    *
889    * @return The JMenuBar for this JInternalFrame.
890    */
891   public JMenuBar getJMenuBar()
892   {
893     return getRootPane().getJMenuBar();
894   }
895
896   /**
897    * This method returns the layer that this JInternalFrame resides in.
898    *
899    * @return The layer that this JInternalFrame resides in.
900    */
901   public int getLayer()
902   {
903     return JLayeredPane.getLayer(this);
904   }
905
906   /**
907    * This method returns the LayeredPane for this JInternalFrame.
908    *
909    * @return The LayeredPane for this JInternalFrame.
910    */
911   public JLayeredPane getLayeredPane()
912   {
913     return getRootPane().getLayeredPane();
914   }
915
916   /**
917    * This method is deprecated. This method returns the JMenuBar for this
918    * JInternalFrame.
919    *
920    * @return The JMenuBar for this JInternalFrame.
921    *
922    * @deprecated 1.0.3
923    */
924   public JMenuBar getMenuBar()
925   {
926     return getJMenuBar();
927   }
928
929   /**
930    * This method returns the child Component that will receive focus when the
931    * JInternalFrame is selected. If the JInternalFrame is selected, this
932    * method returns getFocusOwner(). Otherwise, it will return the child
933    * Component that most recently requested focus. If that is null, then the
934    * initial focus Component is returned. If that is null, then the default
935    * focus component is returned.
936    *
937    * @return The most recent focus owner.
938    */
939   public Component getMostRecentFocusOwner()
940   {
941     if (isSelected())
942       return getFocusOwner();
943     else
944       return defaultFocus;
945   }
946
947   /**
948    * This method returns the bounds of the JInternalFrame if it is not
949    * maximized. If it is maximized, it returns the bounds of the
950    * JInternalFrame before it was maximized (the bounds that it will be
951    * restored to).
952    *
953    * @return A Rectangle that contains this JInternalFrame's normal bounds (or
954    *         just its bounds if it is not maximized).
955    */
956   public Rectangle getNormalBounds()
957   {
958     if (storedBounds == null)
959       return getBounds();
960     else
961       return storedBounds;
962   }
963
964   /**
965    * This method returns the Root Pane for this JInternalFrame.
966    *
967    * @return The Root Pane for this JInternalFrame.
968    */
969   public JRootPane getRootPane()
970   {
971     return rootPane;
972   }
973
974   /**
975    * Returns the frame's title.
976    *
977    * @return The frame's title (can be <code>null</code>).
978    * 
979    * @see #setTitle(String)
980    */
981   public String getTitle()
982   {
983     return title;
984   }
985
986   /**
987    * This method returns the UI used to represent the JInternalFrame.
988    *
989    * @return The UI used to represent the JInternalFrame.
990    */
991   public InternalFrameUI getUI()
992   {
993     return (InternalFrameUI) ui;
994   }
995
996   /**
997    * This method returns a String identifier that is used to determine which
998    * class acts as the JInternalFrame's UI.
999    *
1000    * @return A String identifier to determine a UI class.
1001    */
1002   public String getUIClassID()
1003   {
1004     return "InternalFrameUI";
1005   }
1006
1007   /**
1008    * This method returns null.
1009    *
1010    * @return null.
1011    */
1012   public final String getWarningString()
1013   {
1014     // as defined.
1015     return null;
1016   }
1017
1018   /**
1019    * This method deselects this JInternalFrame and hides it.
1020    */
1021   public void hide()
1022   {
1023     if (isIcon())
1024       getDesktopIcon().hide();
1025     super.hide();
1026   }
1027
1028   /**
1029    * This method returns whether this JInternalFrame is closable.
1030    *
1031    * @return Whether this JInternalFrame is closable.
1032    */
1033   public boolean isClosable()
1034   {
1035     return closable;
1036   }
1037
1038   /**
1039    * This method returns whether this JInternalFrame has been closed.
1040    *
1041    * @return Whether this JInternalFrame is closed.
1042    */
1043   public boolean isClosed()
1044   {
1045     return isClosed;
1046   }
1047
1048   /**
1049    * This must always return true.
1050    *
1051    * @return always true
1052    *
1053    * @since 1.4
1054    */
1055   public final boolean isFocusCycleRoot()
1056   {
1057     return true;
1058   }
1059
1060   /**
1061    * This method returns whether this JInternalFrame is currently iconified.
1062    *
1063    * @return Whether this JInternalFrame is currently iconified.
1064    */
1065   public boolean isIcon()
1066   {
1067     return isIcon;
1068   }
1069
1070   /**
1071    * This method returns whether the JInternalFrame can be iconified.
1072    *
1073    * @return Whether the JInternalFrame can be iconified.
1074    */
1075   public boolean isIconifiable()
1076   {
1077     return iconable;
1078   }
1079
1080   /**
1081    * This method returns whether this JInternalFrame can be maximized.
1082    *
1083    * @return Whether this JInternalFrame can be maximized.
1084    */
1085   public boolean isMaximizable()
1086   {
1087     return maximizable;
1088   }
1089
1090   /**
1091    * This method returns whether this JInternalFrame is currently maximized.
1092    *
1093    * @return Whether this JInternalFrame is maximized.
1094    */
1095   public boolean isMaximum()
1096   {
1097     return isMaximum;
1098   }
1099
1100   /**
1101    * This method returns whether this JInternalFrame is resizable.
1102    *
1103    * @return Whether this JInternalFrame is resizable.
1104    */
1105   public boolean isResizable()
1106   {
1107     return resizable;
1108   }
1109
1110   /**
1111    * This method returns whether root pane checking is enabled. If root pane
1112    * checking is enabled, then calls to addImpl and setLayout will throw
1113    * exceptions.
1114    *
1115    * @return Whether root pane checking is enabled.
1116    */
1117   protected boolean isRootPaneCheckingEnabled()
1118   {
1119     return rootPaneCheckingEnabled;
1120   }
1121
1122   /**
1123    * This method returns whether this JInternalFrame is selected.
1124    *
1125    * @return Whether this JInternalFrame is selected.
1126    */
1127   public boolean isSelected()
1128   {
1129     return isSelected;
1130   }
1131
1132   /**
1133    * A helper method that moves this JInternalFrame to the back if the parent
1134    * is a JLayeredPane.
1135    */
1136   public void moveToBack()
1137   {
1138     Container p = getParent();
1139     if (p instanceof JLayeredPane)
1140       ((JLayeredPane) p).moveToBack(this);
1141   }
1142
1143   /**
1144    * A helper method that moves this JInternalFrame to the front if the parent
1145    * is a JLayeredPane.
1146    */
1147   public void moveToFront()
1148   {
1149     Container p = getParent();
1150     if (p != null && p instanceof JLayeredPane)
1151       ((JLayeredPane) p).moveToFront(this);
1152   }
1153
1154   /**
1155    * This method causes the children of this JInternalFrame to be laid out.
1156    * Before it begins, if this JInternalFrame is an icon, then it will be
1157    * deiconified. If it is maximized, then it will be restored. If either
1158    * operation fails, then this method will return.
1159    */
1160   public void pack()
1161   {
1162     try
1163       {
1164         if (isIcon())
1165           setIcon(false);
1166         else if (isMaximum())
1167           setMaximum(false);
1168       }
1169     catch (PropertyVetoException e)
1170       {
1171         // Do nothing if they don't want to be restored first.
1172       }
1173     setSize(getPreferredSize());
1174     validate();
1175   }
1176
1177   /**
1178    * This method is overridden to allow for speedier painting while this
1179    * JInternalFramme is being dragged.
1180    *
1181    * @param g The Graphics object to paint with.
1182    */
1183   protected void paintComponent(Graphics g)
1184   {
1185     super.paintComponent(g);
1186   }
1187
1188   /**
1189    * An implementation dependent string describing the current state of this 
1190    * <code>JInternalFrame</code> instance.
1191    *
1192    * @return A string describing the current state of this 
1193    *     <code>JInternalFrame</code> instance.
1194    */
1195   protected String paramString()
1196   {
1197     return super.paramString() + ",title=" + getTitle();
1198   }
1199
1200   /**
1201    * This method removes the given Component from the Container.
1202    *
1203    * @param comp The Component to remove.
1204    */
1205   public void remove(Component comp)
1206   {
1207     // If we're removing the root pane, use super.remove.  Otherwise
1208     // pass it on to the content pane instead.
1209     if (comp==rootPane || ! isRootPaneCheckingEnabled())
1210       super.remove(comp);
1211     else
1212       getContentPane().remove(comp);
1213   }
1214
1215   /**
1216    * This method removes an InternalFrameListener from this JInternalFrame.
1217    *
1218    * @param l The listener to remove.
1219    */
1220   public void removeInternalFrameListener(InternalFrameListener l)
1221   {
1222     listenerList.remove(InternalFrameListener.class, l);
1223   }
1224
1225   /**
1226    * This method resizes and positions this JInternalFrame. It also forces a
1227    * relayout of the Container.
1228    *
1229    * @param x The x position of this JInternalFrame.
1230    * @param y The y position of this JInternalFrame.
1231    * @param width The width of this JInternalFrame.
1232    * @param height The height of this JInternalFrame.
1233    */
1234   public void reshape(int x, int y, int width, int height)
1235   {
1236     super.reshape(x, y, width, height);
1237     revalidate();
1238   }
1239
1240   /**
1241    * This method gives focus to the last child Component that had focus. This
1242    * is used by the UI when this JInternalFrame is activated.
1243    */
1244   public void restoreSubcomponentFocus()
1245   {
1246     Component c = getMostRecentFocusOwner();
1247     if (c != null)
1248       c.requestFocus();
1249   }
1250
1251   /**
1252    * This method sets whether this JInternalFrame can be closed.
1253    *
1254    * @param b Whether this JInternalFrame can be closed.
1255    */
1256   public void setClosable(boolean b)
1257   {
1258     if (closable != b)
1259       {
1260         closable = b;
1261         firePropertyChange("closable", ! closable, closable);
1262       }
1263   }
1264
1265   /**
1266    * This method closes the JInternalFrame if the given boolean is true. If it
1267    * is false, then the result of this method is unspecified. If the
1268    * JInternalFrame is closed, this method does nothing. This method will
1269    * first fire an INTERNAL_FRAME_CLOSING event and give a chance for veto
1270    * listeners to cancel the close. If no listener vetoes the change, the
1271    * closed property is set to true and the JInternalFrame is hidden and
1272    * unselected. The method will finish by firing an INTERNAL_FRAME_CLOSED
1273    * event.
1274    *
1275    * @param b Whether the JInternalFrame will be closed.
1276    *
1277    * @throws PropertyVetoException If a VetoableChangeListener vetoes the change.
1278    */
1279   public void setClosed(boolean b) throws PropertyVetoException
1280   {
1281     if (b && ! isClosed())
1282       {
1283         fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
1284         fireVetoableChange(IS_CLOSED_PROPERTY, false, true);
1285
1286         isClosed = b;
1287         dispose();
1288
1289         firePropertyChange(IS_CLOSED_PROPERTY, false, true);
1290       }
1291   }
1292
1293   /**
1294    * This method sets the Container to be used as a Content Pane for this
1295    * JInternalFrame.
1296    *
1297    * @param c The Container to use as a Content Pane.
1298    */
1299   public void setContentPane(Container c)
1300   {
1301     if (c != getContentPane())
1302       {
1303         Container old = getContentPane();
1304         getRootPane().setContentPane(c);
1305         firePropertyChange(CONTENT_PANE_PROPERTY, old, c);
1306       }
1307   }
1308
1309   /**
1310    * Sets a code for the action to be taken when this 
1311    * <code>JInternalFrame</code> is closed.  Note that no validation is 
1312    * performed on the <code>operation</code> code, any integer will be 
1313    * accepted (nevertheless, you should pass in one of the listed values).
1314    *
1315    * @param operation  one of {@link WindowConstants#DO_NOTHING_ON_CLOSE}, 
1316    *   {@link WindowConstants#HIDE_ON_CLOSE} or 
1317    *   {@link WindowConstants#DISPOSE_ON_CLOSE}.
1318    *   
1319    * @see #getDefaultCloseOperation()
1320    * @see #doDefaultCloseAction()
1321    */
1322   public void setDefaultCloseOperation(int operation)
1323   {
1324     /* Reference implementation allows invalid operations to be specified.
1325        In that case, behaviour defaults to DO_NOTHING_ON_CLOSE.
1326        processWindowEvent handles the behaviour. getDefaultCloseOperation
1327        must return the invalid operator code. */
1328     defaultCloseOperation = operation;
1329   }
1330
1331   /**
1332    * Sets the <code>JDesktopIcon</code> instance that represents this 
1333    * <code>JInternalFrame</code> while it is iconified and, if the new icon is
1334    * not the same instance as the existing icon, sends a 
1335    * {@link PropertyChangeEvent} (with the property name 
1336    * <code>"desktopIcon"</code>) to all registered listeners..
1337    *
1338    * @param d  the icon.
1339    * 
1340    * @see #getDesktopIcon()
1341    */
1342   public void setDesktopIcon(JDesktopIcon d)
1343   {
1344     if (desktopIcon != d)
1345       {
1346         JDesktopIcon oldIcon = desktopIcon;
1347         desktopIcon = d;
1348         firePropertyChange("desktopIcon", oldIcon, d);
1349       }
1350   }
1351
1352   /**
1353    * This method does nothing because this must be the root of a focus
1354    * traversal cycle.
1355    *
1356    * @param focusCycleRoot Not used.
1357    */
1358   public final void setFocusCycleRoot(boolean focusCycleRoot)
1359   {
1360     // Do nothing
1361   }
1362
1363   /**
1364    * This method sets the Icon to be used in two places. The first is icon
1365    * that is painted at the top left corner of the JInternalFrame when it is
1366    * not iconified (clicking on that icon will activate the TitlePane
1367    * JMenuBar). When the JInternalFrame is iconified, it will be the icon
1368    * displayed in the JDesktopIcon. If no icon is set, the JInternalFrame
1369    * will use a Look and Feel default.
1370    *
1371    * @param icon The Icon used in the TitlePane JMenuBar and iconified frames.
1372    */
1373   public void setFrameIcon(Icon icon)
1374   {
1375     if (icon != frameIcon)
1376       {
1377         Icon old = frameIcon;
1378         frameIcon = icon;
1379         firePropertyChange(FRAME_ICON_PROPERTY, old, frameIcon);
1380       }
1381   }
1382
1383   /**
1384    * This method sets the Glass Pane used with this JInternalFrame.
1385    *
1386    * @param glass The Glass Pane to use with this JInternalFrame.
1387    */
1388   public void setGlassPane(Component glass)
1389   {
1390     if (glass != getGlassPane())
1391       {
1392         Component old = getGlassPane();
1393         getRootPane().setGlassPane(glass);
1394         firePropertyChange(GLASS_PANE_PROPERTY, old, glass);
1395       }
1396   }
1397
1398   /**
1399    * This method iconifies or deiconifies this JInternalFrame given the
1400    * boolean argument. If the JInternalFrame becomes iconified, it will fire
1401    * an INTERNAL_FRAME_ICONIFIED event. If the JInternalFrame becomes
1402    * deiconified, it will fire anINTERNAL_FRAME_DEICONIFIED event.
1403    *
1404    * @param b Whether this JInternalFrame is to be iconified or deiconified.
1405    *
1406    * @throws PropertyVetoException DOCUMENT ME!
1407    */
1408   public void setIcon(boolean b) throws PropertyVetoException
1409   {
1410     if (b != isIcon())
1411       {
1412         fireVetoableChange(IS_ICON_PROPERTY, b, isIcon);
1413
1414         isIcon = b;
1415
1416         firePropertyChange(IS_ICON_PROPERTY, ! isIcon, isIcon);
1417         if (b)
1418           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
1419         else
1420           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
1421       }
1422   }
1423
1424   /**
1425    * This method sets whether the JInternalFrame can be iconified. (This means
1426    * that the JInternalFrame can be turned into an icon if minimized).
1427    *
1428    * @param b Whether the JInternalFrame can be iconified.
1429    */
1430   public void setIconifiable(boolean b)
1431   {
1432     if (iconable != b)
1433       {
1434         iconable = b;
1435         firePropertyChange("iconable", ! iconable, iconable);
1436       }
1437   }
1438
1439   /**
1440    * This method sets the JMenuBar to be used with this JInternalFrame.
1441    *
1442    * @param b The JMenuBar to be used with this JInternalFrame.
1443    */
1444   public void setJMenuBar(JMenuBar b)
1445   {
1446     JMenuBar old = getJMenuBar();
1447     getRootPane().setJMenuBar(b);
1448     firePropertyChange(MENU_BAR_PROPERTY, old, b);
1449   }
1450
1451   /**
1452    * A helper method that set the layer that this JInternalFrame resides in.
1453    * Using this version of the method means that the user should not set it
1454    * to values that are already defined in JLayeredPane. If predefined values
1455    * are to be used, the user should use the setLayer(Integer) version.
1456    *
1457    * @param layer The layer to place this JInternalFrame in.
1458    */
1459   public void setLayer(int layer)
1460   {
1461     setLayer(new Integer(layer));
1462   }
1463
1464   /**
1465    * A helper method that sets the layer that this JInternalFrame resides in.
1466    * Calling this version of the method should use layer values that are
1467    * already defined in JLayeredPane.
1468    *
1469    * @param layer The layer to place this JInternalFrame in.
1470    */
1471   public void setLayer(Integer layer)
1472   {
1473     Container p = getParent();
1474     if (p instanceof JLayeredPane)
1475       {
1476         JLayeredPane lp = (JLayeredPane) p;
1477         lp.setLayer(this, layer.intValue(), lp.getPosition(this));
1478       }
1479     else
1480       {
1481         JLayeredPane.putLayer(this, layer.intValue());
1482         if (p != null)
1483           p.repaint(getX(), getY(), getWidth(), getHeight());
1484       }
1485   }
1486
1487   /**
1488    * This method sets the JLayeredPane to use with this JInternalFrame.
1489    *
1490    * @param layered The JLayeredPane to use as a layeredPane.
1491    */
1492   public void setLayeredPane(JLayeredPane layered)
1493   {
1494     if (layered == null)
1495       throw new IllegalComponentStateException("LayeredPane must not be null");
1496
1497     if (layered != getLayeredPane())
1498       {
1499         JLayeredPane old = getLayeredPane();
1500         getRootPane().setLayeredPane(layered);
1501         firePropertyChange(LAYERED_PANE_PROPERTY, old, layered);
1502       }
1503   }
1504
1505   /**
1506    * This method sets whether the JInternalFrame can be maximized.
1507    *
1508    * @param b Whether this JInternalFrame can be maximized.
1509    */
1510   public void setMaximizable(boolean b)
1511   {
1512     if (maximizable != b)
1513       {
1514         maximizable = b;
1515         firePropertyChange("maximizable", ! maximizable, maximizable);
1516       }
1517   }
1518
1519   /**
1520    * This method sets the Layout Manager used in the JInternalFrame. SetLayout
1521    * should not be called on the JInternalFrame directly. Instead, it should
1522    * be called with JInternalFrame.getContentPane().setLayout. Calls to this
1523    * method with root pane checking enabled will cause exceptions to be
1524    * thrown.
1525    *
1526    * @param manager The Layout Manager to be used with the JInternalFrame.
1527    *
1528    * @throws Error If rootPaneChecking is enabled.
1529    */
1530   public void setLayout(LayoutManager manager)
1531   {
1532     // Check if we're in initialization stage.  If so, call super.setLayout
1533     // otherwise, valid calls go to the content pane.
1534     if (isRootPaneCheckingEnabled())
1535       getContentPane().setLayout(manager);
1536     else
1537       super.setLayout(manager);
1538   }
1539
1540   /**
1541    * This method sets the JInternalFrame to maximized (if the given argument
1542    * is true) or restores the JInternalFrame to its normal bounds otherwise.
1543    *
1544    * @param b Whether this JInteralFrame will be maximized or restored.
1545    *
1546    * @throws PropertyVetoException If a VetoableChangeListener vetoes the change.
1547    */
1548   public void setMaximum(boolean b) throws PropertyVetoException
1549   {
1550     if (b != isMaximum)
1551       {
1552         fireVetoableChange(IS_MAXIMUM_PROPERTY, isMaximum, b);
1553         isMaximum = b;
1554         firePropertyChange(IS_MAXIMUM_PROPERTY, ! isMaximum, isMaximum);
1555       }
1556   }
1557
1558   /**
1559    * This method is deprecated. This method sets the JMenuBar used with this
1560    * JInternalFrame.
1561    *
1562    * @param m The JMenuBar to use with this JInternalFrame.
1563    *
1564    * @deprecated 1.0.3
1565    */
1566   public void setMenuBar(JMenuBar m)
1567   {
1568     setJMenuBar(m);
1569   }
1570
1571   /**
1572    * This method sets the bounds that this JInternalFrame will be restored to.
1573    *
1574    * @param r The bounds that this JInternalFrame will be restored to.
1575    */
1576   public void setNormalBounds(Rectangle r)
1577   {
1578     storedBounds = r;
1579   }
1580
1581   /**
1582    * This method sets whether the JInternalFrame can be resized by a user
1583    * action (like dragging at the frame borders).
1584    *
1585    * @param b Whether this JInternalFramer can be resized.
1586    */
1587   public void setResizable(boolean b)
1588   {
1589     if (b != resizable)
1590       {
1591         resizable = b;
1592         firePropertyChange("resizable", ! resizable, resizable);
1593       }
1594   }
1595
1596   /**
1597    * This method sets the Root Pane for this JInternalFrame.
1598    *
1599    * @param root The Root Pane for this JInternalFrame.
1600    */
1601   protected void setRootPane(JRootPane root)
1602   {
1603     if (rootPane != null)
1604       remove(rootPane);
1605
1606     JRootPane old = rootPane;
1607     rootPane = root;
1608
1609     if (rootPane != null)
1610       {
1611         boolean checkingEnabled = isRootPaneCheckingEnabled();
1612         try
1613           {
1614             setRootPaneCheckingEnabled(false);
1615             add(rootPane, BorderLayout.CENTER);
1616           }
1617         finally
1618           {
1619             setRootPaneCheckingEnabled(checkingEnabled);
1620           }
1621       }
1622     firePropertyChange(ROOT_PANE_PROPERTY, old, rootPane);
1623   }
1624
1625   /**
1626    * This method sets whether root pane checking is enabled. If root pane
1627    * checking is enabled, then calls to addImpl and setLayout will throw
1628    * exceptions.
1629    *
1630    * @param enabled Whether root pane checking is enabled.
1631    */
1632   protected void setRootPaneCheckingEnabled(boolean enabled)
1633   {
1634     rootPaneCheckingEnabled = enabled;
1635   }
1636
1637   /**
1638    * This method sets whether this JInternalFrame is the selected frame in the
1639    * JDesktopPane (or other container). When selected, a JInternalFrame will
1640    * have focus and paint its TitlePane differently (usually a different
1641    * colour). If this method selects the frame, this JInternalFrame will fire
1642    * an INTERNAL_FRAME_ACTIVATED event. If it deselects this frame, it will
1643    * fire an INTERNAL_FRAME_DEACTIVATED event.
1644    *
1645    * @param selected Whether this JInternalFrame will become selected or
1646    *        deselected.
1647    *
1648    * @throws PropertyVetoException If a VetoableChangeListener vetoes the change.
1649    */
1650   public void setSelected(boolean selected) throws PropertyVetoException
1651   {
1652     if (selected != isSelected
1653         && (! selected || (isIcon ? desktopIcon.isShowing() : isShowing())))
1654       {
1655         fireVetoableChange(IS_SELECTED_PROPERTY, isSelected, selected);
1656
1657         if (! selected)
1658           defaultFocus = getMostRecentFocusOwner();
1659
1660         isSelected = selected;
1661         firePropertyChange(IS_SELECTED_PROPERTY, ! isSelected, isSelected);
1662
1663         if (isSelected)
1664           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED);
1665         else
1666           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
1667
1668         if (selected)
1669           restoreSubcomponentFocus();
1670
1671         repaint();
1672       }
1673   }
1674
1675   /**
1676    * Sets the title for the <code>JInternalFrame</code> and sends a 
1677    * {@link PropertyChangeEvent} (with the property name 
1678    * {@link #TITLE_PROPERTY}) to all registered listeners.
1679    *
1680    * @param title  the new title (<code>null</code> permitted).
1681    * 
1682    * @see #getTitle()
1683    */
1684   public void setTitle(String title)
1685   {
1686     String old = this.title;
1687     this.title = title;
1688     firePropertyChange(TITLE_PROPERTY, old, this.title);
1689   }
1690
1691   /**
1692    * This method displays the JInternalFrame. If it is not visible, this
1693    * method will bring this JInternalFrame to the front, make it visible and
1694    * select it. If this is the first time this JInternalFrame is made
1695    * visible, an INTERNAL_FRAME_OPENED event will be fired.
1696    */
1697   public void show()
1698   {
1699     if (! isVisible())
1700       {
1701         if (isFirstTimeVisible)
1702           {
1703             isFirstTimeVisible = false;
1704             fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
1705           }
1706
1707         getDesktopIcon().setVisible(true);
1708
1709         toFront();
1710         super.show();
1711
1712         if (isIcon())
1713           return;
1714
1715         if (! isSelected())
1716           {
1717             try
1718               {
1719                 setSelected(true);
1720               }
1721             catch (PropertyVetoException e)
1722               {
1723                 // Do nothing. if they don't want to be selected.
1724               }
1725           }
1726       }
1727   }
1728
1729   /**
1730    * This method is used to set the UI responsible for the JInternalFrame.
1731    *
1732    * @param ui The UI responsible for the JInternalFrame.
1733    */
1734   public void setUI(InternalFrameUI ui)
1735   {
1736     // We must temporarily go into init mode so that the UI can directly
1737     // manipulate the JInternalFrame.
1738     boolean old = isRootPaneCheckingEnabled();
1739     setRootPaneCheckingEnabled(false);
1740     super.setUI(ui);
1741     setRootPaneCheckingEnabled(old);
1742   }
1743
1744   /**
1745    * This method causes the JInternalFrame to be brough to back in the
1746    * z-order.
1747    */
1748   public void toBack()
1749   {
1750     moveToBack();
1751   }
1752
1753   /**
1754    * This method causes the JInternalFrame to be brought to front in the
1755    * z-order.
1756    */
1757   public void toFront()
1758   {
1759     moveToFront();
1760   }
1761
1762   /**
1763    * This method resets the UI to the Look and Feel defaults.
1764    */
1765   public void updateUI()
1766   {
1767     // We must go into the init stage when updating the UI, so the UI can
1768     // set layout and components directly on the internal frame, not its
1769     // content pane.
1770         boolean old = isRootPaneCheckingEnabled();
1771     setRootPaneCheckingEnabled(false);
1772     setUI((InternalFrameUI) UIManager.getUI(this));
1773     setRootPaneCheckingEnabled(old);
1774   }
1775
1776   /**
1777    * This helper method allows JInternalFrames to signal that they were
1778    * iconned for the first time.
1779    *
1780    * @param b Whether the JInternalFrame was iconned.
1781    * @param ID The identifier of the property change event to fire if the
1782    *        JInternalFrame is iconned for the first time.
1783    */
1784   void setWasIcon(boolean b, String ID)
1785   {
1786     if (b && ! wasIcon)
1787       {
1788         wasIcon = b;
1789         firePropertyChange(ID, ! b, b);
1790       }
1791   }
1792
1793   /**
1794    * This helper method returns whether the JInternalFrame has been iconned
1795    * once already.
1796    *
1797    * @return Whether the JInternalFrame has been iconned once already.
1798    */
1799   boolean getWasIcon()
1800   {
1801     return wasIcon;
1802   }
1803
1804   /**
1805    * This method is a convenience method to fire vetoable property changes.
1806    *
1807    * @param name The identifier of the property change.
1808    * @param oldValue The old value.
1809    * @param newValue The new value.
1810    *
1811    * @throws PropertyVetoException Fired if a vetoable change listener vetoes
1812    *         the change.
1813    */
1814   private void fireVetoableChange(String name, boolean oldValue,
1815                                   boolean newValue)
1816                            throws PropertyVetoException
1817   {
1818     super.fireVetoableChange(name, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
1819   }
1820 }