jdk/src/share/classes/javax/swing/JInternalFrame.java
changeset 2 90ce3da70b43
child 438 2ae294e4518c
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package javax.swing;
       
    27 
       
    28 import java.awt.*;
       
    29 import java.awt.event.*;
       
    30 
       
    31 import java.beans.PropertyVetoException;
       
    32 import java.beans.PropertyChangeEvent;
       
    33 import java.util.EventListener;
       
    34 
       
    35 import javax.swing.border.Border;
       
    36 import javax.swing.event.InternalFrameEvent;
       
    37 import javax.swing.event.InternalFrameListener;
       
    38 import javax.swing.plaf.*;
       
    39 
       
    40 import javax.accessibility.*;
       
    41 
       
    42 import java.io.ObjectOutputStream;
       
    43 import java.io.ObjectInputStream;
       
    44 import java.io.IOException;
       
    45 import java.lang.StringBuilder;
       
    46 import java.beans.PropertyChangeListener;
       
    47 import sun.awt.AppContext;
       
    48 import sun.swing.SwingUtilities2;
       
    49 
       
    50 
       
    51 /**
       
    52  * A lightweight object that provides many of the features of
       
    53  * a native frame, including dragging, closing, becoming an icon,
       
    54  * resizing, title display, and support for a menu bar.
       
    55  * For task-oriented documentation and examples of using internal frames,
       
    56  * see <a
       
    57  href="http://java.sun.com/docs/books/tutorial/uiswing/components/internalframe.html" target="_top">How to Use Internal Frames</a>,
       
    58  * a section in <em>The Java Tutorial</em>.
       
    59  *
       
    60  * <p>
       
    61  *
       
    62  * Generally,
       
    63  * you add <code>JInternalFrame</code>s to a <code>JDesktopPane</code>. The UI
       
    64  * delegates the look-and-feel-specific actions to the
       
    65  * <code>DesktopManager</code>
       
    66  * object maintained by the <code>JDesktopPane</code>.
       
    67  * <p>
       
    68  * The <code>JInternalFrame</code> content pane
       
    69  * is where you add child components.
       
    70  * As a conveniance <code>add</code> and its variants, <code>remove</code> and
       
    71  * <code>setLayout</code> have been overridden to forward to the
       
    72  * <code>contentPane</code> as necessary. This means you can write:
       
    73  * <pre>
       
    74  *       internalFrame.add(child);
       
    75  * </pre>
       
    76  * And the child will be added to the contentPane.
       
    77  * The content pane is actually managed by an instance of
       
    78  * <code>JRootPane</code>,
       
    79  * which also manages a layout pane, glass pane, and
       
    80  * optional menu bar for the internal frame. Please see the
       
    81  * <code>JRootPane</code>
       
    82  * documentation for a complete description of these components.
       
    83  * Refer to {@link javax.swing.RootPaneContainer}
       
    84  * for details on adding, removing and setting the <code>LayoutManager</code>
       
    85  * of a <code>JInternalFrame</code>.
       
    86  * <p>
       
    87  * <strong>Warning:</strong> Swing is not thread safe. For more
       
    88  * information see <a
       
    89  * href="package-summary.html#threading">Swing's Threading
       
    90  * Policy</a>.
       
    91  * <p>
       
    92  * <strong>Warning:</strong>
       
    93  * Serialized objects of this class will not be compatible with
       
    94  * future Swing releases. The current serialization support is
       
    95  * appropriate for short term storage or RMI between applications running
       
    96  * the same version of Swing.  As of 1.4, support for long term storage
       
    97  * of all JavaBeans<sup><font size="-2">TM</font></sup>
       
    98  * has been added to the <code>java.beans</code> package.
       
    99  * Please see {@link java.beans.XMLEncoder}.
       
   100  *
       
   101  * @see InternalFrameEvent
       
   102  * @see JDesktopPane
       
   103  * @see DesktopManager
       
   104  * @see JInternalFrame.JDesktopIcon
       
   105  * @see JRootPane
       
   106  * @see javax.swing.RootPaneContainer
       
   107  *
       
   108  * @author David Kloba
       
   109  * @author Rich Schiavi
       
   110  * @beaninfo
       
   111  *      attribute: isContainer true
       
   112  *      attribute: containerDelegate getContentPane
       
   113  *      description: A frame container which is contained within
       
   114  *                   another window.
       
   115  */
       
   116 public class JInternalFrame extends JComponent implements
       
   117         Accessible, WindowConstants,
       
   118         RootPaneContainer
       
   119 {
       
   120     /**
       
   121      * @see #getUIClassID
       
   122      * @see #readObject
       
   123      */
       
   124     private static final String uiClassID = "InternalFrameUI";
       
   125 
       
   126     /**
       
   127      * The <code>JRootPane</code> instance that manages the
       
   128      * content pane
       
   129      * and optional menu bar for this internal frame, as well as the
       
   130      * glass pane.
       
   131      *
       
   132      * @see JRootPane
       
   133      * @see RootPaneContainer
       
   134      */
       
   135     protected JRootPane rootPane;
       
   136 
       
   137     /**
       
   138      * If true then calls to <code>add</code> and <code>setLayout</code>
       
   139      * will be forwarded to the <code>contentPane</code>. This is initially
       
   140      * false, but is set to true when the <code>JInternalFrame</code> is
       
   141      * constructed.
       
   142      *
       
   143      * @see #isRootPaneCheckingEnabled
       
   144      * @see #setRootPaneCheckingEnabled
       
   145      * @see javax.swing.RootPaneContainer
       
   146      */
       
   147     protected boolean rootPaneCheckingEnabled = false;
       
   148 
       
   149     /** The frame can be closed. */
       
   150     protected boolean closable;
       
   151     /** The frame has been closed. */
       
   152     protected boolean isClosed;
       
   153     /** The frame can be expanded to the size of the desktop pane. */
       
   154     protected boolean maximizable;
       
   155     /**
       
   156      * The frame has been expanded to its maximum size.
       
   157      * @see #maximizable
       
   158      */
       
   159     protected boolean isMaximum;
       
   160     /**
       
   161      * The frame can "iconified" (shrunk down and displayed as
       
   162      * an icon-image).
       
   163      * @see JInternalFrame.JDesktopIcon
       
   164      * @see #setIconifiable
       
   165      */
       
   166     protected boolean iconable;
       
   167     /**
       
   168      * The frame has been iconified.
       
   169      * @see #isIcon()
       
   170      */
       
   171     protected boolean isIcon;
       
   172     /** The frame's size can be changed. */
       
   173     protected boolean resizable;
       
   174     /** The frame is currently selected. */
       
   175     protected boolean isSelected;
       
   176     /** The icon shown in the top-left corner of this internal frame. */
       
   177     protected Icon frameIcon;
       
   178     /** The title displayed in this internal frame's title bar. */
       
   179     protected String  title;
       
   180     /**
       
   181      * The icon that is displayed when this internal frame is iconified.
       
   182      * @see #iconable
       
   183      */
       
   184     protected JDesktopIcon desktopIcon;
       
   185 
       
   186     private Cursor lastCursor;
       
   187 
       
   188     private boolean opened;
       
   189 
       
   190     private Rectangle normalBounds = null;
       
   191 
       
   192     private int defaultCloseOperation = DISPOSE_ON_CLOSE;
       
   193 
       
   194     /**
       
   195      * Contains the Component that focus is to go when
       
   196      * <code>restoreSubcomponentFocus</code> is invoked, that is,
       
   197      * <code>restoreSubcomponentFocus</code> sets this to the value returned
       
   198      * from <code>getMostRecentFocusOwner</code>.
       
   199      */
       
   200     private Component lastFocusOwner;
       
   201 
       
   202     /** Bound property name. */
       
   203     public final static String CONTENT_PANE_PROPERTY = "contentPane";
       
   204     /** Bound property name. */
       
   205     public final static String MENU_BAR_PROPERTY = "JMenuBar";
       
   206     /** Bound property name. */
       
   207     public final static String TITLE_PROPERTY = "title";
       
   208     /** Bound property name. */
       
   209     public final static String LAYERED_PANE_PROPERTY = "layeredPane";
       
   210     /** Bound property name. */
       
   211     public final static String ROOT_PANE_PROPERTY = "rootPane";
       
   212     /** Bound property name. */
       
   213     public final static String GLASS_PANE_PROPERTY = "glassPane";
       
   214     /** Bound property name. */
       
   215     public final static String FRAME_ICON_PROPERTY = "frameIcon";
       
   216 
       
   217     /**
       
   218      * Constrained property name indicated that this frame has
       
   219      * selected status.
       
   220      */
       
   221     public final static String IS_SELECTED_PROPERTY = "selected";
       
   222     /** Constrained property name indicating that the internal frame is closed. */
       
   223     public final static String IS_CLOSED_PROPERTY = "closed";
       
   224     /** Constrained property name indicating that the internal frame is maximized. */
       
   225     public final static String IS_MAXIMUM_PROPERTY = "maximum";
       
   226     /** Constrained property name indicating that the internal frame is iconified. */
       
   227     public final static String IS_ICON_PROPERTY = "icon";
       
   228 
       
   229     private static final Object PROPERTY_CHANGE_LISTENER_KEY =
       
   230         new StringBuilder("InternalFramePropertyChangeListener");
       
   231 
       
   232     private static void addPropertyChangeListenerIfNecessary() {
       
   233         if (AppContext.getAppContext().get(PROPERTY_CHANGE_LISTENER_KEY) ==
       
   234             null) {
       
   235             PropertyChangeListener focusListener =
       
   236                 new FocusPropertyChangeListener();
       
   237 
       
   238             AppContext.getAppContext().put(PROPERTY_CHANGE_LISTENER_KEY,
       
   239                 focusListener);
       
   240 
       
   241             KeyboardFocusManager.getCurrentKeyboardFocusManager().
       
   242                 addPropertyChangeListener(focusListener);
       
   243         }
       
   244     }
       
   245 
       
   246     private static class FocusPropertyChangeListener implements
       
   247         PropertyChangeListener {
       
   248         public void propertyChange(PropertyChangeEvent e) {
       
   249             if (e.getPropertyName() == "permanentFocusOwner") {
       
   250                 updateLastFocusOwner((Component)e.getNewValue());
       
   251             }
       
   252         }
       
   253     }
       
   254 
       
   255     private static void updateLastFocusOwner(Component component) {
       
   256         if (component != null) {
       
   257             Component parent = component;
       
   258             while (parent != null && !(parent instanceof Window)) {
       
   259                 if (parent instanceof JInternalFrame) {
       
   260                     // Update lastFocusOwner for parent.
       
   261                     ((JInternalFrame)parent).setLastFocusOwner(component);
       
   262                 }
       
   263                 parent = parent.getParent();
       
   264             }
       
   265         }
       
   266     }
       
   267 
       
   268     /**
       
   269      * Creates a non-resizable, non-closable, non-maximizable,
       
   270      * non-iconifiable <code>JInternalFrame</code> with no title.
       
   271      */
       
   272     public JInternalFrame() {
       
   273         this("", false, false, false, false);
       
   274     }
       
   275 
       
   276     /**
       
   277      * Creates a non-resizable, non-closable, non-maximizable,
       
   278      * non-iconifiable <code>JInternalFrame</code> with the specified title.
       
   279      * Note that passing in a <code>null</code> <code>title</code> results in
       
   280      * unspecified behavior and possibly an exception.
       
   281      *
       
   282      * @param title  the non-<code>null</code> <code>String</code>
       
   283      *     to display in the title bar
       
   284      */
       
   285     public JInternalFrame(String title) {
       
   286         this(title, false, false, false, false);
       
   287     }
       
   288 
       
   289     /**
       
   290      * Creates a non-closable, non-maximizable, non-iconifiable
       
   291      * <code>JInternalFrame</code> with the specified title
       
   292      * and resizability.
       
   293      *
       
   294      * @param title      the <code>String</code> to display in the title bar
       
   295      * @param resizable  if <code>true</code>, the internal frame can be resized
       
   296      */
       
   297     public JInternalFrame(String title, boolean resizable) {
       
   298         this(title, resizable, false, false, false);
       
   299     }
       
   300 
       
   301     /**
       
   302      * Creates a non-maximizable, non-iconifiable <code>JInternalFrame</code>
       
   303      * with the specified title, resizability, and
       
   304      * closability.
       
   305      *
       
   306      * @param title      the <code>String</code> to display in the title bar
       
   307      * @param resizable  if <code>true</code>, the internal frame can be resized
       
   308      * @param closable   if <code>true</code>, the internal frame can be closed
       
   309      */
       
   310     public JInternalFrame(String title, boolean resizable, boolean closable) {
       
   311         this(title, resizable, closable, false, false);
       
   312     }
       
   313 
       
   314     /**
       
   315      * Creates a non-iconifiable <code>JInternalFrame</code>
       
   316      * with the specified title,
       
   317      * resizability, closability, and maximizability.
       
   318      *
       
   319      * @param title       the <code>String</code> to display in the title bar
       
   320      * @param resizable   if <code>true</code>, the internal frame can be resized
       
   321      * @param closable    if <code>true</code>, the internal frame can be closed
       
   322      * @param maximizable if <code>true</code>, the internal frame can be maximized
       
   323      */
       
   324     public JInternalFrame(String title, boolean resizable, boolean closable,
       
   325                           boolean maximizable) {
       
   326         this(title, resizable, closable, maximizable, false);
       
   327     }
       
   328 
       
   329     /**
       
   330      * Creates a <code>JInternalFrame</code> with the specified title,
       
   331      * resizability, closability, maximizability, and iconifiability.
       
   332      * All <code>JInternalFrame</code> constructors use this one.
       
   333      *
       
   334      * @param title       the <code>String</code> to display in the title bar
       
   335      * @param resizable   if <code>true</code>, the internal frame can be resized
       
   336      * @param closable    if <code>true</code>, the internal frame can be closed
       
   337      * @param maximizable if <code>true</code>, the internal frame can be maximized
       
   338      * @param iconifiable if <code>true</code>, the internal frame can be iconified
       
   339      */
       
   340     public JInternalFrame(String title, boolean resizable, boolean closable,
       
   341                                 boolean maximizable, boolean iconifiable) {
       
   342 
       
   343         setRootPane(createRootPane());
       
   344         setLayout(new BorderLayout());
       
   345         this.title = title;
       
   346         this.resizable = resizable;
       
   347         this.closable = closable;
       
   348         this.maximizable = maximizable;
       
   349         isMaximum = false;
       
   350         this.iconable = iconifiable;
       
   351         isIcon = false;
       
   352         setVisible(false);
       
   353         setRootPaneCheckingEnabled(true);
       
   354         desktopIcon = new JDesktopIcon(this);
       
   355         updateUI();
       
   356         sun.awt.SunToolkit.checkAndSetPolicy(this, true);
       
   357         addPropertyChangeListenerIfNecessary();
       
   358     }
       
   359 
       
   360     /**
       
   361      * Called by the constructor to set up the <code>JRootPane</code>.
       
   362      * @return  a new <code>JRootPane</code>
       
   363      * @see JRootPane
       
   364      */
       
   365     protected JRootPane createRootPane() {
       
   366         return new JRootPane();
       
   367     }
       
   368 
       
   369     /**
       
   370      * Returns the look-and-feel object that renders this component.
       
   371      *
       
   372      * @return the <code>InternalFrameUI</code> object that renders
       
   373      *          this component
       
   374      */
       
   375     public InternalFrameUI getUI() {
       
   376         return (InternalFrameUI)ui;
       
   377     }
       
   378 
       
   379     /**
       
   380      * Sets the UI delegate for this <code>JInternalFrame</code>.
       
   381      * @param ui  the UI delegate
       
   382      * @beaninfo
       
   383      *        bound: true
       
   384      *       hidden: true
       
   385      *    attribute: visualUpdate true
       
   386      *  description: The UI object that implements the Component's LookAndFeel.
       
   387      */
       
   388     public void setUI(InternalFrameUI ui) {
       
   389         boolean checkingEnabled = isRootPaneCheckingEnabled();
       
   390         try {
       
   391             setRootPaneCheckingEnabled(false);
       
   392             super.setUI(ui);
       
   393         }
       
   394         finally {
       
   395             setRootPaneCheckingEnabled(checkingEnabled);
       
   396         }
       
   397     }
       
   398 
       
   399     /**
       
   400      * Notification from the <code>UIManager</code> that the look and feel
       
   401      * has changed.
       
   402      * Replaces the current UI object with the latest version from the
       
   403      * <code>UIManager</code>.
       
   404      *
       
   405      * @see JComponent#updateUI
       
   406      */
       
   407     public void updateUI() {
       
   408         setUI((InternalFrameUI)UIManager.getUI(this));
       
   409         invalidate();
       
   410         if (desktopIcon != null) {
       
   411             desktopIcon.updateUIWhenHidden();
       
   412         }
       
   413     }
       
   414 
       
   415     /* This method is called if <code>updateUI</code> was called
       
   416      * on the associated
       
   417      * JDesktopIcon.  It's necessary to avoid infinite recursion.
       
   418      */
       
   419     void updateUIWhenHidden() {
       
   420         setUI((InternalFrameUI)UIManager.getUI(this));
       
   421         invalidate();
       
   422         Component[] children = getComponents();
       
   423         if (children != null) {
       
   424             for(int i = 0; i < children.length; i++) {
       
   425                 SwingUtilities.updateComponentTreeUI(children[i]);
       
   426             }
       
   427         }
       
   428     }
       
   429 
       
   430 
       
   431     /**
       
   432      * Returns the name of the look-and-feel
       
   433      * class that renders this component.
       
   434      *
       
   435      * @return the string "InternalFrameUI"
       
   436      *
       
   437      * @see JComponent#getUIClassID
       
   438      * @see UIDefaults#getUI
       
   439      *
       
   440      * @beaninfo
       
   441      *     description: UIClassID
       
   442      */
       
   443     public String getUIClassID() {
       
   444         return uiClassID;
       
   445     }
       
   446 
       
   447     /**
       
   448      * Returns whether calls to <code>add</code> and
       
   449      * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
       
   450      *
       
   451      * @return true if <code>add</code> and <code>setLayout</code>
       
   452      *         are fowarded; false otherwise
       
   453      *
       
   454      * @see #addImpl
       
   455      * @see #setLayout
       
   456      * @see #setRootPaneCheckingEnabled
       
   457      * @see javax.swing.RootPaneContainer
       
   458      */
       
   459     protected boolean isRootPaneCheckingEnabled() {
       
   460         return rootPaneCheckingEnabled;
       
   461     }
       
   462 
       
   463     /**
       
   464      * Sets whether calls to <code>add</code> and
       
   465      * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
       
   466      *
       
   467      * @param enabled  true if <code>add</code> and <code>setLayout</code>
       
   468      *        are forwarded, false if they should operate directly on the
       
   469      *        <code>JInternalFrame</code>.
       
   470      *
       
   471      * @see #addImpl
       
   472      * @see #setLayout
       
   473      * @see #isRootPaneCheckingEnabled
       
   474      * @see javax.swing.RootPaneContainer
       
   475      * @beaninfo
       
   476      *      hidden: true
       
   477      * description: Whether the add and setLayout methods are forwarded
       
   478      */
       
   479     protected void setRootPaneCheckingEnabled(boolean enabled) {
       
   480         rootPaneCheckingEnabled = enabled;
       
   481     }
       
   482 
       
   483     /**
       
   484      * Adds the specified child <code>Component</code>.
       
   485      * This method is overridden to conditionally forward calls to the
       
   486      * <code>contentPane</code>.
       
   487      * By default, children are added to the <code>contentPane</code> instead
       
   488      * of the frame, refer to {@link javax.swing.RootPaneContainer} for
       
   489      * details.
       
   490      *
       
   491      * @param comp the component to be enhanced
       
   492      * @param constraints the constraints to be respected
       
   493      * @param index the index
       
   494      * @exception IllegalArgumentException if <code>index</code> is invalid
       
   495      * @exception IllegalArgumentException if adding the container's parent
       
   496      *                  to itself
       
   497      * @exception IllegalArgumentException if adding a window to a container
       
   498      *
       
   499      * @see #setRootPaneCheckingEnabled
       
   500      * @see javax.swing.RootPaneContainer
       
   501      */
       
   502     protected void addImpl(Component comp, Object constraints, int index) {
       
   503         if(isRootPaneCheckingEnabled()) {
       
   504             getContentPane().add(comp, constraints, index);
       
   505         }
       
   506         else {
       
   507             super.addImpl(comp, constraints, index);
       
   508         }
       
   509     }
       
   510 
       
   511     /**
       
   512      * Removes the specified component from the container. If
       
   513      * <code>comp</code> is not a child of the <code>JInternalFrame</code>
       
   514      * this will forward the call to the <code>contentPane</code>.
       
   515      *
       
   516      * @param comp the component to be removed
       
   517      * @throws NullPointerException if <code>comp</code> is null
       
   518      * @see #add
       
   519      * @see javax.swing.RootPaneContainer
       
   520      */
       
   521     public void remove(Component comp) {
       
   522         int oldCount = getComponentCount();
       
   523         super.remove(comp);
       
   524         if (oldCount == getComponentCount()) {
       
   525             getContentPane().remove(comp);
       
   526         }
       
   527     }
       
   528 
       
   529 
       
   530     /**
       
   531      * Ensures that, by default, the layout of this component cannot be set.
       
   532      * Overridden to conditionally forward the call to the
       
   533      * <code>contentPane</code>.
       
   534      * Refer to {@link javax.swing.RootPaneContainer} for
       
   535      * more information.
       
   536      *
       
   537      * @param manager the <code>LayoutManager</code>
       
   538      * @see #setRootPaneCheckingEnabled
       
   539      */
       
   540     public void setLayout(LayoutManager manager) {
       
   541         if(isRootPaneCheckingEnabled()) {
       
   542             getContentPane().setLayout(manager);
       
   543         }
       
   544         else {
       
   545             super.setLayout(manager);
       
   546         }
       
   547     }
       
   548 
       
   549 
       
   550 //////////////////////////////////////////////////////////////////////////
       
   551 /// Property Methods
       
   552 //////////////////////////////////////////////////////////////////////////
       
   553 
       
   554     /**
       
   555      * Returns the current <code>JMenuBar</code> for this
       
   556      * <code>JInternalFrame</code>, or <code>null</code>
       
   557      * if no menu bar has been set.
       
   558      * @return the current menu bar, or <code>null</code> if none has been set
       
   559      *
       
   560      * @deprecated As of Swing version 1.0.3,
       
   561      * replaced by <code>getJMenuBar()</code>.
       
   562      */
       
   563     @Deprecated
       
   564     public JMenuBar getMenuBar() {
       
   565       return getRootPane().getMenuBar();
       
   566     }
       
   567 
       
   568     /**
       
   569      * Returns the current <code>JMenuBar</code> for this
       
   570      * <code>JInternalFrame</code>, or <code>null</code>
       
   571      * if no menu bar has been set.
       
   572      *
       
   573      * @return  the <code>JMenuBar</code> used by this internal frame
       
   574      * @see #setJMenuBar
       
   575      */
       
   576     public JMenuBar getJMenuBar() {
       
   577         return getRootPane().getJMenuBar();
       
   578     }
       
   579 
       
   580     /**
       
   581      * Sets the <code>menuBar</code> property for this <code>JInternalFrame</code>.
       
   582      *
       
   583      * @param m  the <code>JMenuBar</code> to use in this internal frame
       
   584      * @see #getJMenuBar
       
   585      * @deprecated As of Swing version 1.0.3
       
   586      *  replaced by <code>setJMenuBar(JMenuBar m)</code>.
       
   587      */
       
   588     @Deprecated
       
   589     public void setMenuBar(JMenuBar m) {
       
   590         JMenuBar oldValue = getMenuBar();
       
   591         getRootPane().setJMenuBar(m);
       
   592         firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
       
   593     }
       
   594 
       
   595     /**
       
   596      * Sets the <code>menuBar</code> property for this <code>JInternalFrame</code>.
       
   597      *
       
   598      * @param m  the <code>JMenuBar</code> to use in this internal frame
       
   599      * @see #getJMenuBar
       
   600      * @beaninfo
       
   601      *     bound: true
       
   602      *     preferred: true
       
   603      *     description: The menu bar for accessing pulldown menus
       
   604      *                  from this internal frame.
       
   605      */
       
   606     public void setJMenuBar(JMenuBar m){
       
   607         JMenuBar oldValue = getMenuBar();
       
   608         getRootPane().setJMenuBar(m);
       
   609         firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
       
   610     }
       
   611 
       
   612     // implements javax.swing.RootPaneContainer
       
   613     /**
       
   614      * Returns the content pane for this internal frame.
       
   615      * @return the content pane
       
   616      */
       
   617     public Container getContentPane() {
       
   618         return getRootPane().getContentPane();
       
   619     }
       
   620 
       
   621 
       
   622     /**
       
   623      * Sets this <code>JInternalFrame</code>'s <code>contentPane</code>
       
   624      * property.
       
   625      *
       
   626      * @param c  the content pane for this internal frame
       
   627      *
       
   628      * @exception java.awt.IllegalComponentStateException (a runtime
       
   629      *           exception) if the content pane parameter is <code>null</code>
       
   630      * @see RootPaneContainer#getContentPane
       
   631      * @beaninfo
       
   632      *     bound: true
       
   633      *     hidden: true
       
   634      *     description: The client area of the internal frame where child
       
   635      *                  components are normally inserted.
       
   636      */
       
   637     public void setContentPane(Container c) {
       
   638         Container oldValue = getContentPane();
       
   639         getRootPane().setContentPane(c);
       
   640         firePropertyChange(CONTENT_PANE_PROPERTY, oldValue, c);
       
   641     }
       
   642 
       
   643     /**
       
   644      * Returns the layered pane for this internal frame.
       
   645      *
       
   646      * @return a <code>JLayeredPane</code> object
       
   647      * @see RootPaneContainer#setLayeredPane
       
   648      * @see RootPaneContainer#getLayeredPane
       
   649      */
       
   650     public JLayeredPane getLayeredPane() {
       
   651         return getRootPane().getLayeredPane();
       
   652     }
       
   653 
       
   654     /**
       
   655      * Sets this <code>JInternalFrame</code>'s
       
   656      * <code>layeredPane</code> property.
       
   657      *
       
   658      * @param layered the <code>JLayeredPane</code> for this internal frame
       
   659      *
       
   660      * @exception java.awt.IllegalComponentStateException (a runtime
       
   661      *           exception) if the layered pane parameter is <code>null</code>
       
   662      * @see RootPaneContainer#setLayeredPane
       
   663      * @beaninfo
       
   664      *     hidden: true
       
   665      *     bound: true
       
   666      *     description: The pane which holds the various desktop layers.
       
   667      */
       
   668     public void setLayeredPane(JLayeredPane layered) {
       
   669         JLayeredPane oldValue = getLayeredPane();
       
   670         getRootPane().setLayeredPane(layered);
       
   671         firePropertyChange(LAYERED_PANE_PROPERTY, oldValue, layered);
       
   672     }
       
   673 
       
   674     /**
       
   675      * Returns the glass pane for this internal frame.
       
   676      *
       
   677      * @return the glass pane
       
   678      * @see RootPaneContainer#setGlassPane
       
   679      */
       
   680     public Component getGlassPane() {
       
   681         return getRootPane().getGlassPane();
       
   682     }
       
   683 
       
   684     /**
       
   685      * Sets this <code>JInternalFrame</code>'s
       
   686      * <code>glassPane</code> property.
       
   687      *
       
   688      * @param glass the glass pane for this internal frame
       
   689      * @see RootPaneContainer#getGlassPane
       
   690      * @beaninfo
       
   691      *     bound: true
       
   692      *     hidden: true
       
   693      *     description: A transparent pane used for menu rendering.
       
   694      */
       
   695     public void setGlassPane(Component glass) {
       
   696         Component oldValue = getGlassPane();
       
   697         getRootPane().setGlassPane(glass);
       
   698         firePropertyChange(GLASS_PANE_PROPERTY, oldValue, glass);
       
   699     }
       
   700 
       
   701     /**
       
   702      * Returns the <code>rootPane</code> object for this internal frame.
       
   703      *
       
   704      * @return the <code>rootPane</code> property
       
   705      * @see RootPaneContainer#getRootPane
       
   706      */
       
   707     public JRootPane getRootPane() {
       
   708         return rootPane;
       
   709     }
       
   710 
       
   711 
       
   712     /**
       
   713      * Sets the <code>rootPane</code> property
       
   714      * for this <code>JInternalFrame</code>.
       
   715      * This method is called by the constructor.
       
   716      *
       
   717      * @param root  the new <code>JRootPane</code> object
       
   718      * @beaninfo
       
   719      *     bound: true
       
   720      *     hidden: true
       
   721      *     description: The root pane used by this internal frame.
       
   722      */
       
   723     protected void setRootPane(JRootPane root) {
       
   724         if(rootPane != null) {
       
   725             remove(rootPane);
       
   726         }
       
   727         JRootPane oldValue = getRootPane();
       
   728         rootPane = root;
       
   729         if(rootPane != null) {
       
   730             boolean checkingEnabled = isRootPaneCheckingEnabled();
       
   731             try {
       
   732                 setRootPaneCheckingEnabled(false);
       
   733                 add(rootPane, BorderLayout.CENTER);
       
   734             }
       
   735             finally {
       
   736                 setRootPaneCheckingEnabled(checkingEnabled);
       
   737             }
       
   738         }
       
   739         firePropertyChange(ROOT_PANE_PROPERTY, oldValue, root);
       
   740     }
       
   741 
       
   742     /**
       
   743      * Sets whether this <code>JInternalFrame</code> can be closed by
       
   744      * some user action.
       
   745      * @param b a boolean value, where <code>true</code> means this internal frame can be closed
       
   746      * @beaninfo
       
   747      *     preferred: true
       
   748      *           bound: true
       
   749      *     description: Indicates whether this internal frame can be closed.
       
   750      */
       
   751     public void setClosable(boolean b) {
       
   752         Boolean oldValue = closable ? Boolean.TRUE : Boolean.FALSE;
       
   753         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
       
   754         closable = b;
       
   755         firePropertyChange("closable", oldValue, newValue);
       
   756     }
       
   757 
       
   758     /**
       
   759      * Returns whether this <code>JInternalFrame</code> can be closed by
       
   760      * some user action.
       
   761      * @return <code>true</code> if this internal frame can be closed
       
   762      */
       
   763     public boolean isClosable() {
       
   764         return closable;
       
   765     }
       
   766 
       
   767     /**
       
   768      * Returns whether this <code>JInternalFrame</code> is currently closed.
       
   769      * @return <code>true</code> if this internal frame is closed, <code>false</code> otherwise
       
   770      */
       
   771     public boolean isClosed() {
       
   772         return isClosed;
       
   773     }
       
   774 
       
   775     /**
       
   776      * Closes this internal frame if the argument is <code>true</code>.
       
   777      * Do not invoke this method with a <code>false</code> argument;
       
   778      * the result of invoking <code>setClosed(false)</code>
       
   779      * is unspecified.
       
   780      *
       
   781      * <p>
       
   782      *
       
   783      * If the internal frame is already closed,
       
   784      * this method does nothing and returns immediately.
       
   785      * Otherwise,
       
   786      * this method begins by firing
       
   787      * an <code>INTERNAL_FRAME_CLOSING</code> event.
       
   788      * Then this method sets the <code>closed</code> property to <code>true</code>
       
   789      * unless a listener vetoes the property change.
       
   790      * This method finishes by making the internal frame
       
   791      * invisible and unselected,
       
   792      * and then firing an <code>INTERNAL_FRAME_CLOSED</code> event.
       
   793      *
       
   794      * <p>
       
   795      *
       
   796      * <b>Note:</b>
       
   797      * To reuse an internal frame that has been closed,
       
   798      * you must add it to a container
       
   799      * (even if you never removed it from its previous container).
       
   800      * Typically, this container will be the <code>JDesktopPane</code>
       
   801      * that previously contained the internal frame.
       
   802      *
       
   803      * @param b must be <code>true</code>
       
   804      *
       
   805      * @exception PropertyVetoException when the attempt to set the
       
   806      *            property is vetoed by the <code>JInternalFrame</code>
       
   807      *
       
   808      * @see #isClosed()
       
   809      * @see #setDefaultCloseOperation
       
   810      * @see #dispose
       
   811      * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSING
       
   812      *
       
   813      * @beaninfo
       
   814      *           bound: true
       
   815      *     constrained: true
       
   816      *     description: Indicates whether this internal frame has been closed.
       
   817      */
       
   818     public void setClosed(boolean b) throws PropertyVetoException {
       
   819         if (isClosed == b) {
       
   820             return;
       
   821         }
       
   822 
       
   823         Boolean oldValue = isClosed ? Boolean.TRUE : Boolean.FALSE;
       
   824         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
       
   825         if (b) {
       
   826           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
       
   827         }
       
   828         fireVetoableChange(IS_CLOSED_PROPERTY, oldValue, newValue);
       
   829         isClosed = b;
       
   830         if (isClosed) {
       
   831           setVisible(false);
       
   832         }
       
   833         firePropertyChange(IS_CLOSED_PROPERTY, oldValue, newValue);
       
   834         if (isClosed) {
       
   835           dispose();
       
   836         } else if (!opened) {
       
   837           /* this bogus -- we haven't defined what
       
   838              setClosed(false) means. */
       
   839           //        fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
       
   840           //            opened = true;
       
   841         }
       
   842     }
       
   843 
       
   844     /**
       
   845      * Sets whether the <code>JInternalFrame</code> can be resized by some
       
   846      * user action.
       
   847      *
       
   848      * @param b  a boolean, where <code>true</code> means this internal frame can be resized
       
   849      * @beaninfo
       
   850      *     preferred: true
       
   851      *           bound: true
       
   852      *     description: Determines whether this internal frame can be resized
       
   853      *                  by the user.
       
   854      */
       
   855     public void setResizable(boolean b) {
       
   856         Boolean oldValue = resizable ? Boolean.TRUE : Boolean.FALSE;
       
   857         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
       
   858         resizable = b;
       
   859         firePropertyChange("resizable", oldValue, newValue);
       
   860     }
       
   861 
       
   862     /**
       
   863      * Returns whether the <code>JInternalFrame</code> can be resized
       
   864      * by some user action.
       
   865      *
       
   866      * @return <code>true</code> if this internal frame can be resized, <code>false</code> otherwise
       
   867      */
       
   868     public boolean isResizable() {
       
   869         // don't allow resizing when maximized.
       
   870         return isMaximum ? false : resizable;
       
   871     }
       
   872 
       
   873     /**
       
   874      * Sets the <code>iconable</code> property,
       
   875      * which must be <code>true</code>
       
   876      * for the user to be able to
       
   877      * make the <code>JInternalFrame</code> an icon.
       
   878      * Some look and feels might not implement iconification;
       
   879      * they will ignore this property.
       
   880      *
       
   881      * @param b  a boolean, where <code>true</code> means this internal frame can be iconified
       
   882      * @beaninfo
       
   883      *     preferred: true
       
   884                bound: true
       
   885      *     description: Determines whether this internal frame can be iconified.
       
   886      */
       
   887     public void setIconifiable(boolean b) {
       
   888         Boolean oldValue = iconable ? Boolean.TRUE : Boolean.FALSE;
       
   889         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
       
   890         iconable = b;
       
   891         firePropertyChange("iconable", oldValue, newValue);
       
   892     }
       
   893 
       
   894     /**
       
   895      * Gets the <code>iconable</code> property,
       
   896      * which by default is <code>false</code>.
       
   897      *
       
   898      * @return the value of the <code>iconable</code> property.
       
   899      *
       
   900      * @see #setIconifiable
       
   901      */
       
   902     public boolean isIconifiable() {
       
   903         return iconable;
       
   904     }
       
   905 
       
   906     /**
       
   907      * Returns whether the <code>JInternalFrame</code> is currently iconified.
       
   908      *
       
   909      * @return <code>true</code> if this internal frame is iconified
       
   910      */
       
   911     public boolean isIcon() {
       
   912         return isIcon;
       
   913     }
       
   914 
       
   915     /**
       
   916      * Iconifies or de-iconifies this internal frame,
       
   917      * if the look and feel supports iconification.
       
   918      * If the internal frame's state changes to iconified,
       
   919      * this method fires an <code>INTERNAL_FRAME_ICONIFIED</code> event.
       
   920      * If the state changes to de-iconified,
       
   921      * an <code>INTERNAL_FRAME_DEICONIFIED</code> event is fired.
       
   922      *
       
   923      * @param b a boolean, where <code>true</code> means to iconify this internal frame and
       
   924      *          <code>false</code> means to de-iconify it
       
   925      * @exception PropertyVetoException when the attempt to set the
       
   926      *            property is vetoed by the <code>JInternalFrame</code>
       
   927      *
       
   928      * @see InternalFrameEvent#INTERNAL_FRAME_ICONIFIED
       
   929      * @see InternalFrameEvent#INTERNAL_FRAME_DEICONIFIED
       
   930      *
       
   931      * @beaninfo
       
   932      *           bound: true
       
   933      *     constrained: true
       
   934      *     description: The image displayed when this internal frame is minimized.
       
   935      */
       
   936     public void setIcon(boolean b) throws PropertyVetoException {
       
   937         if (isIcon == b) {
       
   938             return;
       
   939         }
       
   940 
       
   941         /* If an internal frame is being iconified before it has a
       
   942            parent, (e.g., client wants it to start iconic), create the
       
   943            parent if possible so that we can place the icon in its
       
   944            proper place on the desktop. I am not sure the call to
       
   945            validate() is necessary, since we are not going to display
       
   946            this frame yet */
       
   947         firePropertyChange("ancestor", null, getParent());
       
   948 
       
   949         Boolean oldValue = isIcon ? Boolean.TRUE : Boolean.FALSE;
       
   950         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
       
   951         fireVetoableChange(IS_ICON_PROPERTY, oldValue, newValue);
       
   952         isIcon = b;
       
   953         firePropertyChange(IS_ICON_PROPERTY, oldValue, newValue);
       
   954         if (b)
       
   955           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
       
   956         else
       
   957           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
       
   958     }
       
   959 
       
   960     /**
       
   961      * Sets the <code>maximizable</code> property,
       
   962      * which determines whether the <code>JInternalFrame</code>
       
   963      * can be maximized by
       
   964      * some user action.
       
   965      * Some look and feels might not support maximizing internal frames;
       
   966      * they will ignore this property.
       
   967      *
       
   968      * @param b <code>true</code> to specify that this internal frame should be maximizable; <code>false</code> to specify that it should not be
       
   969      * @beaninfo
       
   970      *         bound: true
       
   971      *     preferred: true
       
   972      *     description: Determines whether this internal frame can be maximized.
       
   973      */
       
   974     public void setMaximizable(boolean b) {
       
   975         Boolean oldValue = maximizable ? Boolean.TRUE : Boolean.FALSE;
       
   976         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
       
   977         maximizable = b;
       
   978         firePropertyChange("maximizable", oldValue, newValue);
       
   979     }
       
   980 
       
   981     /**
       
   982      * Gets the value of the <code>maximizable</code> property.
       
   983      *
       
   984      * @return the value of the <code>maximizable</code> property
       
   985      * @see #setMaximizable
       
   986      */
       
   987     public boolean isMaximizable() {
       
   988         return maximizable;
       
   989     }
       
   990 
       
   991     /**
       
   992      * Returns whether the <code>JInternalFrame</code> is currently maximized.
       
   993      *
       
   994      * @return <code>true</code> if this internal frame is maximized, <code>false</code> otherwise
       
   995      */
       
   996     public boolean isMaximum() {
       
   997         return isMaximum;
       
   998     }
       
   999 
       
  1000     /**
       
  1001      * Maximizes and restores this internal frame.  A maximized frame is resized to
       
  1002      * fully fit the <code>JDesktopPane</code> area associated with the
       
  1003      * <code>JInternalFrame</code>.
       
  1004      * A restored frame's size is set to the <code>JInternalFrame</code>'s
       
  1005      * actual size.
       
  1006      *
       
  1007      * @param b  a boolean, where <code>true</code> maximizes this internal frame and <code>false</code>
       
  1008      *           restores it
       
  1009      * @exception PropertyVetoException when the attempt to set the
       
  1010      *            property is vetoed by the <code>JInternalFrame</code>
       
  1011      * @beaninfo
       
  1012      *     bound: true
       
  1013      *     constrained: true
       
  1014      *     description: Indicates whether this internal frame is maximized.
       
  1015      */
       
  1016     public void setMaximum(boolean b) throws PropertyVetoException {
       
  1017         if (isMaximum == b) {
       
  1018             return;
       
  1019         }
       
  1020 
       
  1021         Boolean oldValue = isMaximum ? Boolean.TRUE : Boolean.FALSE;
       
  1022         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
       
  1023         fireVetoableChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
       
  1024         /* setting isMaximum above the event firing means that
       
  1025            property listeners that, for some reason, test it will
       
  1026            get it wrong... See, for example, getNormalBounds() */
       
  1027         isMaximum = b;
       
  1028         firePropertyChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
       
  1029     }
       
  1030 
       
  1031     /**
       
  1032      * Returns the title of the <code>JInternalFrame</code>.
       
  1033      *
       
  1034      * @return a <code>String</code> containing this internal frame's title
       
  1035      * @see #setTitle
       
  1036      */
       
  1037     public String getTitle() {
       
  1038         return title;
       
  1039     }
       
  1040 
       
  1041     /**
       
  1042      * Sets the <code>JInternalFrame</code> title. <code>title</code>
       
  1043      * may have a <code>null</code> value.
       
  1044      * @see #getTitle
       
  1045      *
       
  1046      * @param title  the <code>String</code> to display in the title bar
       
  1047      * @beaninfo
       
  1048      *     preferred: true
       
  1049      *     bound: true
       
  1050      *     description: The text displayed in the title bar.
       
  1051      */
       
  1052     public void setTitle(String title) {
       
  1053         String oldValue = this.title;
       
  1054         this.title = title;
       
  1055         firePropertyChange(TITLE_PROPERTY, oldValue, title);
       
  1056     }
       
  1057 
       
  1058     /**
       
  1059      * Selects or deselects the internal frame
       
  1060      * if it's showing.
       
  1061      * A <code>JInternalFrame</code> normally draws its title bar
       
  1062      * differently if it is
       
  1063      * the selected frame, which indicates to the user that this
       
  1064      * internal frame has the focus.
       
  1065      * When this method changes the state of the internal frame
       
  1066      * from deselected to selected, it fires an
       
  1067      * <code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code> event.
       
  1068      * If the change is from selected to deselected,
       
  1069      * an <code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code> event
       
  1070      * is fired.
       
  1071      *
       
  1072      * @param selected  a boolean, where <code>true</code> means this internal frame
       
  1073      *                  should become selected (currently active)
       
  1074      *                  and <code>false</code> means it should become deselected
       
  1075      * @exception PropertyVetoException when the attempt to set the
       
  1076      *            property is vetoed by the <code>JInternalFrame</code>
       
  1077      *
       
  1078      * @see #isShowing
       
  1079      * @see InternalFrameEvent#INTERNAL_FRAME_ACTIVATED
       
  1080      * @see InternalFrameEvent#INTERNAL_FRAME_DEACTIVATED
       
  1081      *
       
  1082      * @beaninfo
       
  1083      *     constrained: true
       
  1084      *           bound: true
       
  1085      *     description: Indicates whether this internal frame is currently
       
  1086      *                  the active frame.
       
  1087      */
       
  1088     public void setSelected(boolean selected) throws PropertyVetoException {
       
  1089        // The InternalFrame may already be selected, but the focus
       
  1090        // may be outside it, so restore the focus to the subcomponent
       
  1091        // which previously had it. See Bug 4302764.
       
  1092         if (selected && isSelected) {
       
  1093             restoreSubcomponentFocus();
       
  1094             return;
       
  1095         }
       
  1096         // The internal frame or the desktop icon must be showing to allow
       
  1097         // selection.  We may deselect even if neither is showing.
       
  1098         if ((isSelected == selected) || (selected &&
       
  1099             (isIcon ? !desktopIcon.isShowing() : !isShowing()))) {
       
  1100             return;
       
  1101         }
       
  1102 
       
  1103         Boolean oldValue = isSelected ? Boolean.TRUE : Boolean.FALSE;
       
  1104         Boolean newValue = selected ? Boolean.TRUE : Boolean.FALSE;
       
  1105         fireVetoableChange(IS_SELECTED_PROPERTY, oldValue, newValue);
       
  1106 
       
  1107         /* We don't want to leave focus in the previously selected
       
  1108            frame, so we have to set it to *something* in case it
       
  1109            doesn't get set in some other way (as if a user clicked on
       
  1110            a component that doesn't request focus).  If this call is
       
  1111            happening because the user clicked on a component that will
       
  1112            want focus, then it will get transfered there later.
       
  1113 
       
  1114            We test for parent.isShowing() above, because AWT throws a
       
  1115            NPE if you try to request focus on a lightweight before its
       
  1116            parent has been made visible */
       
  1117 
       
  1118         if (selected) {
       
  1119             restoreSubcomponentFocus();
       
  1120         }
       
  1121 
       
  1122         isSelected = selected;
       
  1123         firePropertyChange(IS_SELECTED_PROPERTY, oldValue, newValue);
       
  1124         if (isSelected)
       
  1125           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED);
       
  1126         else
       
  1127           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
       
  1128         repaint();
       
  1129     }
       
  1130 
       
  1131     /**
       
  1132      * Returns whether the <code>JInternalFrame</code> is the
       
  1133      * currently "selected" or active frame.
       
  1134      *
       
  1135      * @return <code>true</code> if this internal frame is currently selected (active)
       
  1136      * @see #setSelected
       
  1137      */
       
  1138     public boolean isSelected() {
       
  1139         return isSelected;
       
  1140     }
       
  1141 
       
  1142     /**
       
  1143      * Sets an image to be displayed in the titlebar of this internal frame (usually
       
  1144      * in the top-left corner).
       
  1145      * This image is not the <code>desktopIcon</code> object, which
       
  1146      * is the image displayed in the <code>JDesktop</code> when
       
  1147      * this internal frame is iconified.
       
  1148      *
       
  1149      * Passing <code>null</code> to this function is valid,
       
  1150      * but the look and feel
       
  1151      * can choose the
       
  1152      * appropriate behavior for that situation, such as displaying no icon
       
  1153      * or a default icon for the look and feel.
       
  1154      *
       
  1155      * @param icon the <code>Icon</code> to display in the title bar
       
  1156      * @see #getFrameIcon
       
  1157      * @beaninfo
       
  1158      *           bound: true
       
  1159      *     description: The icon shown in the top-left corner of this internal frame.
       
  1160      */
       
  1161   public void setFrameIcon(Icon icon) {
       
  1162         Icon oldIcon = frameIcon;
       
  1163         frameIcon = icon;
       
  1164         firePropertyChange(FRAME_ICON_PROPERTY, oldIcon, icon);
       
  1165     }
       
  1166 
       
  1167     /**
       
  1168      * Returns the image displayed in the title bar of this internal frame (usually
       
  1169      * in the top-left corner).
       
  1170      *
       
  1171      * @return the <code>Icon</code> displayed in the title bar
       
  1172      * @see #setFrameIcon
       
  1173      */
       
  1174     public Icon getFrameIcon()  {
       
  1175         return frameIcon;
       
  1176     }
       
  1177 
       
  1178     /**
       
  1179       * Convenience method that moves this component to position 0 if its
       
  1180       * parent is a <code>JLayeredPane</code>.
       
  1181       */
       
  1182     public void moveToFront() {
       
  1183         if (isIcon()) {
       
  1184             if (getDesktopIcon().getParent() instanceof JLayeredPane) {
       
  1185                 ((JLayeredPane)getDesktopIcon().getParent()).
       
  1186                     moveToFront(getDesktopIcon());
       
  1187             }
       
  1188         }
       
  1189         else if (getParent() instanceof JLayeredPane) {
       
  1190             ((JLayeredPane)getParent()).moveToFront(this);
       
  1191         }
       
  1192     }
       
  1193 
       
  1194     /**
       
  1195       * Convenience method that moves this component to position -1 if its
       
  1196       * parent is a <code>JLayeredPane</code>.
       
  1197       */
       
  1198     public void moveToBack() {
       
  1199         if (isIcon()) {
       
  1200             if (getDesktopIcon().getParent() instanceof JLayeredPane) {
       
  1201                 ((JLayeredPane)getDesktopIcon().getParent()).
       
  1202                     moveToBack(getDesktopIcon());
       
  1203             }
       
  1204         }
       
  1205         else if (getParent() instanceof JLayeredPane) {
       
  1206             ((JLayeredPane)getParent()).moveToBack(this);
       
  1207         }
       
  1208     }
       
  1209 
       
  1210     /**
       
  1211      * Returns the last <code>Cursor</code> that was set by the
       
  1212      * <code>setCursor</code> method that is not a resizable
       
  1213      * <code>Cursor</code>.
       
  1214      *
       
  1215      * @return the last non-resizable <code>Cursor</code>
       
  1216      * @since 1.6
       
  1217      */
       
  1218     public Cursor getLastCursor() {
       
  1219         return lastCursor;
       
  1220     }
       
  1221 
       
  1222     /**
       
  1223      * {@inheritDoc}
       
  1224      * @since 1.6
       
  1225      */
       
  1226     public void setCursor(Cursor cursor) {
       
  1227         if (cursor == null) {
       
  1228             lastCursor = null;
       
  1229             super.setCursor(cursor);
       
  1230             return;
       
  1231         }
       
  1232         int type = cursor.getType();
       
  1233         if (!(type == Cursor.SW_RESIZE_CURSOR  ||
       
  1234               type == Cursor.SE_RESIZE_CURSOR  ||
       
  1235               type == Cursor.NW_RESIZE_CURSOR  ||
       
  1236               type == Cursor.NE_RESIZE_CURSOR  ||
       
  1237               type == Cursor.N_RESIZE_CURSOR   ||
       
  1238               type == Cursor.S_RESIZE_CURSOR   ||
       
  1239               type == Cursor.W_RESIZE_CURSOR   ||
       
  1240               type == Cursor.E_RESIZE_CURSOR)) {
       
  1241             lastCursor = cursor;
       
  1242         }
       
  1243         super.setCursor(cursor);
       
  1244     }
       
  1245 
       
  1246     /**
       
  1247      * Convenience method for setting the layer attribute of this component.
       
  1248      *
       
  1249      * @param layer  an <code>Integer</code> object specifying this
       
  1250      *          frame's desktop layer
       
  1251      * @see JLayeredPane
       
  1252      * @beaninfo
       
  1253      *     expert: true
       
  1254      *     description: Specifies what desktop layer is used.
       
  1255      */
       
  1256     public void setLayer(Integer layer) {
       
  1257         if(getParent() != null && getParent() instanceof JLayeredPane) {
       
  1258             // Normally we want to do this, as it causes the LayeredPane
       
  1259             // to draw properly.
       
  1260             JLayeredPane p = (JLayeredPane)getParent();
       
  1261             p.setLayer(this, layer.intValue(), p.getPosition(this));
       
  1262         } else {
       
  1263              // Try to do the right thing
       
  1264              JLayeredPane.putLayer(this, layer.intValue());
       
  1265              if(getParent() != null)
       
  1266                  getParent().repaint(getX(), getY(), getWidth(), getHeight());
       
  1267         }
       
  1268     }
       
  1269 
       
  1270     /**
       
  1271      * Convenience method for setting the layer attribute of this component.
       
  1272      * The method <code>setLayer(Integer)</code> should be used for
       
  1273      * layer values predefined in <code>JLayeredPane</code>.
       
  1274      * When using <code>setLayer(int)</code>, care must be taken not to
       
  1275      * accidentally clash with those values.
       
  1276      *
       
  1277      * @param layer  an integer specifying this internal frame's desktop layer
       
  1278      *
       
  1279      * @since 1.3
       
  1280      *
       
  1281      * @see #setLayer(Integer)
       
  1282      * @see JLayeredPane
       
  1283      * @beaninfo
       
  1284      *     expert: true
       
  1285      *     description: Specifies what desktop layer is used.
       
  1286      */
       
  1287     public void setLayer(int layer) {
       
  1288       this.setLayer(new Integer(layer));
       
  1289     }
       
  1290 
       
  1291     /**
       
  1292      * Convenience method for getting the layer attribute of this component.
       
  1293      *
       
  1294      * @return  an <code>Integer</code> object specifying this
       
  1295      *          frame's desktop layer
       
  1296      * @see JLayeredPane
       
  1297       */
       
  1298     public int getLayer() {
       
  1299         return JLayeredPane.getLayer(this);
       
  1300     }
       
  1301 
       
  1302     /**
       
  1303       * Convenience method that searches the ancestor hierarchy for a
       
  1304       * <code>JDesktop</code> instance. If <code>JInternalFrame</code>
       
  1305       * finds none, the <code>desktopIcon</code> tree is searched.
       
  1306       *
       
  1307       * @return the <code>JDesktopPane</code> this internal frame belongs to,
       
  1308       *         or <code>null</code> if none is found
       
  1309       */
       
  1310     public JDesktopPane getDesktopPane() {
       
  1311         Container p;
       
  1312 
       
  1313         // Search upward for desktop
       
  1314         p = getParent();
       
  1315         while(p != null && !(p instanceof JDesktopPane))
       
  1316             p = p.getParent();
       
  1317 
       
  1318         if(p == null) {
       
  1319            // search its icon parent for desktop
       
  1320            p = getDesktopIcon().getParent();
       
  1321            while(p != null && !(p instanceof JDesktopPane))
       
  1322                 p = p.getParent();
       
  1323         }
       
  1324 
       
  1325         return (JDesktopPane)p;
       
  1326     }
       
  1327 
       
  1328     /**
       
  1329      * Sets the <code>JDesktopIcon</code> associated with this
       
  1330      * <code>JInternalFrame</code>.
       
  1331      *
       
  1332      * @param d the <code>JDesktopIcon</code> to display on the desktop
       
  1333      * @see #getDesktopIcon
       
  1334      * @beaninfo
       
  1335      *           bound: true
       
  1336      *     description: The icon shown when this internal frame is minimized.
       
  1337      */
       
  1338     public void setDesktopIcon(JDesktopIcon d) {
       
  1339         JDesktopIcon oldValue = getDesktopIcon();
       
  1340         desktopIcon = d;
       
  1341         firePropertyChange("desktopIcon", oldValue, d);
       
  1342     }
       
  1343 
       
  1344     /**
       
  1345      * Returns the <code>JDesktopIcon</code> used when this
       
  1346      * <code>JInternalFrame</code> is iconified.
       
  1347      *
       
  1348      * @return the <code>JDesktopIcon</code> displayed on the desktop
       
  1349      * @see #setDesktopIcon
       
  1350      */
       
  1351     public JDesktopIcon getDesktopIcon() {
       
  1352         return desktopIcon;
       
  1353     }
       
  1354 
       
  1355     /**
       
  1356      * If the <code>JInternalFrame</code> is not in maximized state, returns
       
  1357      * <code>getBounds()</code>; otherwise, returns the bounds that the
       
  1358      * <code>JInternalFrame</code> would be restored to.
       
  1359      *
       
  1360      * @return a <code>Rectangle</code> containing the bounds of this
       
  1361      *          frame when in the normal state
       
  1362      * @since 1.3
       
  1363      */
       
  1364     public Rectangle getNormalBounds() {
       
  1365 
       
  1366       /* we used to test (!isMaximum) here, but since this
       
  1367          method is used by the property listener for the
       
  1368          IS_MAXIMUM_PROPERTY, it ended up getting the wrong
       
  1369          answer... Since normalBounds get set to null when the
       
  1370          frame is restored, this should work better */
       
  1371 
       
  1372       if (normalBounds != null) {
       
  1373         return normalBounds;
       
  1374       } else {
       
  1375         return getBounds();
       
  1376       }
       
  1377     }
       
  1378 
       
  1379     /**
       
  1380      * Sets the normal bounds for this internal frame, the bounds that
       
  1381      * this internal frame would be restored to from its maximized state.
       
  1382      * This method is intended for use only by desktop managers.
       
  1383      *
       
  1384      * @param r the bounds that this internal frame should be restored to
       
  1385      * @since 1.3
       
  1386      */
       
  1387     public void setNormalBounds(Rectangle r) {
       
  1388         normalBounds = r;
       
  1389     }
       
  1390 
       
  1391     /**
       
  1392      * If this <code>JInternalFrame</code> is active,
       
  1393      * returns the child that has focus.
       
  1394      * Otherwise, returns <code>null</code>.
       
  1395      *
       
  1396      * @return the component with focus, or <code>null</code> if no children have focus
       
  1397      * @since 1.3
       
  1398      */
       
  1399     public Component getFocusOwner() {
       
  1400         if (isSelected()) {
       
  1401             return lastFocusOwner;
       
  1402         }
       
  1403         return null;
       
  1404     }
       
  1405 
       
  1406     /**
       
  1407      * Returns the child component of this <code>JInternalFrame</code>
       
  1408      * that will receive the
       
  1409      * focus when this <code>JInternalFrame</code> is selected.
       
  1410      * If this <code>JInternalFrame</code> is
       
  1411      * currently selected, this method returns the same component as
       
  1412      * the <code>getFocusOwner</code> method.
       
  1413      * If this <code>JInternalFrame</code> is not selected,
       
  1414      * then the child component that most recently requested focus will be
       
  1415      * returned. If no child component has ever requested focus, then this
       
  1416      * <code>JInternalFrame</code>'s initial focusable component is returned.
       
  1417      * If no such
       
  1418      * child exists, then this <code>JInternalFrame</code>'s default component
       
  1419      * to focus is returned.
       
  1420      *
       
  1421      * @return the child component that will receive focus when this
       
  1422      *         <code>JInternalFrame</code> is selected
       
  1423      * @see #getFocusOwner
       
  1424      * @see #isSelected
       
  1425      * @since 1.4
       
  1426      */
       
  1427     public Component getMostRecentFocusOwner() {
       
  1428         if (isSelected()) {
       
  1429             return getFocusOwner();
       
  1430         }
       
  1431 
       
  1432         if (lastFocusOwner != null) {
       
  1433             return lastFocusOwner;
       
  1434         }
       
  1435 
       
  1436         FocusTraversalPolicy policy = getFocusTraversalPolicy();
       
  1437         if (policy instanceof InternalFrameFocusTraversalPolicy) {
       
  1438             return ((InternalFrameFocusTraversalPolicy)policy).
       
  1439                 getInitialComponent(this);
       
  1440         }
       
  1441 
       
  1442         Component toFocus = policy.getDefaultComponent(this);
       
  1443         if (toFocus != null) {
       
  1444             return toFocus;
       
  1445         }
       
  1446         return getContentPane();
       
  1447     }
       
  1448 
       
  1449     /**
       
  1450      * Requests the internal frame to restore focus to the
       
  1451      * last subcomponent that had focus. This is used by the UI when
       
  1452      * the user selected this internal frame --
       
  1453      * for example, by clicking on the title bar.
       
  1454      *
       
  1455      * @since 1.3
       
  1456      */
       
  1457     public void restoreSubcomponentFocus() {
       
  1458         if (isIcon()) {
       
  1459             SwingUtilities2.compositeRequestFocus(getDesktopIcon());
       
  1460         }
       
  1461         else {
       
  1462             // FocusPropertyChangeListener will eventually update
       
  1463             // lastFocusOwner. As focus requests are asynchronous
       
  1464             // lastFocusOwner may be accessed before it has been correctly
       
  1465             // updated. To avoid any problems, lastFocusOwner is immediately
       
  1466             // set, assuming the request will succeed.
       
  1467             lastFocusOwner = getMostRecentFocusOwner();
       
  1468             if (lastFocusOwner == null) {
       
  1469                 // Make sure focus is restored somewhere, so that
       
  1470                 // we don't leave a focused component in another frame while
       
  1471                 // this frame is selected.
       
  1472                 lastFocusOwner = getContentPane();
       
  1473             }
       
  1474             lastFocusOwner.requestFocus();
       
  1475         }
       
  1476     }
       
  1477 
       
  1478     private void setLastFocusOwner(Component component) {
       
  1479         lastFocusOwner = component;
       
  1480     }
       
  1481 
       
  1482     /**
       
  1483      * Moves and resizes this component.  Unlike other components,
       
  1484      * this implementation also forces re-layout, so that frame
       
  1485      * decorations such as the title bar are always redisplayed.
       
  1486      *
       
  1487      * @param x  an integer giving the component's new horizontal position
       
  1488      *           measured in pixels from the left of its container
       
  1489      * @param y  an integer giving the component's new vertical position,
       
  1490      *           measured in pixels from the bottom of its container
       
  1491      * @param width  an integer giving the component's new width in pixels
       
  1492      * @param height an integer giving the component's new height in pixels
       
  1493      */
       
  1494     public void reshape(int x, int y, int width, int height) {
       
  1495         super.reshape(x, y, width, height);
       
  1496         validate();
       
  1497         repaint();
       
  1498     }
       
  1499 
       
  1500 ///////////////////////////
       
  1501 // Frame/Window equivalents
       
  1502 ///////////////////////////
       
  1503 
       
  1504     /**
       
  1505      * Adds the specified listener to receive internal
       
  1506      * frame events from this internal frame.
       
  1507      *
       
  1508      * @param l the internal frame listener
       
  1509      */
       
  1510     public void addInternalFrameListener(InternalFrameListener l) {  // remind: sync ??
       
  1511       listenerList.add(InternalFrameListener.class, l);
       
  1512       // remind: needed?
       
  1513       enableEvents(0);   // turn on the newEventsOnly flag in Component.
       
  1514     }
       
  1515 
       
  1516     /**
       
  1517      * Removes the specified internal frame listener so that it no longer
       
  1518      * receives internal frame events from this internal frame.
       
  1519      *
       
  1520      * @param l the internal frame listener
       
  1521      */
       
  1522     public void removeInternalFrameListener(InternalFrameListener l) {  // remind: sync??
       
  1523       listenerList.remove(InternalFrameListener.class, l);
       
  1524     }
       
  1525 
       
  1526     /**
       
  1527      * Returns an array of all the <code>InternalFrameListener</code>s added
       
  1528      * to this <code>JInternalFrame</code> with
       
  1529      * <code>addInternalFrameListener</code>.
       
  1530      *
       
  1531      * @return all of the <code>InternalFrameListener</code>s added or an empty
       
  1532      *         array if no listeners have been added
       
  1533      * @since 1.4
       
  1534      *
       
  1535      * @see #addInternalFrameListener
       
  1536      */
       
  1537     public InternalFrameListener[] getInternalFrameListeners() {
       
  1538         return (InternalFrameListener[])listenerList.getListeners(
       
  1539                 InternalFrameListener.class);
       
  1540     }
       
  1541 
       
  1542     // remind: name ok? all one method ok? need to be synchronized?
       
  1543     /**
       
  1544      * Fires an internal frame event.
       
  1545      *
       
  1546      * @param id  the type of the event being fired; one of the following:
       
  1547      * <ul>
       
  1548      * <li><code>InternalFrameEvent.INTERNAL_FRAME_OPENED</code>
       
  1549      * <li><code>InternalFrameEvent.INTERNAL_FRAME_CLOSING</code>
       
  1550      * <li><code>InternalFrameEvent.INTERNAL_FRAME_CLOSED</code>
       
  1551      * <li><code>InternalFrameEvent.INTERNAL_FRAME_ICONIFIED</code>
       
  1552      * <li><code>InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED</code>
       
  1553      * <li><code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code>
       
  1554      * <li><code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code>
       
  1555      * </ul>
       
  1556      * If the event type is not one of the above, nothing happens.
       
  1557      */
       
  1558     protected void fireInternalFrameEvent(int id){
       
  1559       Object[] listeners = listenerList.getListenerList();
       
  1560       InternalFrameEvent e = null;
       
  1561       for (int i = listeners.length -2; i >=0; i -= 2){
       
  1562         if (listeners[i] == InternalFrameListener.class){
       
  1563           if (e == null){
       
  1564             e = new InternalFrameEvent(this, id);
       
  1565             //      System.out.println("InternalFrameEvent: " + e.paramString());
       
  1566           }
       
  1567           switch(e.getID()) {
       
  1568           case InternalFrameEvent.INTERNAL_FRAME_OPENED:
       
  1569             ((InternalFrameListener)listeners[i+1]).internalFrameOpened(e);
       
  1570             break;
       
  1571           case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
       
  1572             ((InternalFrameListener)listeners[i+1]).internalFrameClosing(e);
       
  1573             break;
       
  1574           case InternalFrameEvent.INTERNAL_FRAME_CLOSED:
       
  1575             ((InternalFrameListener)listeners[i+1]).internalFrameClosed(e);
       
  1576             break;
       
  1577           case InternalFrameEvent.INTERNAL_FRAME_ICONIFIED:
       
  1578             ((InternalFrameListener)listeners[i+1]).internalFrameIconified(e);
       
  1579             break;
       
  1580           case InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED:
       
  1581             ((InternalFrameListener)listeners[i+1]).internalFrameDeiconified(e);
       
  1582             break;
       
  1583           case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
       
  1584             ((InternalFrameListener)listeners[i+1]).internalFrameActivated(e);
       
  1585             break;
       
  1586           case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
       
  1587             ((InternalFrameListener)listeners[i+1]).internalFrameDeactivated(e);
       
  1588             break;
       
  1589           default:
       
  1590             break;
       
  1591           }
       
  1592         }
       
  1593       }
       
  1594       /* we could do it off the event, but at the moment, that's not how
       
  1595          I'm implementing it */
       
  1596       //      if (id == InternalFrameEvent.INTERNAL_FRAME_CLOSING) {
       
  1597       //          doDefaultCloseAction();
       
  1598       //      }
       
  1599     }
       
  1600 
       
  1601     /**
       
  1602      * Fires an
       
  1603      * <code>INTERNAL_FRAME_CLOSING</code> event
       
  1604      * and then performs the action specified by
       
  1605      * the internal frame's default close operation.
       
  1606      * This method is typically invoked by the
       
  1607      * look-and-feel-implemented action handler
       
  1608      * for the internal frame's close button.
       
  1609      *
       
  1610      * @since 1.3
       
  1611      * @see #setDefaultCloseOperation
       
  1612      * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSING
       
  1613      */
       
  1614     public void doDefaultCloseAction() {
       
  1615         fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
       
  1616         switch(defaultCloseOperation) {
       
  1617           case DO_NOTHING_ON_CLOSE:
       
  1618             break;
       
  1619           case HIDE_ON_CLOSE:
       
  1620             setVisible(false);
       
  1621             if (isSelected())
       
  1622                 try {
       
  1623                     setSelected(false);
       
  1624                 } catch (PropertyVetoException pve) {}
       
  1625 
       
  1626             /* should this activate the next frame? that's really
       
  1627                desktopmanager's policy... */
       
  1628             break;
       
  1629           case DISPOSE_ON_CLOSE:
       
  1630               try {
       
  1631                 fireVetoableChange(IS_CLOSED_PROPERTY, Boolean.FALSE,
       
  1632                                    Boolean.TRUE);
       
  1633                 isClosed = true;
       
  1634                 setVisible(false);
       
  1635                 firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE,
       
  1636                                    Boolean.TRUE);
       
  1637                 dispose();
       
  1638               } catch (PropertyVetoException pve) {}
       
  1639               break;
       
  1640           default:
       
  1641               break;
       
  1642         }
       
  1643     }
       
  1644 
       
  1645     /**
       
  1646      * Sets the operation that will happen by default when
       
  1647      * the user initiates a "close" on this internal frame.
       
  1648      * The possible choices are:
       
  1649      * <p>
       
  1650      * <dl>
       
  1651      * <dt><code>DO_NOTHING_ON_CLOSE</code>
       
  1652      * <dd> Do nothing.
       
  1653      *      This requires the program to handle the operation
       
  1654      *      in the <code>windowClosing</code> method
       
  1655      *      of a registered <code>InternalFrameListener</code> object.
       
  1656      * <dt><code>HIDE_ON_CLOSE</code>
       
  1657      * <dd> Automatically make the internal frame invisible.
       
  1658      * <dt><code>DISPOSE_ON_CLOSE</code>
       
  1659      * <dd> Automatically dispose of the internal frame.
       
  1660      * </dl>
       
  1661      * <p>
       
  1662      * The default value is <code>DISPOSE_ON_CLOSE</code>.
       
  1663      * Before performing the specified close operation,
       
  1664      * the internal frame fires
       
  1665      * an <code>INTERNAL_FRAME_CLOSING</code> event.
       
  1666      *
       
  1667      * @param operation one of the following constants defined in
       
  1668      *                  <code>javax.swing.WindowConstants</code>
       
  1669      *                  (an interface implemented by
       
  1670      *                  <code>JInternalFrame</code>):
       
  1671      *                  <code>DO_NOTHING_ON_CLOSE</code>,
       
  1672      *                  <code>HIDE_ON_CLOSE</code>, or
       
  1673      *                  <code>DISPOSE_ON_CLOSE</code>
       
  1674      *
       
  1675      * @see #addInternalFrameListener
       
  1676      * @see #getDefaultCloseOperation
       
  1677      * @see #setVisible
       
  1678      * @see #dispose
       
  1679      * @see InternalFrameEvent#INTERNAL_FRAME_CLOSING
       
  1680      */
       
  1681     public void setDefaultCloseOperation(int operation) {
       
  1682         this.defaultCloseOperation = operation;
       
  1683     }
       
  1684 
       
  1685    /**
       
  1686     * Returns the default operation that occurs when the user
       
  1687     * initiates a "close" on this internal frame.
       
  1688     * @return the operation that will occur when the user closes the internal
       
  1689     *         frame
       
  1690     * @see #setDefaultCloseOperation
       
  1691     */
       
  1692     public int getDefaultCloseOperation() {
       
  1693         return defaultCloseOperation;
       
  1694     }
       
  1695 
       
  1696     /**
       
  1697      * Causes subcomponents of this <code>JInternalFrame</code>
       
  1698      * to be laid out at their preferred size.  Internal frames that are
       
  1699      * iconized or maximized are first restored and then packed.  If the
       
  1700      * internal frame is unable to be restored its state is not changed
       
  1701      * and will not be packed.
       
  1702      *
       
  1703      * @see       java.awt.Window#pack
       
  1704      */
       
  1705     public void pack() {
       
  1706         try {
       
  1707             if (isIcon()) {
       
  1708                 setIcon(false);
       
  1709             } else if (isMaximum()) {
       
  1710                 setMaximum(false);
       
  1711             }
       
  1712         } catch(PropertyVetoException e) {
       
  1713             return;
       
  1714         }
       
  1715         setSize(getPreferredSize());
       
  1716         validate();
       
  1717     }
       
  1718 
       
  1719     /**
       
  1720      * If the internal frame is not visible,
       
  1721      * brings the internal frame to the front,
       
  1722      * makes it visible,
       
  1723      * and attempts to select it.
       
  1724      * The first time the internal frame is made visible,
       
  1725      * this method also fires an <code>INTERNAL_FRAME_OPENED</code> event.
       
  1726      * This method does nothing if the internal frame is already visible.
       
  1727      * Invoking this method
       
  1728      * has the same result as invoking
       
  1729      * <code>setVisible(true)</code>.
       
  1730      *
       
  1731      * @see #moveToFront
       
  1732      * @see #setSelected
       
  1733      * @see InternalFrameEvent#INTERNAL_FRAME_OPENED
       
  1734      * @see #setVisible
       
  1735      */
       
  1736     public void show() {
       
  1737         // bug 4312922
       
  1738         if (isVisible()) {
       
  1739             //match the behavior of setVisible(true): do nothing
       
  1740             return;
       
  1741         }
       
  1742 
       
  1743         // bug 4149505
       
  1744         if (!opened) {
       
  1745           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
       
  1746           opened = true;
       
  1747         }
       
  1748 
       
  1749         /* icon default visibility is false; set it to true so that it shows
       
  1750            up when user iconifies frame */
       
  1751         getDesktopIcon().setVisible(true);
       
  1752 
       
  1753         toFront();
       
  1754         super.show();
       
  1755 
       
  1756         if (isIcon) {
       
  1757             return;
       
  1758         }
       
  1759 
       
  1760         if (!isSelected()) {
       
  1761             try {
       
  1762                 setSelected(true);
       
  1763             } catch (PropertyVetoException pve) {}
       
  1764         }
       
  1765     }
       
  1766 
       
  1767     public void hide() {
       
  1768         if (isIcon()) {
       
  1769             getDesktopIcon().setVisible(false);
       
  1770         }
       
  1771         super.hide();
       
  1772     }
       
  1773 
       
  1774     /**
       
  1775      * Makes this internal frame
       
  1776      * invisible, unselected, and closed.
       
  1777      * If the frame is not already closed,
       
  1778      * this method fires an
       
  1779      * <code>INTERNAL_FRAME_CLOSED</code> event.
       
  1780      * The results of invoking this method are similar to
       
  1781      * <code>setClosed(true)</code>,
       
  1782      * but <code>dispose</code> always succeeds in closing
       
  1783      * the internal frame and does not fire
       
  1784      * an <code>INTERNAL_FRAME_CLOSING</code> event.
       
  1785      *
       
  1786      * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSED
       
  1787      * @see #setVisible
       
  1788      * @see #setSelected
       
  1789      * @see #setClosed
       
  1790      */
       
  1791     public void dispose() {
       
  1792         if (isVisible()) {
       
  1793             setVisible(false);
       
  1794         }
       
  1795         if (isSelected()) {
       
  1796             try {
       
  1797                 setSelected(false);
       
  1798             } catch (PropertyVetoException pve) {}
       
  1799         }
       
  1800         if (!isClosed) {
       
  1801           firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE, Boolean.TRUE);
       
  1802           isClosed = true;
       
  1803         }
       
  1804         fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
       
  1805     }
       
  1806 
       
  1807     /**
       
  1808      * Brings this internal frame to the front.
       
  1809      * Places this internal frame  at the top of the stacking order
       
  1810      * and makes the corresponding adjustment to other visible internal
       
  1811      * frames.
       
  1812      *
       
  1813      * @see       java.awt.Window#toFront
       
  1814      * @see       #moveToFront
       
  1815      */
       
  1816     public void toFront() {
       
  1817         moveToFront();
       
  1818     }
       
  1819 
       
  1820     /**
       
  1821      * Sends this internal frame to the back.
       
  1822      * Places this internal frame at the bottom of the stacking order
       
  1823      * and makes the corresponding adjustment to other visible
       
  1824      * internal frames.
       
  1825      *
       
  1826      * @see       java.awt.Window#toBack
       
  1827      * @see       #moveToBack
       
  1828      */
       
  1829     public void toBack() {
       
  1830         moveToBack();
       
  1831     }
       
  1832 
       
  1833     /**
       
  1834      * Does nothing because <code>JInternalFrame</code>s must always be roots of a focus
       
  1835      * traversal cycle.
       
  1836      *
       
  1837      * @param focusCycleRoot this value is ignored
       
  1838      * @see #isFocusCycleRoot
       
  1839      * @see java.awt.Container#setFocusTraversalPolicy
       
  1840      * @see java.awt.Container#getFocusTraversalPolicy
       
  1841      * @since 1.4
       
  1842      */
       
  1843     public final void setFocusCycleRoot(boolean focusCycleRoot) {
       
  1844     }
       
  1845 
       
  1846     /**
       
  1847      * Always returns <code>true</code> because all <code>JInternalFrame</code>s must be
       
  1848      * roots of a focus traversal cycle.
       
  1849      *
       
  1850      * @return <code>true</code>
       
  1851      * @see #setFocusCycleRoot
       
  1852      * @see java.awt.Container#setFocusTraversalPolicy
       
  1853      * @see java.awt.Container#getFocusTraversalPolicy
       
  1854      * @since 1.4
       
  1855      */
       
  1856     public final boolean isFocusCycleRoot() {
       
  1857         return true;
       
  1858     }
       
  1859 
       
  1860     /**
       
  1861      * Always returns <code>null</code> because <code>JInternalFrame</code>s
       
  1862      * must always be roots of a focus
       
  1863      * traversal cycle.
       
  1864      *
       
  1865      * @return <code>null</code>
       
  1866      * @see java.awt.Container#isFocusCycleRoot()
       
  1867      * @since 1.4
       
  1868      */
       
  1869     public final Container getFocusCycleRootAncestor() {
       
  1870         return null;
       
  1871     }
       
  1872 
       
  1873     /**
       
  1874      * Gets the warning string that is displayed with this internal frame.
       
  1875      * Since an internal frame is always secure (since it's fully
       
  1876      * contained within a window that might need a warning string)
       
  1877      * this method always returns <code>null</code>.
       
  1878      * @return    <code>null</code>
       
  1879      * @see       java.awt.Window#getWarningString
       
  1880      */
       
  1881     public final String getWarningString() {
       
  1882         return null;
       
  1883     }
       
  1884 
       
  1885     /**
       
  1886      * See <code>readObject</code> and <code>writeObject</code>
       
  1887      * in <code>JComponent</code> for more
       
  1888      * information about serialization in Swing.
       
  1889      */
       
  1890     private void writeObject(ObjectOutputStream s) throws IOException {
       
  1891         s.defaultWriteObject();
       
  1892         if (getUIClassID().equals(uiClassID)) {
       
  1893             byte count = JComponent.getWriteObjCounter(this);
       
  1894             JComponent.setWriteObjCounter(this, --count);
       
  1895             if (count == 0 && ui != null) {
       
  1896                 boolean old = isRootPaneCheckingEnabled();
       
  1897                 try {
       
  1898                     setRootPaneCheckingEnabled(false);
       
  1899                     ui.installUI(this);
       
  1900                 } finally {
       
  1901                     setRootPaneCheckingEnabled(old);
       
  1902                 }
       
  1903             }
       
  1904         }
       
  1905     }
       
  1906 
       
  1907     /* Called from the JComponent's EnableSerializationFocusListener to
       
  1908      * do any Swing-specific pre-serialization configuration.
       
  1909      */
       
  1910     void compWriteObjectNotify() {
       
  1911       // need to disable rootpane checking for InternalFrame: 4172083
       
  1912       boolean old = isRootPaneCheckingEnabled();
       
  1913       try {
       
  1914         setRootPaneCheckingEnabled(false);
       
  1915         super.compWriteObjectNotify();
       
  1916       }
       
  1917       finally {
       
  1918         setRootPaneCheckingEnabled(old);
       
  1919       }
       
  1920     }
       
  1921 
       
  1922     /**
       
  1923      * Returns a string representation of this <code>JInternalFrame</code>.
       
  1924      * This method
       
  1925      * is intended to be used only for debugging purposes, and the
       
  1926      * content and format of the returned string may vary between
       
  1927      * implementations. The returned string may be empty but may not
       
  1928      * be <code>null</code>.
       
  1929      *
       
  1930      * @return  a string representation of this <code>JInternalFrame</code>
       
  1931      */
       
  1932     protected String paramString() {
       
  1933         String rootPaneString = (rootPane != null ?
       
  1934                                  rootPane.toString() : "");
       
  1935         String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
       
  1936                                                 "true" : "false");
       
  1937         String closableString = (closable ? "true" : "false");
       
  1938         String isClosedString = (isClosed ? "true" : "false");
       
  1939         String maximizableString = (maximizable ? "true" : "false");
       
  1940         String isMaximumString = (isMaximum ? "true" : "false");
       
  1941         String iconableString = (iconable ? "true" : "false");
       
  1942         String isIconString = (isIcon ? "true" : "false");
       
  1943         String resizableString = (resizable ? "true" : "false");
       
  1944         String isSelectedString = (isSelected ? "true" : "false");
       
  1945         String frameIconString = (frameIcon != null ?
       
  1946                                   frameIcon.toString() : "");
       
  1947         String titleString = (title != null ?
       
  1948                               title : "");
       
  1949         String desktopIconString = (desktopIcon != null ?
       
  1950                                     desktopIcon.toString() : "");
       
  1951         String openedString = (opened ? "true" : "false");
       
  1952         String defaultCloseOperationString;
       
  1953         if (defaultCloseOperation == HIDE_ON_CLOSE) {
       
  1954             defaultCloseOperationString = "HIDE_ON_CLOSE";
       
  1955         } else if (defaultCloseOperation == DISPOSE_ON_CLOSE) {
       
  1956             defaultCloseOperationString = "DISPOSE_ON_CLOSE";
       
  1957         } else if (defaultCloseOperation == DO_NOTHING_ON_CLOSE) {
       
  1958             defaultCloseOperationString = "DO_NOTHING_ON_CLOSE";
       
  1959         } else defaultCloseOperationString = "";
       
  1960 
       
  1961         return super.paramString() +
       
  1962         ",closable=" + closableString +
       
  1963         ",defaultCloseOperation=" + defaultCloseOperationString +
       
  1964         ",desktopIcon=" + desktopIconString +
       
  1965         ",frameIcon=" + frameIconString +
       
  1966         ",iconable=" + iconableString +
       
  1967         ",isClosed=" + isClosedString +
       
  1968         ",isIcon=" + isIconString +
       
  1969         ",isMaximum=" + isMaximumString +
       
  1970         ",isSelected=" + isSelectedString +
       
  1971         ",maximizable=" + maximizableString +
       
  1972         ",opened=" + openedString +
       
  1973         ",resizable=" + resizableString +
       
  1974         ",rootPane=" + rootPaneString +
       
  1975         ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString +
       
  1976         ",title=" + titleString;
       
  1977     }
       
  1978 
       
  1979     // ======= begin optimized frame dragging defence code ==============
       
  1980 
       
  1981     boolean isDragging = false;
       
  1982     boolean danger = false;
       
  1983 
       
  1984     /**
       
  1985      * Overridden to allow optimized painting when the
       
  1986      * internal frame is being dragged.
       
  1987      */
       
  1988     protected void paintComponent(Graphics g) {
       
  1989       if (isDragging) {
       
  1990         //         System.out.println("ouch");
       
  1991          danger = true;
       
  1992       }
       
  1993 
       
  1994       super.paintComponent(g);
       
  1995    }
       
  1996 
       
  1997     // ======= end optimized frame dragging defence code ==============
       
  1998 
       
  1999 /////////////////
       
  2000 // Accessibility support
       
  2001 ////////////////
       
  2002 
       
  2003     /**
       
  2004      * Gets the <code>AccessibleContext</code> associated with this
       
  2005      * <code>JInternalFrame</code>.
       
  2006      * For internal frames, the <code>AccessibleContext</code>
       
  2007      * takes the form of an
       
  2008      * <code>AccessibleJInternalFrame</code> object.
       
  2009      * A new <code>AccessibleJInternalFrame</code> instance is created if necessary.
       
  2010      *
       
  2011      * @return an <code>AccessibleJInternalFrame</code> that serves as the
       
  2012      *         <code>AccessibleContext</code> of this
       
  2013      *         <code>JInternalFrame</code>
       
  2014      * @see AccessibleJInternalFrame
       
  2015      */
       
  2016     public AccessibleContext getAccessibleContext() {
       
  2017         if (accessibleContext == null) {
       
  2018             accessibleContext = new AccessibleJInternalFrame();
       
  2019         }
       
  2020         return accessibleContext;
       
  2021     }
       
  2022 
       
  2023     /**
       
  2024      * This class implements accessibility support for the
       
  2025      * <code>JInternalFrame</code> class.  It provides an implementation of the
       
  2026      * Java Accessibility API appropriate to internal frame user-interface
       
  2027      * elements.
       
  2028      * <p>
       
  2029      * <strong>Warning:</strong>
       
  2030      * Serialized objects of this class will not be compatible with
       
  2031      * future Swing releases. The current serialization support is
       
  2032      * appropriate for short term storage or RMI between applications running
       
  2033      * the same version of Swing.  As of 1.4, support for long term storage
       
  2034      * of all JavaBeans<sup><font size="-2">TM</font></sup>
       
  2035      * has been added to the <code>java.beans</code> package.
       
  2036      * Please see {@link java.beans.XMLEncoder}.
       
  2037      */
       
  2038     protected class AccessibleJInternalFrame extends AccessibleJComponent
       
  2039         implements AccessibleValue {
       
  2040 
       
  2041         /**
       
  2042          * Get the accessible name of this object.
       
  2043          *
       
  2044          * @return the localized name of the object -- can be <code>null</code> if this
       
  2045          * object does not have a name
       
  2046          * @see #setAccessibleName
       
  2047          */
       
  2048         public String getAccessibleName() {
       
  2049             String name = accessibleName;
       
  2050 
       
  2051             if (name == null) {
       
  2052                 name = (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
       
  2053             }
       
  2054             if (name == null) {
       
  2055                 name = getTitle();
       
  2056             }
       
  2057             return name;
       
  2058         }
       
  2059 
       
  2060         /**
       
  2061          * Get the role of this object.
       
  2062          *
       
  2063          * @return an instance of AccessibleRole describing the role of the
       
  2064          * object
       
  2065          * @see AccessibleRole
       
  2066          */
       
  2067         public AccessibleRole getAccessibleRole() {
       
  2068             return AccessibleRole.INTERNAL_FRAME;
       
  2069         }
       
  2070 
       
  2071         /**
       
  2072          * Gets the AccessibleValue associated with this object.  In the
       
  2073          * implementation of the Java Accessibility API for this class,
       
  2074          * returns this object, which is responsible for implementing the
       
  2075          * <code>AccessibleValue</code> interface on behalf of itself.
       
  2076          *
       
  2077          * @return this object
       
  2078          */
       
  2079         public AccessibleValue getAccessibleValue() {
       
  2080             return this;
       
  2081         }
       
  2082 
       
  2083 
       
  2084         //
       
  2085         // AccessibleValue methods
       
  2086         //
       
  2087 
       
  2088         /**
       
  2089          * Get the value of this object as a Number.
       
  2090          *
       
  2091          * @return value of the object -- can be <code>null</code> if this object does not
       
  2092          * have a value
       
  2093          */
       
  2094         public Number getCurrentAccessibleValue() {
       
  2095             return new Integer(getLayer());
       
  2096         }
       
  2097 
       
  2098         /**
       
  2099          * Set the value of this object as a Number.
       
  2100          *
       
  2101          * @return <code>true</code> if the value was set
       
  2102          */
       
  2103         public boolean setCurrentAccessibleValue(Number n) {
       
  2104             // TIGER - 4422535
       
  2105             if (n == null) {
       
  2106                 return false;
       
  2107             }
       
  2108             setLayer(new Integer(n.intValue()));
       
  2109             return true;
       
  2110         }
       
  2111 
       
  2112         /**
       
  2113          * Get the minimum value of this object as a Number.
       
  2114          *
       
  2115          * @return Minimum value of the object; <code>null</code> if this object does not
       
  2116          * have a minimum value
       
  2117          */
       
  2118         public Number getMinimumAccessibleValue() {
       
  2119             return new Integer(Integer.MIN_VALUE);
       
  2120         }
       
  2121 
       
  2122         /**
       
  2123          * Get the maximum value of this object as a Number.
       
  2124          *
       
  2125          * @return Maximum value of the object; <code>null</code> if this object does not
       
  2126          * have a maximum value
       
  2127          */
       
  2128         public Number getMaximumAccessibleValue() {
       
  2129             return new Integer(Integer.MAX_VALUE);
       
  2130         }
       
  2131 
       
  2132     } // AccessibleJInternalFrame
       
  2133 
       
  2134     /**
       
  2135      * This component represents an iconified version of a
       
  2136      * <code>JInternalFrame</code>.
       
  2137      * This API should NOT BE USED by Swing applications, as it will go
       
  2138      * away in future versions of Swing as its functionality is moved into
       
  2139      * <code>JInternalFrame</code>.  This class is public only so that
       
  2140      * UI objects can display a desktop icon.  If an application
       
  2141      * wants to display a desktop icon, it should create a
       
  2142      * <code>JInternalFrame</code> instance and iconify it.
       
  2143      * <p>
       
  2144      * <strong>Warning:</strong>
       
  2145      * Serialized objects of this class will not be compatible with
       
  2146      * future Swing releases. The current serialization support is
       
  2147      * appropriate for short term storage or RMI between applications running
       
  2148      * the same version of Swing.  As of 1.4, support for long term storage
       
  2149      * of all JavaBeans<sup><font size="-2">TM</font></sup>
       
  2150      * has been added to the <code>java.beans</code> package.
       
  2151      * Please see {@link java.beans.XMLEncoder}.
       
  2152      *
       
  2153      * @author David Kloba
       
  2154      */
       
  2155     static public class JDesktopIcon extends JComponent implements Accessible
       
  2156     {
       
  2157         JInternalFrame internalFrame;
       
  2158 
       
  2159         /**
       
  2160          * Creates an icon for an internal frame.
       
  2161          *
       
  2162          * @param f  the <code>JInternalFrame</code>
       
  2163          *              for which the icon is created
       
  2164          */
       
  2165         public JDesktopIcon(JInternalFrame f) {
       
  2166             setVisible(false);
       
  2167             setInternalFrame(f);
       
  2168             updateUI();
       
  2169         }
       
  2170 
       
  2171         /**
       
  2172          * Returns the look-and-feel object that renders this component.
       
  2173          *
       
  2174          * @return the <code>DesktopIconUI</code> object that renders
       
  2175          *              this component
       
  2176          */
       
  2177         public DesktopIconUI getUI() {
       
  2178             return (DesktopIconUI)ui;
       
  2179         }
       
  2180 
       
  2181         /**
       
  2182          * Sets the look-and-feel object that renders this component.
       
  2183          *
       
  2184          * @param ui  the <code>DesktopIconUI</code> look-and-feel object
       
  2185          * @see UIDefaults#getUI
       
  2186          */
       
  2187         public void setUI(DesktopIconUI ui) {
       
  2188             super.setUI(ui);
       
  2189         }
       
  2190 
       
  2191         /**
       
  2192          * Returns the <code>JInternalFrame</code> that this
       
  2193          * <code>DesktopIcon</code> is associated with.
       
  2194          *
       
  2195          * @return the <code>JInternalFrame</code> with which this icon
       
  2196          *              is associated
       
  2197          */
       
  2198         public JInternalFrame getInternalFrame() {
       
  2199             return internalFrame;
       
  2200         }
       
  2201 
       
  2202         /**
       
  2203          * Sets the <code>JInternalFrame</code> with which this
       
  2204          * <code>DesktopIcon</code> is associated.
       
  2205          *
       
  2206          * @param f  the <code>JInternalFrame</code> with which this icon
       
  2207          *              is associated
       
  2208          */
       
  2209         public void setInternalFrame(JInternalFrame f) {
       
  2210             internalFrame = f;
       
  2211         }
       
  2212 
       
  2213         /**
       
  2214          * Convenience method to ask the icon for the <code>Desktop</code>
       
  2215          * object it belongs to.
       
  2216          *
       
  2217          * @return the <code>JDesktopPane</code> that contains this
       
  2218          *           icon's internal frame, or <code>null</code> if none found
       
  2219          */
       
  2220         public JDesktopPane getDesktopPane() {
       
  2221             if(getInternalFrame() != null)
       
  2222                 return getInternalFrame().getDesktopPane();
       
  2223             return null;
       
  2224         }
       
  2225 
       
  2226         /**
       
  2227          * Notification from the <code>UIManager</code> that the look and feel
       
  2228          * has changed.
       
  2229          * Replaces the current UI object with the latest version from the
       
  2230          * <code>UIManager</code>.
       
  2231          *
       
  2232          * @see JComponent#updateUI
       
  2233          */
       
  2234         public void updateUI() {
       
  2235             boolean hadUI = (ui != null);
       
  2236             setUI((DesktopIconUI)UIManager.getUI(this));
       
  2237             invalidate();
       
  2238 
       
  2239             Dimension r = getPreferredSize();
       
  2240             setSize(r.width, r.height);
       
  2241 
       
  2242 
       
  2243             if (internalFrame != null && internalFrame.getUI() != null) {  // don't do this if UI not created yet
       
  2244                 SwingUtilities.updateComponentTreeUI(internalFrame);
       
  2245             }
       
  2246         }
       
  2247 
       
  2248         /* This method is called if updateUI was called on the associated
       
  2249          * JInternalFrame.  It's necessary to avoid infinite recursion.
       
  2250          */
       
  2251         void updateUIWhenHidden() {
       
  2252             /* Update this UI and any associated internal frame */
       
  2253             setUI((DesktopIconUI)UIManager.getUI(this));
       
  2254 
       
  2255             Dimension r = getPreferredSize();
       
  2256             setSize(r.width, r.height);
       
  2257 
       
  2258             invalidate();
       
  2259             Component[] children = getComponents();
       
  2260             if (children != null) {
       
  2261                 for(int i = 0; i < children.length; i++) {
       
  2262                     SwingUtilities.updateComponentTreeUI(children[i]);
       
  2263                 }
       
  2264             }
       
  2265         }
       
  2266 
       
  2267         /**
       
  2268          * Returns the name of the look-and-feel
       
  2269          * class that renders this component.
       
  2270          *
       
  2271          * @return the string "DesktopIconUI"
       
  2272          * @see JComponent#getUIClassID
       
  2273          * @see UIDefaults#getUI
       
  2274          */
       
  2275         public String getUIClassID() {
       
  2276             return "DesktopIconUI";
       
  2277         }
       
  2278         ////////////////
       
  2279         // Serialization support
       
  2280         ////////////////
       
  2281         private void writeObject(ObjectOutputStream s) throws IOException {
       
  2282             s.defaultWriteObject();
       
  2283             if (getUIClassID().equals("DesktopIconUI")) {
       
  2284                 byte count = JComponent.getWriteObjCounter(this);
       
  2285                 JComponent.setWriteObjCounter(this, --count);
       
  2286                 if (count == 0 && ui != null) {
       
  2287                     ui.installUI(this);
       
  2288                 }
       
  2289             }
       
  2290         }
       
  2291 
       
  2292        /////////////////
       
  2293        // Accessibility support
       
  2294        ////////////////
       
  2295 
       
  2296         /**
       
  2297          * Gets the AccessibleContext associated with this JDesktopIcon.
       
  2298          * For desktop icons, the AccessibleContext takes the form of an
       
  2299          * AccessibleJDesktopIcon.
       
  2300          * A new AccessibleJDesktopIcon instance is created if necessary.
       
  2301          *
       
  2302          * @return an AccessibleJDesktopIcon that serves as the
       
  2303          *         AccessibleContext of this JDesktopIcon
       
  2304          */
       
  2305         public AccessibleContext getAccessibleContext() {
       
  2306             if (accessibleContext == null) {
       
  2307                 accessibleContext = new AccessibleJDesktopIcon();
       
  2308             }
       
  2309             return accessibleContext;
       
  2310         }
       
  2311 
       
  2312         /**
       
  2313          * This class implements accessibility support for the
       
  2314          * <code>JInternalFrame.JDesktopIcon</code> class.  It provides an
       
  2315          * implementation of the Java Accessibility API appropriate to
       
  2316          * desktop icon user-interface elements.
       
  2317          * <p>
       
  2318          * <strong>Warning:</strong>
       
  2319          * Serialized objects of this class will not be compatible with
       
  2320          * future Swing releases. The current serialization support is
       
  2321          * appropriate for short term storage or RMI between applications running
       
  2322          * the same version of Swing.  As of 1.4, support for long term storage
       
  2323          * of all JavaBeans<sup><font size="-2">TM</font></sup>
       
  2324          * has been added to the <code>java.beans</code> package.
       
  2325          * Please see {@link java.beans.XMLEncoder}.
       
  2326          */
       
  2327         protected class AccessibleJDesktopIcon extends AccessibleJComponent
       
  2328             implements AccessibleValue {
       
  2329 
       
  2330             /**
       
  2331              * Gets the role of this object.
       
  2332              *
       
  2333              * @return an instance of AccessibleRole describing the role of the
       
  2334              * object
       
  2335              * @see AccessibleRole
       
  2336              */
       
  2337             public AccessibleRole getAccessibleRole() {
       
  2338                 return AccessibleRole.DESKTOP_ICON;
       
  2339             }
       
  2340 
       
  2341             /**
       
  2342              * Gets the AccessibleValue associated with this object.  In the
       
  2343              * implementation of the Java Accessibility API for this class,
       
  2344              * returns this object, which is responsible for implementing the
       
  2345              * <code>AccessibleValue</code> interface on behalf of itself.
       
  2346              *
       
  2347              * @return this object
       
  2348              */
       
  2349             public AccessibleValue getAccessibleValue() {
       
  2350                 return this;
       
  2351             }
       
  2352 
       
  2353             //
       
  2354             // AccessibleValue methods
       
  2355             //
       
  2356 
       
  2357             /**
       
  2358              * Gets the value of this object as a <code>Number</code>.
       
  2359              *
       
  2360              * @return value of the object -- can be <code>null</code> if this object does not
       
  2361              * have a value
       
  2362              */
       
  2363             public Number getCurrentAccessibleValue() {
       
  2364                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
       
  2365                 AccessibleValue v = a.getAccessibleValue();
       
  2366                 if (v != null) {
       
  2367                     return v.getCurrentAccessibleValue();
       
  2368                 } else {
       
  2369                     return null;
       
  2370                 }
       
  2371             }
       
  2372 
       
  2373             /**
       
  2374              * Sets the value of this object as a <code>Number</code>.
       
  2375              *
       
  2376              * @return <code>true</code> if the value was set
       
  2377              */
       
  2378             public boolean setCurrentAccessibleValue(Number n) {
       
  2379                 // TIGER - 4422535
       
  2380                 if (n == null) {
       
  2381                     return false;
       
  2382                 }
       
  2383                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
       
  2384                 AccessibleValue v = a.getAccessibleValue();
       
  2385                 if (v != null) {
       
  2386                     return v.setCurrentAccessibleValue(n);
       
  2387                 } else {
       
  2388                     return false;
       
  2389                 }
       
  2390             }
       
  2391 
       
  2392             /**
       
  2393              * Gets the minimum value of this object as a <code>Number</code>.
       
  2394              *
       
  2395              * @return minimum value of the object; <code>null</code> if this object does not
       
  2396              * have a minimum value
       
  2397              */
       
  2398             public Number getMinimumAccessibleValue() {
       
  2399                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
       
  2400                 if (a instanceof AccessibleValue) {
       
  2401                     return ((AccessibleValue)a).getMinimumAccessibleValue();
       
  2402                 } else {
       
  2403                     return null;
       
  2404                 }
       
  2405             }
       
  2406 
       
  2407             /**
       
  2408              * Gets the maximum value of this object as a <code>Number</code>.
       
  2409              *
       
  2410              * @return maximum value of the object; <code>null</code> if this object does not
       
  2411              * have a maximum value
       
  2412              */
       
  2413             public Number getMaximumAccessibleValue() {
       
  2414                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
       
  2415                 if (a instanceof AccessibleValue) {
       
  2416                     return ((AccessibleValue)a).getMaximumAccessibleValue();
       
  2417                 } else {
       
  2418                     return null;
       
  2419                 }
       
  2420             }
       
  2421 
       
  2422         } // AccessibleJDesktopIcon
       
  2423     }
       
  2424 }