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     * should become selected (currently active)
1005     * and <code>false</code> means it should become deselected
1006     * @exception PropertyVetoException when the attempt to set the
1007     * property is vetoed by the <code>JInternalFrame</code>
1008     *
1009     * @see #isShowing
1010     * @see InternalFrameEvent#INTERNAL_FRAME_ACTIVATED
1011     * @see InternalFrameEvent#INTERNAL_FRAME_DEACTIVATED
1012     *
1013     * @beaninfo
1014     * constrained: true
1015     * bound: true
1016     * description: Indicates whether this internal frame is currently
1017     * the active frame.
1018     */

1019    public void setSelected(boolean selected) throws PropertyVetoException JavaDoc {
1020        // The internal frame or the desktop icon must be showing to allow
1021
// selection. We may deselect even if neither is showing.
1022
if ((isSelected == selected) || (selected &&
1023            (isIcon ? !desktopIcon.isShowing() : !isShowing()))) {
1024            return;
1025        }
1026
1027        Boolean JavaDoc oldValue = isSelected ? Boolean.TRUE : Boolean.FALSE;
1028        Boolean JavaDoc newValue = selected ? Boolean.TRUE : Boolean.FALSE;
1029        fireVetoableChange(IS_SELECTED_PROPERTY, oldValue, newValue);
1030
1031    /* We don't want to leave focus in the previously selected
1032       frame, so we have to set it to *something* in case it
1033       doesn't get set in some other way (as if a user clicked on
1034       a component that doesn't request focus). If this call is
1035       happening because the user clicked on a component that will
1036       want focus, then it will get transfered there later.
1037
1038       We test for parent.isShowing() above, because AWT throws a
1039       NPE if you try to request focus on a lightweight before its
1040       parent has been made visible */

1041
1042        lastFocusOwner = null;
1043    if (selected) {
1044        restoreSubcomponentFocus();
1045    } else {
1046        getRootPane().setMostRecentFocusOwner(getFocusOwner());
1047    }
1048
1049        isSelected = selected;
1050        firePropertyChange(IS_SELECTED_PROPERTY, oldValue, newValue);
1051    if (isSelected)
1052      fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED);
1053    else
1054      fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
1055        lastFocusOwner = null;
1056        repaint();
1057    }
1058
1059    /**
1060     * Returns whether the <code>JInternalFrame</code> is the
1061     * currently "selected" or active frame.
1062     *
1063     * @return <code>true</code> if this internal frame is currently selected (active)
1064     * @see #setSelected
1065     */

1066    public boolean isSelected() {
1067        return isSelected;
1068    }
1069
1070    /**
1071     * Sets an image to be displayed in the titlebar of this internal frame (usually
1072     * in the top-left corner).
1073     * This image is not the <code>desktopIcon</code> object, which
1074     * is the image displayed in the <code>JDesktop</code> when
1075     * this internal frame is iconified.
1076     *
1077     * Passing <code>null</code> to this function is valid,
1078     * but the look and feel
1079     * can choose the
1080     * appropriate behavior for that situation, such as displaying no icon
1081     * or a default icon for the look and feel.
1082     *
1083     * @param icon the <code>Icon</code> to display in the title bar
1084     * @see #getFrameIcon
1085     * @beaninfo
1086     * bound: true
1087     * description: The icon shown in the top-left corner of this internal frame.
1088     */

1089  public void setFrameIcon(Icon JavaDoc icon) {
1090        Icon JavaDoc oldIcon = frameIcon;
1091        frameIcon = icon;
1092        firePropertyChange(FRAME_ICON_PROPERTY, oldIcon, icon);
1093    }
1094
1095    /**
1096     * Returns the image displayed in the title bar of this internal frame (usually
1097     * in the top-left corner).
1098     *
1099     * @return the <code>Icon</code> displayed in the title bar
1100     * @see #setFrameIcon
1101     */

1102    public Icon JavaDoc getFrameIcon() {
1103        return frameIcon;
1104    }
1105
1106    /**
1107      * Convenience method that moves this component to position 0 if its
1108      * parent is a <code>JLayeredPane</code>.
1109      */

1110    public void moveToFront() {
1111        if(getParent() != null && getParent() instanceof JLayeredPane JavaDoc) {
1112            JLayeredPane JavaDoc l = (JLayeredPane JavaDoc)getParent();
1113            // Because move to front typically involves adding and removing
1114
// Components, it will often times result in focus changes. We
1115
// either install focus to the lastFocusOwner, or our desendant
1116
// that has focus. We use the ivar for lastFocusOwner as in
1117
// some cases requestFocus is async and won't have completed from
1118
// the requestFocus call in setSelected so that getFocusOwner
1119
// will return the wrong component.
1120
Component focusOwner = (lastFocusOwner != null) ? lastFocusOwner :
1121                         KeyboardFocusManager.getCurrentKeyboardFocusManager().
1122                         getFocusOwner();
1123
1124            if (focusOwner != null &&
1125                     !SwingUtilities.isDescendingFrom(focusOwner, this)) {
1126                focusOwner = null;
1127            }
1128            l.moveToFront(this);
1129            if (focusOwner != null) {
1130                focusOwner.requestFocus();
1131            }
1132        }
1133    }
1134
1135    /**
1136      * Convenience method that moves this component to position -1 if its
1137      * parent is a <code>JLayeredPane</code>.
1138      */

1139    public void moveToBack() {
1140        if(getParent() != null && getParent() instanceof JLayeredPane JavaDoc) {
1141            JLayeredPane JavaDoc l = (JLayeredPane JavaDoc)getParent();
1142            l.moveToBack(this);
1143        }
1144    }
1145
1146    /**
1147     * Convenience method for setting the layer attribute of this component.
1148     *
1149     * @param layer an <code>Integer</code> object specifying this
1150     * frame's desktop layer
1151     * @see JLayeredPane
1152     * @beaninfo
1153     * expert: true
1154     * description: Specifies what desktop layer is used.
1155     */

1156    public void setLayer(Integer JavaDoc layer) {
1157        if(getParent() != null && getParent() instanceof JLayeredPane JavaDoc) {
1158            // Normally we want to do this, as it causes the LayeredPane
1159
// to draw properly.
1160
JLayeredPane JavaDoc p = (JLayeredPane JavaDoc)getParent();
1161            p.setLayer(this, layer.intValue(), p.getPosition(this));
1162        } else {
1163             // Try to do the right thing
1164
JLayeredPane.putLayer(this, layer.intValue());
1165             if(getParent() != null)
1166                 getParent().repaint(getX(), getY(), getWidth(), getHeight());
1167        }
1168    }
1169
1170    /**
1171     * Convenience method for setting the layer attribute of this component.
1172     * The method <code>setLayer(Integer)</code> should be used for
1173     * layer values predefined in <code>JLayeredPane</code>.
1174     * When using <code>setLayer(int)</code>, care must be taken not to
1175     * accidentally clash with those values.
1176     *
1177     * @param layer an integer specifying this internal frame's desktop layer
1178     *
1179     * @since 1.3
1180     *
1181     * @see #setLayer(Integer)
1182     * @see JLayeredPane
1183     * @beaninfo
1184     * expert: true
1185     * description: Specifies what desktop layer is used.
1186     */

1187    public void setLayer(int layer) {
1188      this.setLayer(new Integer JavaDoc(layer));
1189    }
1190
1191    /**
1192     * Convenience method for getting the layer attribute of this component.
1193     *
1194     * @return an <code>Integer</code> object specifying this
1195     * frame's desktop layer
1196     * @see JLayeredPane
1197      */

1198    public int getLayer() {
1199        return JLayeredPane.getLayer(this);
1200    }
1201
1202    /**
1203      * Convenience method that searches the ancestor hierarchy for a
1204      * <code>JDesktop</code> instance. If <code>JInternalFrame</code>
1205      * finds none, the <code>desktopIcon</code> tree is searched.
1206      *
1207      * @return the <code>JDesktopPane</code> this internal frame belongs to,
1208      * or <code>null</code> if none is found
1209      */

1210    public JDesktopPane JavaDoc getDesktopPane() {
1211        Container p;
1212
1213        // Search upward for desktop
1214
p = getParent();
1215        while(p != null && !(p instanceof JDesktopPane JavaDoc))
1216            p = p.getParent();
1217        
1218        if(p == null) {
1219           // search its icon parent for desktop
1220
p = getDesktopIcon().getParent();
1221           while(p != null && !(p instanceof JDesktopPane JavaDoc))
1222                p = p.getParent();
1223        }
1224
1225        return (JDesktopPane JavaDoc)p;
1226    }
1227
1228    /**
1229     * Sets the <code>JDesktopIcon</code> associated with this
1230     * <code>JInternalFrame</code>.
1231     *
1232     * @param d the <code>JDesktopIcon</code> to display on the desktop
1233     * @see #getDesktopIcon
1234     * @beaninfo
1235     * bound: true
1236     * description: The icon shown when this internal frame is minimized.
1237     */

1238    public void setDesktopIcon(JDesktopIcon d) {
1239    JDesktopIcon oldValue = getDesktopIcon();
1240    desktopIcon = d;
1241    firePropertyChange("desktopIcon", oldValue, d);
1242    }
1243
1244    /**
1245     * Returns the <code>JDesktopIcon</code> used when this
1246     * <code>JInternalFrame</code> is iconified.
1247     *
1248     * @return the <code>JDesktopIcon</code> displayed on the desktop
1249     * @see #setDesktopIcon
1250     */

1251    public JDesktopIcon getDesktopIcon() {
1252        return desktopIcon;
1253    }
1254
1255    /**
1256     * If the <code>JInternalFrame</code> is not in maximized state, returns
1257     * <code>getBounds()</code>; otherwise, returns the bounds that the
1258     * <code>JInternalFrame</code> would be restored to.
1259     *
1260     * @return a <code>Rectangle</code> containing the bounds of this
1261     * frame when in the normal state
1262     * @since 1.3
1263     */

1264    public Rectangle getNormalBounds() {
1265
1266      /* we used to test (!isMaximum) here, but since this
1267     method is used by the property listener for the
1268     IS_MAXIMUM_PROPERTY, it ended up getting the wrong
1269     answer... Since normalBounds get set to null when the
1270     frame is restored, this should work better */

1271
1272      if (normalBounds != null) {
1273    return normalBounds;
1274      } else {
1275    return getBounds();
1276      }
1277    }
1278
1279    /**
1280     * Sets the normal bounds for this internal frame, the bounds that
1281     * this internal frame would be restored to from its maximized state.
1282     * This method is intended for use only by desktop managers.
1283     *
1284     * @param r the bounds that this internal frame should be restored to
1285     * @since 1.3
1286     */

1287    public void setNormalBounds(Rectangle r) {
1288    normalBounds = r;
1289    }
1290
1291    /**
1292     * If this <code>JInternalFrame</code> is active,
1293     * returns the child that has focus.
1294     * Otherwise, returns <code>null</code>.
1295     *
1296     * @return the component with focus, or <code>null</code> if no children have focus
1297     * @since 1.3
1298     */

1299    public Component getFocusOwner() {
1300        if (isSelected()) {
1301            Component focusOwner = KeyboardFocusManager.
1302                           getCurrentKeyboardFocusManager().getFocusOwner();
1303
1304            if (focusOwner != null && !SwingUtilities.
1305                                        isDescendingFrom(focusOwner, this)) {
1306                // Sanity check, may sure we don't return a bogus value here.
1307
focusOwner = null;
1308            }
1309            return focusOwner;
1310        }
1311        return null;
1312    }
1313  
1314    /**
1315     * Returns the child component of this <code>JInternalFrame</code>
1316     * that will receive the
1317     * focus when this <code>JInternalFrame</code> is selected.
1318     * If this <code>JInternalFrame</code> is
1319     * currently selected, this method returns the same component as
1320     * the <code>getFocusOwner</code> method.
1321     * If this <code>JInternalFrame</code> is not selected,
1322     * then the child component that most recently requested focus will be
1323     * returned. If no child component has ever requested focus, then this
1324     * <code>JInternalFrame</code>'s initial focusable component is returned.
1325     * If no such
1326     * child exists, then this <code>JInternalFrame</code>'s default component
1327     * to focus is returned.
1328     *
1329     * @return the child component that will receive focus when this
1330     * <code>JInternalFrame</code> is selected
1331     * @see #getFocusOwner
1332     * @see #isSelected
1333     * @since 1.4
1334     */

1335    public Component getMostRecentFocusOwner() {
1336    if (isSelected()) {
1337        return getFocusOwner();
1338    }
1339 
1340    Component mostRecentFocusOwner =
1341        getRootPane().getMostRecentFocusOwner();
1342    if (mostRecentFocusOwner != null) {
1343        return mostRecentFocusOwner;
1344    }
1345 
1346    FocusTraversalPolicy policy = getFocusTraversalPolicy();
1347    if (policy instanceof InternalFrameFocusTraversalPolicy JavaDoc) {
1348        return ((InternalFrameFocusTraversalPolicy JavaDoc)policy).
1349        getInitialComponent(this);
1350    }
1351    
1352    return policy.getDefaultComponent(this);
1353    }
1354 
1355    /**
1356     * Requests the internal frame to restore focus to the
1357     * last subcomponent that had focus. This is used by the UI when
1358     * the user selected this internal frame --
1359     * for example, by clicking on the title bar.
1360     *
1361     * @since 1.3
1362     */

1363    public void restoreSubcomponentFocus() {
1364        lastFocusOwner = getMostRecentFocusOwner();
1365        if (lastFocusOwner == null) {
1366            // Make sure focus is restored somewhere, so that
1367
// we don't leave a focused component in another frame while
1368
// this frame is selected.
1369
lastFocusOwner = getContentPane();
1370        }
1371        lastFocusOwner.requestFocus();
1372    }
1373
1374    /**
1375     * Moves and resizes this component. Unlike other components,
1376     * this implementation also forces re-layout, so that frame
1377     * decorations such as the title bar are always redisplayed.
1378     *
1379     * @param x an integer giving the component's new horizontal position
1380     * measured in pixels from the left of its container
1381     * @param y an integer giving the component's new vertical position,
1382     * measured in pixels from the bottom of its container
1383     * @param width an integer giving the component's new width in pixels
1384     * @param height an integer giving the component's new height in pixels
1385     */

1386    public void reshape(int x, int y, int width, int height) {
1387        super.reshape(x, y, width, height);
1388        validate();
1389        repaint();
1390    }
1391
1392///////////////////////////
1393
// Frame/Window equivalents
1394
///////////////////////////
1395

1396    /**
1397     * Adds the specified listener to receive internal
1398     * frame events from this internal frame.
1399     *
1400     * @param l the internal frame listener
1401     */

1402    public void addInternalFrameListener(InternalFrameListener JavaDoc l) { // remind: sync ??
1403
listenerList.add(InternalFrameListener JavaDoc.class, l);
1404      // remind: needed?
1405
enableEvents(0); // turn on the newEventsOnly flag in Component.
1406
}
1407
1408    /**
1409     * Removes the specified internal frame listener so that it no longer
1410     * receives internal frame events from this internal frame.
1411     *
1412     * @param l the internal frame listener
1413     */

1414    public void removeInternalFrameListener(InternalFrameListener JavaDoc l) { // remind: sync??
1415
listenerList.remove(InternalFrameListener JavaDoc.class, l);
1416    }
1417
1418    /**
1419     * Returns an array of all the <code>InternalFrameListener</code>s added
1420     * to this <code>JInternalFrame</code> with
1421     * <code>addInternalFrameListener</code>.
1422     *
1423     * @return all of the <code>InternalFrameListener</code>s added or an empty
1424     * array if no listeners have been added
1425     * @since 1.4
1426     *
1427     * @see #addInternalFrameListener
1428     */

1429    public InternalFrameListener JavaDoc[] getInternalFrameListeners() {
1430        return (InternalFrameListener JavaDoc[])listenerList.getListeners(
1431                InternalFrameListener JavaDoc.class);
1432    }
1433
1434    // remind: name ok? all one method ok? need to be synchronized?
1435
/**
1436     * Fires an internal frame event.
1437     *
1438     * @param id the type of the event being fired; one of the following:
1439     * <ul>
1440     * <li><code>InternalFrameEvent.INTERNAL_FRAME_OPENED</code>
1441     * <li><code>InternalFrameEvent.INTERNAL_FRAME_CLOSING</code>
1442     * <li><code>InternalFrameEvent.INTERNAL_FRAME_CLOSED</code>
1443     * <li><code>InternalFrameEvent.INTERNAL_FRAME_ICONIFIED</code>
1444     * <li><code>InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED</code>
1445     * <li><code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code>
1446     * <li><code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code>
1447     * </ul>
1448     * If the event type is not one of the above, nothing happens.
1449     */

1450    protected void fireInternalFrameEvent(int id){
1451      Object JavaDoc[] listeners = listenerList.getListenerList();
1452      InternalFrameEvent JavaDoc e = null;
1453      for (int i = listeners.length -2; i >=0; i -= 2){
1454    if (listeners[i] == InternalFrameListener JavaDoc.class){
1455      if (e == null){
1456        e = new InternalFrameEvent JavaDoc(this, id);
1457        // System.out.println("InternalFrameEvent: " + e.paramString());
1458
}
1459      switch(e.getID()) {
1460      case InternalFrameEvent.INTERNAL_FRAME_OPENED:
1461        ((InternalFrameListener JavaDoc)listeners[i+1]).internalFrameOpened(e);
1462        break;
1463      case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
1464        ((InternalFrameListener JavaDoc)listeners[i+1]).internalFrameClosing(e);
1465        break;
1466      case InternalFrameEvent.INTERNAL_FRAME_CLOSED:
1467        ((InternalFrameListener JavaDoc)listeners[i+1]).internalFrameClosed(e);
1468        break;
1469      case InternalFrameEvent.INTERNAL_FRAME_ICONIFIED:
1470        ((InternalFrameListener JavaDoc)listeners[i+1]).internalFrameIconified(e);
1471        break;
1472      case InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED:
1473        ((InternalFrameListener JavaDoc)listeners[i+1]).internalFrameDeiconified(e);
1474        break;
1475      case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
1476        ((InternalFrameListener JavaDoc)listeners[i+1]).internalFrameActivated(e);
1477        break;
1478      case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
1479        ((InternalFrameListener JavaDoc)listeners[i+1]).internalFrameDeactivated(e);
1480        break;
1481      default:
1482        break;
1483      }
1484    }
1485      }
1486      /* we could do it off the event, but at the moment, that's not how
1487     I'm implementing it */

1488      // if (id == InternalFrameEvent.INTERNAL_FRAME_CLOSING) {
1489
// doDefaultCloseAction();
1490
// }
1491
}
1492
1493    /**
1494     * Fires an
1495     * <code>INTERNAL_FRAME_CLOSING</code> event
1496     * and then performs the action specified by
1497     * the internal frame's default close operation.
1498     * This method is typically invoked by the
1499     * look-and-feel-implemented action handler
1500     * for the internal frame's close button.
1501     *
1502     * @since 1.3
1503     * @see #setDefaultCloseOperation
1504     * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSING
1505     */

1506    public void doDefaultCloseAction() {
1507        fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
1508        switch(defaultCloseOperation) {
1509          case DO_NOTHING_ON_CLOSE:
1510        break;
1511          case HIDE_ON_CLOSE:
1512            setVisible(false);
1513        if (isSelected())
1514                try {
1515                    setSelected(false);
1516                } catch (PropertyVetoException JavaDoc pve) {}
1517          
1518        /* should this activate the next frame? that's really
1519           desktopmanager's policy... */

1520            break;
1521          case DISPOSE_ON_CLOSE:
1522              try {
1523        fireVetoableChange(IS_CLOSED_PROPERTY, Boolean.FALSE,
1524                   Boolean.TRUE);
1525        isClosed = true;
1526        firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE,
1527                   Boolean.TRUE);
1528        dispose();
1529          } catch (PropertyVetoException JavaDoc pve) {}
1530              break;
1531          default:
1532              break;
1533        }
1534    }
1535
1536    /**
1537     * Sets the operation that will happen by default when
1538     * the user initiates a "close" on this internal frame.
1539     * The possible choices are:
1540     * <p>
1541     * <dl>
1542     * <dt><code>DO_NOTHING_ON_CLOSE</code>
1543     * <dd> Do nothing.
1544     * This requires the program to handle the operation
1545     * in the <code>windowClosing</code> method
1546     * of a registered <code>InternalFrameListener</code> object.
1547     * <dt><code>HIDE_ON_CLOSE</code>
1548     * <dd> Automatically make the internal frame invisible.
1549     * <dt><code>DISPOSE_ON_CLOSE</code>
1550     * <dd> Automatically dispose of the internal frame.
1551     * </dl>
1552     * <p>
1553     * The default value is <code>DISPOSE_ON_CLOSE</code>.
1554     * Before performing the specified close operation,
1555     * the internal frame fires
1556     * an <code>INTERNAL_FRAME_CLOSING</code> event.
1557     *
1558     * @param operation one of the following constants defined in
1559     * <code>javax.swing.WindowConstants</code>
1560     * (an interface implemented by
1561     * <code>JInternalFrame</code>):
1562     * <code>DO_NOTHING_ON_CLOSE</code>,
1563     * <code>HIDE_ON_CLOSE</code>, or
1564     * <code>DISPOSE_ON_CLOSE</code>
1565     *
1566     * @see #addInternalFrameListener
1567     * @see #getDefaultCloseOperation
1568     * @see #setVisible
1569     * @see #dispose
1570     * @see InternalFrameEvent#INTERNAL_FRAME_CLOSING
1571     */

1572    public void setDefaultCloseOperation(int operation) {
1573        this.defaultCloseOperation = operation;
1574    }
1575
1576   /**
1577    * Returns the default operation that occurs when the user
1578    * initiates a "close" on this internal frame.
1579    * @return the operation that will occur when the user closes the internal
1580    * frame
1581    * @see #setDefaultCloseOperation
1582    */

1583    public int getDefaultCloseOperation() {
1584        return defaultCloseOperation;
1585    }
1586
1587    /**
1588     * Causes subcomponents of this <code>JInternalFrame</code>
1589     * to be laid out at their preferred size. Internal frames that are
1590     * iconized or maximized are first restored and then packed. If the
1591     * internal frame is unable to be restored its state is not changed
1592     * and will not be packed.
1593     *
1594     * @see java.awt.Window#pack
1595     */

1596    public void pack() {
1597        try {
1598            if (isIcon()) {
1599                setIcon(false);
1600            } else if (isMaximum()) {
1601                setMaximum(false);
1602            }
1603        } catch(PropertyVetoException JavaDoc e) {
1604            return;
1605        }
1606        setSize(getPreferredSize());
1607        validate();
1608    }
1609
1610    /**
1611     * If the internal frame is not visible,
1612     * brings the internal frame to the front,
1613     * makes it visible,
1614     * and attempts to select it.
1615     * The first time the internal frame is made visible,
1616     * this method also fires an <code>INTERNAL_FRAME_OPENED</code> event.
1617     * This method does nothing if the internal frame is already visible.
1618     * Invoking this method
1619     * has the same result as invoking
1620     * <code>setVisible(true)</code>.
1621     *
1622     * @see #moveToFront
1623     * @see #setSelected
1624     * @see InternalFrameEvent#INTERNAL_FRAME_OPENED
1625     * @see #setVisible
1626     */

1627    public void show() {
1628    // bug 4312922
1629
if (isVisible()) {
1630        //match the behavior of setVisible(true): do nothing
1631
return;
1632    }
1633
1634    // bug 4149505
1635
if (!opened) {
1636      fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
1637      opened = true;
1638    }
1639    
1640        /* icon default visibility is false; set it to true so that it shows
1641           up when user iconifies frame */

1642        getDesktopIcon().setVisible(true);
1643
1644    toFront();
1645    super.show();
1646
1647    if (isIcon) {
1648        return;
1649    }
1650
1651        if (!isSelected()) {
1652            try {
1653                setSelected(true);
1654            } catch (PropertyVetoException JavaDoc pve) {}
1655        }
1656    }
1657
1658    public void hide() {
1659        if (isIcon()) {
1660            getDesktopIcon().setVisible(false);
1661        }
1662        super.hide();
1663    }
1664
1665    /**
1666     * Makes this internal frame
1667     * invisible, unselected, and closed.
1668     * If the frame is not already closed,
1669     * this method fires an
1670     * <code>INTERNAL_FRAME_CLOSED</code> event.
1671     * The results of invoking this method are similar to
1672     * <code>setClosed(true)</code>,
1673     * but <code>dispose</code> always succeeds in closing
1674     * the internal frame and does not fire
1675     * an <code>INTERNAL_FRAME_CLOSING</code> event.
1676     *
1677     * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSED
1678     * @see #setVisible
1679     * @see #setSelected
1680     * @see #setClosed
1681     */

1682    public void dispose() {
1683        if (isVisible()) {
1684            setVisible(false);
1685        }
1686        if (isSelected()) {
1687            try {
1688                setSelected(false);
1689            } catch (PropertyVetoException JavaDoc pve) {}
1690        }
1691        if (!isClosed) {
1692      firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE, Boolean.TRUE);
1693      isClosed = true;
1694    }
1695    fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
1696    }
1697
1698    /**
1699     * Brings this internal frame to the front.
1700     * Places this internal frame at the top of the stacking order
1701     * and makes the corresponding adjustment to other visible internal
1702     * frames.
1703     *
1704     * @see java.awt.Window#toFront
1705     * @see #moveToFront
1706     */

1707    public void toFront() {
1708        moveToFront();
1709    }
1710
1711    /**
1712     * Sends this internal frame to the back.
1713     * Places this internal frame at the bottom of the stacking order
1714     * and makes the corresponding adjustment to other visible
1715     * internal frames.
1716     *
1717     * @see java.awt.Window#toBack
1718     * @see #moveToBack
1719     */

1720    public void toBack() {
1721        moveToBack();
1722    }
1723
1724    /**
1725     * Does nothing because <code>JInternalFrame</code>s must always be roots of a focus
1726     * traversal cycle.
1727     *
1728     * @param focusCycleRoot this value is ignored
1729     * @see #isFocusCycleRoot
1730     * @see java.awt.Container#setFocusTraversalPolicy
1731     * @see java.awt.Container#getFocusTraversalPolicy
1732     * @since 1.4
1733     */

1734    public final void setFocusCycleRoot(boolean focusCycleRoot) {
1735    }
1736
1737    /**
1738     * Always returns <code>true</code> because all <code>JInternalFrame</code>s must be
1739     * roots of a focus traversal cycle.
1740     *
1741     * @return <code>true</code>
1742     * @see #setFocusCycleRoot
1743     * @see java.awt.Container#setFocusTraversalPolicy
1744     * @see java.awt.Container#getFocusTraversalPolicy
1745     * @since 1.4
1746     */

1747    public final boolean isFocusCycleRoot() {
1748        return true;
1749    }
1750
1751    /**
1752     * Always returns <code>null</code> because <code>JInternalFrame</code>s
1753     * must always be roots of a focus
1754     * traversal cycle.
1755     *
1756     * @return <code>null</code>
1757     * @see java.awt.Container#isFocusCycleRoot()
1758     * @since 1.4
1759     */

1760    public final Container getFocusCycleRootAncestor() {
1761        return null;
1762    }
1763
1764    /**
1765     * Gets the warning string that is displayed with this internal frame.
1766     * Since an internal frame is always secure (since it's fully
1767     * contained within a window that might need a warning string)
1768     * this method always returns <code>null</code>.
1769     * @return <code>null</code>
1770     * @see java.awt.Window#getWarningString
1771     */

1772    public final String JavaDoc getWarningString() {
1773        return null;
1774    }
1775
1776    /**
1777     * See <code>readObject</code> and <code>writeObject</code>
1778     * in <code>JComponent</code> for more
1779     * information about serialization in Swing.
1780     */

1781    private void writeObject(ObjectOutputStream JavaDoc s) throws IOException JavaDoc {
1782        s.defaultWriteObject();
1783        if (getUIClassID().equals(uiClassID)) {
1784            byte count = JComponent.getWriteObjCounter(this);
1785            JComponent.setWriteObjCounter(this, --count);
1786            if (count == 0 && ui != null) {
1787                boolean old = isRootPaneCheckingEnabled();
1788                try {
1789                    setRootPaneCheckingEnabled(false);
1790                    ui.installUI(this);
1791                } finally {
1792                    setRootPaneCheckingEnabled(old);
1793                }
1794            }
1795        }
1796    }
1797
1798    /* Called from the JComponent's EnableSerializationFocusListener to
1799     * do any Swing-specific pre-serialization configuration.
1800     */

1801    void compWriteObjectNotify() {
1802      // need to disable rootpane checking for InternalFrame: 4172083
1803
boolean old = isRootPaneCheckingEnabled();
1804      try {
1805    setRootPaneCheckingEnabled(false);
1806        super.compWriteObjectNotify();
1807      }
1808      finally {
1809    setRootPaneCheckingEnabled(old);
1810      }
1811    }
1812
1813    /**
1814     * Returns a string representation of this <code>JInternalFrame</code>.
1815     * This method
1816     * is intended to be used only for debugging purposes, and the
1817     * content and format of the returned string may vary between
1818     * implementations. The returned string may be empty but may not
1819     * be <code>null</code>.
1820     *
1821     * @return a string representation of this <code>JInternalFrame</code>
1822     */

1823    protected String JavaDoc paramString() {
1824    String JavaDoc rootPaneString = (rootPane != null ?
1825                 rootPane.toString() : "");
1826    String JavaDoc rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
1827                        "true" : "false");
1828    String JavaDoc closableString = (closable ? "true" : "false");
1829    String JavaDoc isClosedString = (isClosed ? "true" : "false");
1830    String JavaDoc maximizableString = (maximizable ? "true" : "false");
1831    String JavaDoc isMaximumString = (isMaximum ? "true" : "false");
1832    String JavaDoc iconableString = (iconable ? "true" : "false");
1833    String JavaDoc isIconString = (isIcon ? "true" : "false");
1834    String JavaDoc resizableString = (resizable ? "true" : "false");
1835    String JavaDoc isSelectedString = (isSelected ? "true" : "false");
1836    String JavaDoc frameIconString = (frameIcon != null ?
1837                  frameIcon.toString() : "");
1838    String JavaDoc titleString = (title != null ?
1839                  title : "");
1840    String JavaDoc desktopIconString = (desktopIcon != null ?
1841                    desktopIcon.toString() : "");
1842    String JavaDoc openedString = (opened ? "true" : "false");
1843        String JavaDoc defaultCloseOperationString;
1844        if (defaultCloseOperation == HIDE_ON_CLOSE) {
1845            defaultCloseOperationString = "HIDE_ON_CLOSE";
1846        } else if (defaultCloseOperation == DISPOSE_ON_CLOSE) {
1847            defaultCloseOperationString = "DISPOSE_ON_CLOSE";
1848        } else if (defaultCloseOperation == DO_NOTHING_ON_CLOSE) {
1849            defaultCloseOperationString = "DO_NOTHING_ON_CLOSE";
1850        } else defaultCloseOperationString = "";
1851
1852    return super.paramString() +
1853    ",closable=" + closableString +
1854    ",defaultCloseOperation=" + defaultCloseOperationString +
1855    ",desktopIcon=" + desktopIconString +
1856    ",frameIcon=" + frameIconString +
1857    ",iconable=" + iconableString +
1858    ",isClosed=" + isClosedString +
1859    ",isIcon=" + isIconString +
1860    ",isMaximum=" + isMaximumString +
1861    ",isSelected=" + isSelectedString +
1862    ",maximizable=" + maximizableString +
1863    ",opened=" + openedString +
1864    ",resizable=" + resizableString +
1865    ",rootPane=" + rootPaneString +
1866    ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString +
1867    ",title=" + titleString;
1868    }
1869
1870    // ======= begin optimized frame dragging defence code ==============
1871

1872    boolean isDragging = false;
1873    boolean danger = false;
1874
1875    /**
1876     * Overridden to allow optimized painting when the
1877     * internal frame is being dragged.
1878     */

1879    protected void paintComponent(Graphics g) {
1880      if (isDragging) {
1881    // System.out.println("ouch");
1882
danger = true;
1883      }
1884
1885      super.paintComponent(g);
1886   }
1887
1888    // ======= end optimized frame dragging defence code ==============
1889

1890/////////////////
1891
// Accessibility support
1892
////////////////
1893

1894    /**
1895     * Gets the <code>AccessibleContext</code> associated with this
1896     * <code>JInternalFrame</code>.
1897     * For internal frames, the <code>AccessibleContext</code>
1898     * takes the form of an
1899     * <code>AccessibleJInternalFrame</code> object.
1900     * A new <code>AccessibleJInternalFrame</code> instance is created if necessary.
1901     *
1902     * @return an <code>AccessibleJInternalFrame</code> that serves as the
1903     * <code>AccessibleContext</code> of this
1904     * <code>JInternalFrame</code>
1905     * @see AccessibleJInternalFrame
1906     */

1907    public AccessibleContext getAccessibleContext() {
1908        if (accessibleContext == null) {
1909            accessibleContext = new AccessibleJInternalFrame();
1910        }
1911        return accessibleContext;
1912    }
1913
1914    /**
1915     * This class implements accessibility support for the
1916     * <code>JInternalFrame</code> class. It provides an implementation of the
1917     * Java Accessibility API appropriate to internal frame user-interface
1918     * elements.
1919     * <p>
1920     * <strong>Warning:</strong>
1921     * Serialized objects of this class will not be compatible with
1922     * future Swing releases. The current serialization support is
1923     * appropriate for short term storage or RMI between applications running
1924     * the same version of Swing. As of 1.4, support for long term storage
1925     * of all JavaBeans<sup><font size="-2">TM</font></sup>
1926     * has been added to the <code>java.beans</code> package.
1927     * Please see {@link java.beans.XMLEncoder}.
1928     */

1929    protected class AccessibleJInternalFrame extends AccessibleJComponent
1930        implements AccessibleValue {
1931
1932        /**
1933         * Get the accessible name of this object.
1934         *
1935         * @return the localized name of the object -- can be <code>null</code> if this
1936         * object does not have a name
1937         * @see #setAccessibleName
1938         */

1939        public String JavaDoc getAccessibleName() {
1940            if (accessibleName != null) {
1941                return accessibleName;
1942            } else {
1943                return getTitle();
1944            }
1945        }
1946
1947        /**
1948         * Get the role of this object.
1949         *
1950         * @return an instance of AccessibleRole describing the role of the
1951         * object
1952         * @see AccessibleRole
1953         */

1954        public AccessibleRole getAccessibleRole() {
1955            return AccessibleRole.INTERNAL_FRAME;
1956        }
1957
1958        /**
1959         * Gets the AccessibleValue associated with this object. In the
1960         * implementation of the Java Accessibility API for this class,
1961     * returns this object, which is responsible for implementing the
1962         * <code>AccessibleValue</code> interface on behalf of itself.
1963     *
1964     * @return this object
1965         */

1966        public AccessibleValue getAccessibleValue() {
1967            return this;
1968        }
1969
1970
1971        //
1972
// AccessibleValue methods
1973
//
1974

1975        /**
1976         * Get the value of this object as a Number.
1977         *
1978         * @return value of the object -- can be <code>null</code> if this object does not
1979         * have a value
1980         */

1981        public Number JavaDoc getCurrentAccessibleValue() {
1982            return new Integer JavaDoc(getLayer());
1983        }
1984
1985        /**
1986         * Set the value of this object as a Number.
1987         *
1988         * @return <code>true</code> if the value was set
1989         */

1990        public boolean setCurrentAccessibleValue(Number JavaDoc n) {
1991        // TIGER - 4422535
1992
if (n == null) {
1993        return false;
1994        }
1995        setLayer(new Integer JavaDoc(n.intValue()));
1996        return true;
1997        }
1998
1999        /**
2000         * Get the minimum value of this object as a Number.
2001         *
2002         * @return Minimum value of the object; <code>null</code> if this object does not
2003         * have a minimum value
2004         */

2005        public Number JavaDoc getMinimumAccessibleValue() {
2006            return new Integer JavaDoc(Integer.MIN_VALUE);
2007        }
2008
2009        /**
2010         * Get the maximum value of this object as a Number.
2011         *
2012         * @return Maximum value of the object; <code>null</code> if this object does not
2013         * have a maximum value
2014         */

2015        public Number JavaDoc getMaximumAccessibleValue() {
2016            return new Integer JavaDoc(Integer.MAX_VALUE);
2017        }
2018
2019    } // AccessibleJInternalFrame
2020

2021    /**
2022     * This component represents an iconified version of a
2023     * <code>JInternalFrame</code>.
2024     * This API should NOT BE USED by Swing applications, as it will go
2025     * away in future versions of Swing as its functionality is moved into
2026     * <code>JInternalFrame</code>. This class is public only so that
2027     * UI objects can display a desktop icon. If an application
2028     * wants to display a desktop icon, it should create a
2029     * <code>JInternalFrame</code> instance and iconify it.
2030     * <p>
2031     * <strong>Warning:</strong>
2032     * Serialized objects of this class will not be compatible with
2033     * future Swing releases. The current serialization support is
2034     * appropriate for short term storage or RMI between applications running
2035     * the same version of Swing. As of 1.4, support for long term storage
2036     * of all JavaBeans<sup><font size="-2">TM</font></sup>
2037     * has been added to the <code>java.beans</code> package.
2038     * Please see {@link java.beans.XMLEncoder}.
2039     *
2040     * @author David Kloba
2041     */

2042    static public class JDesktopIcon extends JComponent JavaDoc implements Accessible
2043    {
2044        JInternalFrame JavaDoc internalFrame;
2045
2046        /**
2047         * Creates an icon for an internal frame.
2048         *
2049         * @param f the <code>JInternalFrame</code>
2050         * for which the icon is created
2051         */

2052        public JDesktopIcon(JInternalFrame JavaDoc f) {
2053        setVisible(false);
2054            setInternalFrame(f);
2055            updateUI();
2056        }
2057
2058        /**
2059         * Returns the look-and-feel object that renders this component.
2060         *
2061         * @return the <code>DesktopIconUI</code> object that renders
2062         * this component
2063         */

2064        public DesktopIconUI getUI() {
2065            return (DesktopIconUI)ui;
2066        }
2067
2068        /**
2069         * Sets the look-and-feel object that renders this component.
2070         *
2071         * @param ui the <code>DesktopIconUI</code> look-and-feel object
2072         * @see UIDefaults#getUI
2073         */

2074        public void setUI(DesktopIconUI ui) {
2075            super.setUI(ui);
2076        }
2077
2078        /**
2079         * Returns the <code>JInternalFrame</code> that this
2080         * <code>DesktopIcon</code> is associated with.
2081         *
2082         * @return the <code>JInternalFrame</code> with which this icon
2083         * is associated
2084         */

2085        public JInternalFrame JavaDoc getInternalFrame() {
2086            return internalFrame;
2087        }
2088
2089        /**
2090         * Sets the <code>JInternalFrame</code> with which this
2091         * <code>DesktopIcon</code> is associated.
2092         *
2093         * @param f the <code>JInternalFrame</code> with which this icon
2094         * is associated
2095         */

2096        public void setInternalFrame(JInternalFrame JavaDoc f) {
2097            internalFrame = f;
2098        }
2099
2100        /**
2101         * Convenience method to ask the icon for the <code>Desktop</code>
2102     * object it belongs to.
2103         *
2104         * @return the <code>JDesktopPane</code> that contains this
2105         * icon's internal frame, or <code>null</code> if none found
2106         */

2107        public JDesktopPane JavaDoc getDesktopPane() {
2108            if(getInternalFrame() != null)
2109                return getInternalFrame().getDesktopPane();
2110            return null;
2111        }
2112
2113        /**
2114         * Notification from the <code>UIManager</code> that the look and feel
2115         * has changed.
2116         * Replaces the current UI object with the latest version from the
2117         * <code>UIManager</code>.
2118         *
2119         * @see JComponent#updateUI
2120         */

2121        public void updateUI() {
2122            boolean hadUI = (ui != null);
2123            setUI((DesktopIconUI)UIManager.getUI(this));
2124            invalidate();
2125
2126            Dimension r = getPreferredSize();
2127            setSize(r.width, r.height);
2128            
2129
2130            if (internalFrame != null && internalFrame.getUI() != null) { // don't do this if UI not created yet
2131
SwingUtilities.updateComponentTreeUI(internalFrame);
2132            }
2133        }
2134
2135        /* This method is called if updateUI was called on the associated
2136         * JInternalFrame. It's necessary to avoid infinite recursion.
2137         */

2138        void updateUIWhenHidden() {
2139            /* Update this UI and any associated internal frame */
2140            setUI((DesktopIconUI)UIManager.getUI(this));
2141
2142            Dimension r = getPreferredSize();
2143            setSize(r.width, r.height);
2144            
2145            invalidate();
2146            Component[] children = getComponents();
2147            if (children != null) {
2148                for(int i = 0; i < children.length; i++) {
2149                    SwingUtilities.updateComponentTreeUI(children[i]);
2150                }
2151            }
2152        }
2153
2154        /**
2155         * Returns the name of the look-and-feel
2156     * class that renders this component.
2157         *
2158         * @return the string "DesktopIconUI"
2159         * @see JComponent#getUIClassID
2160         * @see UIDefaults#getUI
2161         */

2162        public String JavaDoc getUIClassID() {
2163            return "DesktopIconUI";
2164        }
2165    ////////////////
2166
// Serialization support
2167
////////////////
2168
private void writeObject(ObjectOutputStream JavaDoc s) throws IOException JavaDoc {
2169            s.defaultWriteObject();
2170            if (getUIClassID().equals("DesktopIconUI")) {
2171                byte count = JComponent.getWriteObjCounter(this);
2172                JComponent.setWriteObjCounter(this, --count);
2173                if (count == 0 && ui != null) {
2174                    ui.installUI(this);
2175                }
2176            }
2177    }
2178
2179       /////////////////
2180
// Accessibility support
2181
////////////////
2182

2183        /**
2184         * Gets the AccessibleContext associated with this JDesktopIcon.
2185         * For desktop icons, the AccessibleContext takes the form of an
2186         * AccessibleJDesktopIcon.
2187         * A new AccessibleJDesktopIcon instance is created if necessary.
2188         *
2189         * @return an AccessibleJDesktopIcon that serves as the
2190         * AccessibleContext of this JDesktopIcon
2191         */

2192        public AccessibleContext getAccessibleContext() {
2193            if (accessibleContext == null) {
2194                accessibleContext = new AccessibleJDesktopIcon();
2195            }
2196            return accessibleContext;
2197        }
2198
2199        /**
2200         * This class implements accessibility support for the
2201         * <code>JInternalFrame.JDesktopIcon</code> class. It provides an
2202     * implementation of the Java Accessibility API appropriate to
2203     * desktop icon user-interface elements.
2204         * <p>
2205         * <strong>Warning:</strong>
2206         * Serialized objects of this class will not be compatible with
2207         * future Swing releases. The current serialization support is
2208         * appropriate for short term storage or RMI between applications running
2209         * the same version of Swing. As of 1.4, support for long term storage
2210         * of all JavaBeans<sup><font size="-2">TM</font></sup>
2211         * has been added to the <code>java.beans</code> package.
2212         * Please see {@link java.beans.XMLEncoder}.
2213         */

2214        protected class AccessibleJDesktopIcon extends AccessibleJComponent
2215            implements AccessibleValue {
2216
2217            /**
2218             * Gets the role of this object.
2219             *
2220             * @return an instance of AccessibleRole describing the role of the
2221             * object
2222             * @see AccessibleRole
2223             */

2224            public AccessibleRole getAccessibleRole() {
2225                return AccessibleRole.DESKTOP_ICON;
2226            }
2227
2228            /**
2229             * Gets the AccessibleValue associated with this object. In the
2230             * implementation of the Java Accessibility API for this class,
2231         * returns this object, which is responsible for implementing the
2232             * <code>AccessibleValue</code> interface on behalf of itself.
2233         *
2234         * @return this object
2235             */

2236            public AccessibleValue getAccessibleValue() {
2237                return this;
2238            }
2239
2240            //
2241
// AccessibleValue methods
2242
//
2243

2244            /**
2245             * Gets the value of this object as a <code>Number</code>.
2246             *
2247             * @return value of the object -- can be <code>null</code> if this object does not
2248             * have a value
2249             */

2250            public Number JavaDoc getCurrentAccessibleValue() {
2251                AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
2252                AccessibleValue v = a.getAccessibleValue();
2253                if (v != null) {
2254                    return v.getCurrentAccessibleValue();
2255                } else {
2256                    return null;
2257                }
2258            }
2259
2260            /**
2261             * Sets the value of this object as a <code>Number</code>.
2262             *
2263             * @return <code>true</code> if the value was set
2264             */

2265            public boolean setCurrentAccessibleValue(Number JavaDoc n) {
2266        // TIGER - 4422535
2267
if (n == null) {
2268            return false;
2269        }
2270                AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
2271                AccessibleValue v = a.getAccessibleValue();
2272                if (v != null) {
2273                    return v.setCurrentAccessibleValue(n);
2274                } else {
2275                    return false;
2276                }
2277            }
2278
2279            /**
2280             * Gets the minimum value of this object as a <code>Number</code>.
2281             *
2282             * @return minimum value of the object; <code>null</code> if this object does not
2283             * have a minimum value
2284             */

2285            public Number JavaDoc getMinimumAccessibleValue() {
2286                AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
2287                if (a instanceof AccessibleValue) {
2288                    return ((AccessibleValue)a).getMinimumAccessibleValue();
2289                } else {
2290                    return null;
2291                }
2292            }
2293
2294            /**
2295             * Gets the maximum value of this object as a <code>Number</code>.
2296             *
2297             * @return maximum value of the object; <code>null</code> if this object does not
2298             * have a maximum value
2299             */

2300            public Number JavaDoc getMaximumAccessibleValue() {
2301                AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
2302                if (a instanceof AccessibleValue) {
2303                    return ((AccessibleValue)a).getMaximumAccessibleValue();
2304                } else {
2305                    return null;
2306                }
2307            }
2308
2309        } // AccessibleJDesktopIcon
2310
}
2311}
2312
Popular Tags