/*
 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javax.swing;

import java.awt.*;

import java.beans.PropertyVetoException;
import java.beans.PropertyChangeEvent;

import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.plaf.*;

import javax.accessibility.*;

import java.io.ObjectOutputStream;
import java.io.IOException;
import java.lang.StringBuilder;
import java.beans.PropertyChangeListener;
import sun.awt.AppContext;
import sun.swing.SwingUtilities2;


/**
 * A lightweight object that provides many of the features of
 * a native frame, including dragging, closing, becoming an icon,
 * resizing, title display, and support for a menu bar.
 * For task-oriented documentation and examples of using internal frames,
 * see <a
 href="http://java.sun.com/docs/books/tutorial/uiswing/components/internalframe.html" target="_top">How to Use Internal Frames</a>,
 * a section in <em>The Java Tutorial</em>.
 *
 * <p>
 *
 * Generally,
 * you add <code>JInternalFrame</code>s to a <code>JDesktopPane</code>. The UI
 * delegates the look-and-feel-specific actions to the
 * <code>DesktopManager</code>
 * object maintained by the <code>JDesktopPane</code>.
 * <p>
 * The <code>JInternalFrame</code> content pane
 * is where you add child components.
 * As a conveniance <code>add</code> and its variants, <code>remove</code> and
 * <code>setLayout</code> have been overridden to forward to the
 * <code>contentPane</code> as necessary. This means you can write:
 * <pre>
 *       internalFrame.add(child);
 * </pre>
 * And the child will be added to the contentPane.
 * The content pane is actually managed by an instance of
 * <code>JRootPane</code>,
 * which also manages a layout pane, glass pane, and
 * optional menu bar for the internal frame. Please see the
 * <code>JRootPane</code>
 * documentation for a complete description of these components.
 * Refer to {@link javax.swing.RootPaneContainer}
 * for details on adding, removing and setting the <code>LayoutManager</code>
 * of a <code>JInternalFrame</code>.
 * <p>
 * <strong>Warning:</strong> Swing is not thread safe. For more
 * information see <a
 * href="package-summary.html#threading">Swing's Threading
 * Policy</a>.
 * <p>
 * <strong>Warning:</strong>
 * Serialized objects of this class will not be compatible with
 * future Swing releases. The current serialization support is
 * appropriate for short term storage or RMI between applications running
 * the same version of Swing.  As of 1.4, support for long term storage
 * of all JavaBeans<sup><font size="-2">TM</font></sup>
 * has been added to the <code>java.beans</code> package.
 * Please see {@link java.beans.XMLEncoder}.
 *
 * @see InternalFrameEvent
 * @see JDesktopPane
 * @see DesktopManager
 * @see JInternalFrame.JDesktopIcon
 * @see JRootPane
 * @see javax.swing.RootPaneContainer
 *
 * @author David Kloba
 * @author Rich Schiavi
 * @beaninfo
 *      attribute: isContainer true
 *      attribute: containerDelegate getContentPane
 *      description: A frame container which is contained within
 *                   another window.
 */
public class JInternalFrame extends JComponent implements
        Accessible, WindowConstants,
        RootPaneContainer
{
    /**
     * @see #getUIClassID
     * @see #readObject
     */
    private static final String uiClassID = "InternalFrameUI";

    /**
     * The <code>JRootPane</code> instance that manages the
     * content pane
     * and optional menu bar for this internal frame, as well as the
     * glass pane.
     *
     * @see JRootPane
     * @see RootPaneContainer
     */
    protected JRootPane rootPane;

    /**
     * If true then calls to <code>add</code> and <code>setLayout</code>
     * will be forwarded to the <code>contentPane</code>. This is initially
     * false, but is set to true when the <code>JInternalFrame</code> is
     * constructed.
     *
     * @see #isRootPaneCheckingEnabled
     * @see #setRootPaneCheckingEnabled
     * @see javax.swing.RootPaneContainer
     */
    protected boolean rootPaneCheckingEnabled = false;

    /** The frame can be closed. */
    protected boolean closable;
    /** The frame has been closed. */
    protected boolean isClosed;
    /** The frame can be expanded to the size of the desktop pane. */
    protected boolean maximizable;
    /**
     * The frame has been expanded to its maximum size.
     * @see #maximizable
     */
    protected boolean isMaximum;
    /**
     * The frame can "iconified" (shrunk down and displayed as
     * an icon-image).
     * @see JInternalFrame.JDesktopIcon
     * @see #setIconifiable
     */
    protected boolean iconable;
    /**
     * The frame has been iconified.
     * @see #isIcon()
     */
    protected boolean isIcon;
    /** The frame's size can be changed. */
    protected boolean resizable;
    /** The frame is currently selected. */
    protected boolean isSelected;
    /** The icon shown in the top-left corner of this internal frame. */
    protected Icon frameIcon;
    /** The title displayed in this internal frame's title bar. */
    protected String  title;
    /**
     * The icon that is displayed when this internal frame is iconified.
     * @see #iconable
     */
    protected JDesktopIcon desktopIcon;

    private Cursor lastCursor;

    private boolean opened;

    private Rectangle normalBounds = null;

    private int defaultCloseOperation = DISPOSE_ON_CLOSE;

    /**
     * Contains the Component that focus is to go when
     * <code>restoreSubcomponentFocus</code> is invoked, that is,
     * <code>restoreSubcomponentFocus</code> sets this to the value returned
     * from <code>getMostRecentFocusOwner</code>.
     */
    private Component lastFocusOwner;

    /** Bound property name. */
    public final static String CONTENT_PANE_PROPERTY = "contentPane";
    /** Bound property name. */
    public final static String MENU_BAR_PROPERTY = "JMenuBar";
    /** Bound property name. */
    public final static String TITLE_PROPERTY = "title";
    /** Bound property name. */
    public final static String LAYERED_PANE_PROPERTY = "layeredPane";
    /** Bound property name. */
    public final static String ROOT_PANE_PROPERTY = "rootPane";
    /** Bound property name. */
    public final static String GLASS_PANE_PROPERTY = "glassPane";
    /** Bound property name. */
    public final static String FRAME_ICON_PROPERTY = "frameIcon";

    /**
     * Constrained property name indicated that this frame has
     * selected status.
     */
    public final static String IS_SELECTED_PROPERTY = "selected";
    /** Constrained property name indicating that the internal frame is closed. */
    public final static String IS_CLOSED_PROPERTY = "closed";
    /** Constrained property name indicating that the internal frame is maximized. */
    public final static String IS_MAXIMUM_PROPERTY = "maximum";
    /** Constrained property name indicating that the internal frame is iconified. */
    public final static String IS_ICON_PROPERTY = "icon";

    private static final Object PROPERTY_CHANGE_LISTENER_KEY =
        new StringBuilder("InternalFramePropertyChangeListener");

    private static void addPropertyChangeListenerIfNecessary() {
        if (AppContext.getAppContext().get(PROPERTY_CHANGE_LISTENER_KEY) ==
            null) {
            PropertyChangeListener focusListener =
                new FocusPropertyChangeListener();

            AppContext.getAppContext().put(PROPERTY_CHANGE_LISTENER_KEY,
                focusListener);

            KeyboardFocusManager.getCurrentKeyboardFocusManager().
                addPropertyChangeListener(focusListener);
        }
    }

    private static class FocusPropertyChangeListener implements
        PropertyChangeListener {
        public void propertyChange(PropertyChangeEvent e) {
            if (e.getPropertyName() == "permanentFocusOwner") {
                updateLastFocusOwner((Component)e.getNewValue());
            }
        }
    }

    private static void updateLastFocusOwner(Component component) {
        if (component != null) {
            Component parent = component;
            while (parent != null && !(parent instanceof Window)) {
                if (parent instanceof JInternalFrame) {
                    // Update lastFocusOwner for parent.
                    ((JInternalFrame)parent).setLastFocusOwner(component);
                }
                parent = parent.getParent();
            }
        }
    }

    /**
     * Creates a non-resizable, non-closable, non-maximizable,
     * non-iconifiable <code>JInternalFrame</code> with no title.
     */
    public JInternalFrame() {
        this("", false, false, false, false);
    }

    /**
     * Creates a non-resizable, non-closable, non-maximizable,
     * non-iconifiable <code>JInternalFrame</code> with the specified title.
     * Note that passing in a <code>null</code> <code>title</code> results in
     * unspecified behavior and possibly an exception.
     *
     * @param title  the non-<code>null</code> <code>String</code>
     *     to display in the title bar
     */
    public JInternalFrame(String title) {
        this(title, false, false, false, false);
    }

    /**
     * Creates a non-closable, non-maximizable, non-iconifiable
     * <code>JInternalFrame</code> with the specified title
     * and resizability.
     *
     * @param title      the <code>String</code> to display in the title bar
     * @param resizable  if <code>true</code>, the internal frame can be resized
     */
    public JInternalFrame(String title, boolean resizable) {
        this(title, resizable, false, false, false);
    }

    /**
     * Creates a non-maximizable, non-iconifiable <code>JInternalFrame</code>
     * with the specified title, resizability, and
     * closability.
     *
     * @param title      the <code>String</code> to display in the title bar
     * @param resizable  if <code>true</code>, the internal frame can be resized
     * @param closable   if <code>true</code>, the internal frame can be closed
     */
    public JInternalFrame(String title, boolean resizable, boolean closable) {
        this(title, resizable, closable, false, false);
    }

    /**
     * Creates a non-iconifiable <code>JInternalFrame</code>
     * with the specified title,
     * resizability, closability, and maximizability.
     *
     * @param title       the <code>String</code> to display in the title bar
     * @param resizable   if <code>true</code>, the internal frame can be resized
     * @param closable    if <code>true</code>, the internal frame can be closed
     * @param maximizable if <code>true</code>, the internal frame can be maximized
     */
    public JInternalFrame(String title, boolean resizable, boolean closable,
                          boolean maximizable) {
        this(title, resizable, closable, maximizable, false);
    }

    /**
     * Creates a <code>JInternalFrame</code> with the specified title,
     * resizability, closability, maximizability, and iconifiability.
     * All <code>JInternalFrame</code> constructors use this one.
     *
     * @param title       the <code>String</code> to display in the title bar
     * @param resizable   if <code>true</code>, the internal frame can be resized
     * @param closable    if <code>true</code>, the internal frame can be closed
     * @param maximizable if <code>true</code>, the internal frame can be maximized
     * @param iconifiable if <code>true</code>, the internal frame can be iconified
     */
    public JInternalFrame(String title, boolean resizable, boolean closable,
                                boolean maximizable, boolean iconifiable) {

        setRootPane(createRootPane());
        setLayout(new BorderLayout());
        this.title = title;
        this.resizable = resizable;
        this.closable = closable;
        this.maximizable = maximizable;
        isMaximum = false;
        this.iconable = iconifiable;
        isIcon = false;
        setVisible(false);
        setRootPaneCheckingEnabled(true);
        desktopIcon = new JDesktopIcon(this);
        updateUI();
        sun.awt.SunToolkit.checkAndSetPolicy(this, true);
        addPropertyChangeListenerIfNecessary();
    }

    /**
     * Called by the constructor to set up the <code>JRootPane</code>.
     * @return  a new <code>JRootPane</code>
     * @see JRootPane
     */
    protected JRootPane createRootPane() {
        return new JRootPane();
    }

    /**
     * Returns the look-and-feel object that renders this component.
     *
     * @return the <code>InternalFrameUI</code> object that renders
     *          this component
     */
    public InternalFrameUI getUI() {
        return (InternalFrameUI)ui;
    }

    /**
     * Sets the UI delegate for this <code>JInternalFrame</code>.
     * @param ui  the UI delegate
     * @beaninfo
     *        bound: true
     *       hidden: true
     *    attribute: visualUpdate true
     *  description: The UI object that implements the Component's LookAndFeel.
     */
    public void setUI(InternalFrameUI ui) {
        boolean checkingEnabled = isRootPaneCheckingEnabled();
        try {
            setRootPaneCheckingEnabled(false);
            super.setUI(ui);
        }
        finally {
            setRootPaneCheckingEnabled(checkingEnabled);
        }
    }

    /**
     * Notification from the <code>UIManager</code> that the look and feel
     * has changed.
     * Replaces the current UI object with the latest version from the
     * <code>UIManager</code>.
     *
     * @see JComponent#updateUI
     */
    public void updateUI() {
        setUI((InternalFrameUI)UIManager.getUI(this));
        invalidate();
        if (desktopIcon != null) {
            desktopIcon.updateUIWhenHidden();
        }
    }

    /* This method is called if <code>updateUI</code> was called
     * on the associated
     * JDesktopIcon.  It's necessary to avoid infinite recursion.
     */
    void updateUIWhenHidden() {
        setUI((InternalFrameUI)UIManager.getUI(this));
        invalidate();
        Component[] children = getComponents();
        if (children != null) {
            for (Component child : children) {
                SwingUtilities.updateComponentTreeUI(child);
            }
        }
    }


    /**
     * Returns the name of the look-and-feel
     * class that renders this component.
     *
     * @return the string "InternalFrameUI"
     *
     * @see JComponent#getUIClassID
     * @see UIDefaults#getUI
     *
     * @beaninfo
     *     description: UIClassID
     */
    public String getUIClassID() {
        return uiClassID;
    }

    /**
     * Returns whether calls to <code>add</code> and
     * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
     *
     * @return true if <code>add</code> and <code>setLayout</code>
     *         are fowarded; false otherwise
     *
     * @see #addImpl
     * @see #setLayout
     * @see #setRootPaneCheckingEnabled
     * @see javax.swing.RootPaneContainer
     */
    protected boolean isRootPaneCheckingEnabled() {
        return rootPaneCheckingEnabled;
    }

    /**
     * Sets whether calls to <code>add</code> and
     * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
     *
     * @param enabled  true if <code>add</code> and <code>setLayout</code>
     *        are forwarded, false if they should operate directly on the
     *        <code>JInternalFrame</code>.
     *
     * @see #addImpl
     * @see #setLayout
     * @see #isRootPaneCheckingEnabled
     * @see javax.swing.RootPaneContainer
     * @beaninfo
     *      hidden: true
     * description: Whether the add and setLayout methods are forwarded
     */
    protected void setRootPaneCheckingEnabled(boolean enabled) {
        rootPaneCheckingEnabled = enabled;
    }

    /**
     * Adds the specified child <code>Component</code>.
     * This method is overridden to conditionally forward calls to the
     * <code>contentPane</code>.
     * By default, children are added to the <code>contentPane</code> instead
     * of the frame, refer to {@link javax.swing.RootPaneContainer} for
     * details.
     *
     * @param comp the component to be enhanced
     * @param constraints the constraints to be respected
     * @param index the index
     * @exception IllegalArgumentException if <code>index</code> is invalid
     * @exception IllegalArgumentException if adding the container's parent
     *                  to itself
     * @exception IllegalArgumentException if adding a window to a container
     *
     * @see #setRootPaneCheckingEnabled
     * @see javax.swing.RootPaneContainer
     */
    protected void addImpl(Component comp, Object constraints, int index) {
        if(isRootPaneCheckingEnabled()) {
            getContentPane().add(comp, constraints, index);
        }
        else {
            super.addImpl(comp, constraints, index);
        }
    }

    /**
     * Removes the specified component from the container. If
     * <code>comp</code> is not a child of the <code>JInternalFrame</code>
     * this will forward the call to the <code>contentPane</code>.
     *
     * @param comp the component to be removed
     * @throws NullPointerException if <code>comp</code> is null
     * @see #add
     * @see javax.swing.RootPaneContainer
     */
    public void remove(Component comp) {
        int oldCount = getComponentCount();
        super.remove(comp);
        if (oldCount == getComponentCount()) {
            getContentPane().remove(comp);
        }
    }


    /**
     * Ensures that, by default, the layout of this component cannot be set.
     * Overridden to conditionally forward the call to the
     * <code>contentPane</code>.
     * Refer to {@link javax.swing.RootPaneContainer} for
     * more information.
     *
     * @param manager the <code>LayoutManager</code>
     * @see #setRootPaneCheckingEnabled
     */
    public void setLayout(LayoutManager manager) {
        if(isRootPaneCheckingEnabled()) {
            getContentPane().setLayout(manager);
        }
        else {
            super.setLayout(manager);
        }
    }


//////////////////////////////////////////////////////////////////////////
/// Property Methods
//////////////////////////////////////////////////////////////////////////

    /**
     * Returns the current <code>JMenuBar</code> for this
     * <code>JInternalFrame</code>, or <code>null</code>
     * if no menu bar has been set.
     * @return the current menu bar, or <code>null</code> if none has been set
     *
     * @deprecated As of Swing version 1.0.3,
     * replaced by <code>getJMenuBar()</code>.
     */
    @Deprecated
    public JMenuBar getMenuBar() {
      return getRootPane().getMenuBar();
    }

    /**
     * Returns the current <code>JMenuBar</code> for this
     * <code>JInternalFrame</code>, or <code>null</code>
     * if no menu bar has been set.
     *
     * @return  the <code>JMenuBar</code> used by this internal frame
     * @see #setJMenuBar
     */
    public JMenuBar getJMenuBar() {
        return getRootPane().getJMenuBar();
    }

    /**
     * Sets the <code>menuBar</code> property for this <code>JInternalFrame</code>.
     *
     * @param m  the <code>JMenuBar</code> to use in this internal frame
     * @see #getJMenuBar
     * @deprecated As of Swing version 1.0.3
     *  replaced by <code>setJMenuBar(JMenuBar m)</code>.
     */
    @Deprecated
    public void setMenuBar(JMenuBar m) {
        JMenuBar oldValue = getMenuBar();
        getRootPane().setJMenuBar(m);
        firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
    }

    /**
     * Sets the <code>menuBar</code> property for this <code>JInternalFrame</code>.
     *
     * @param m  the <code>JMenuBar</code> to use in this internal frame
     * @see #getJMenuBar
     * @beaninfo
     *     bound: true
     *     preferred: true
     *     description: The menu bar for accessing pulldown menus
     *                  from this internal frame.
     */
    public void setJMenuBar(JMenuBar m){
        JMenuBar oldValue = getMenuBar();
        getRootPane().setJMenuBar(m);
        firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
    }

    // implements javax.swing.RootPaneContainer
    /**
     * Returns the content pane for this internal frame.
     * @return the content pane
     */
    public Container getContentPane() {
        return getRootPane().getContentPane();
    }


    /**
     * Sets this <code>JInternalFrame</code>'s <code>contentPane</code>
     * property.
     *
     * @param c  the content pane for this internal frame
     *
     * @exception java.awt.IllegalComponentStateException (a runtime
     *           exception) if the content pane parameter is <code>null</code>
     * @see RootPaneContainer#getContentPane
     * @beaninfo
     *     bound: true
     *     hidden: true
     *     description: The client area of the internal frame where child
     *                  components are normally inserted.
     */
    public void setContentPane(Container c) {
        Container oldValue = getContentPane();
        getRootPane().setContentPane(c);
        firePropertyChange(CONTENT_PANE_PROPERTY, oldValue, c);
    }

    /**
     * Returns the layered pane for this internal frame.
     *
     * @return a <code>JLayeredPane</code> object
     * @see RootPaneContainer#setLayeredPane
     * @see RootPaneContainer#getLayeredPane
     */
    public JLayeredPane getLayeredPane() {
        return getRootPane().getLayeredPane();
    }

    /**
     * Sets this <code>JInternalFrame</code>'s
     * <code>layeredPane</code> property.
     *
     * @param layered the <code>JLayeredPane</code> for this internal frame
     *
     * @exception java.awt.IllegalComponentStateException (a runtime
     *           exception) if the layered pane parameter is <code>null</code>
     * @see RootPaneContainer#setLayeredPane
     * @beaninfo
     *     hidden: true
     *     bound: true
     *     description: The pane which holds the various desktop layers.
     */
    public void setLayeredPane(JLayeredPane layered) {
        JLayeredPane oldValue = getLayeredPane();
        getRootPane().setLayeredPane(layered);
        firePropertyChange(LAYERED_PANE_PROPERTY, oldValue, layered);
    }

    /**
     * Returns the glass pane for this internal frame.
     *
     * @return the glass pane
     * @see RootPaneContainer#setGlassPane
     */
    public Component getGlassPane() {
        return getRootPane().getGlassPane();
    }

    /**
     * Sets this <code>JInternalFrame</code>'s
     * <code>glassPane</code> property.
     *
     * @param glass the glass pane for this internal frame
     * @see RootPaneContainer#getGlassPane
     * @beaninfo
     *     bound: true
     *     hidden: true
     *     description: A transparent pane used for menu rendering.
     */
    public void setGlassPane(Component glass) {
        Component oldValue = getGlassPane();
        getRootPane().setGlassPane(glass);
        firePropertyChange(GLASS_PANE_PROPERTY, oldValue, glass);
    }

    /**
     * Returns the <code>rootPane</code> object for this internal frame.
     *
     * @return the <code>rootPane</code> property
     * @see RootPaneContainer#getRootPane
     */
    public JRootPane getRootPane() {
        return rootPane;
    }


    /**
     * Sets the <code>rootPane</code> property
     * for this <code>JInternalFrame</code>.
     * This method is called by the constructor.
     *
     * @param root  the new <code>JRootPane</code> object
     * @beaninfo
     *     bound: true
     *     hidden: true
     *     description: The root pane used by this internal frame.
     */
    protected void setRootPane(JRootPane root) {
        if(rootPane != null) {
            remove(rootPane);
        }
        JRootPane oldValue = getRootPane();
        rootPane = root;
        if(rootPane != null) {
            boolean checkingEnabled = isRootPaneCheckingEnabled();
            try {
                setRootPaneCheckingEnabled(false);
                add(rootPane, BorderLayout.CENTER);
            }
            finally {
                setRootPaneCheckingEnabled(checkingEnabled);
            }
        }
        firePropertyChange(ROOT_PANE_PROPERTY, oldValue, root);
    }

    /**
     * Sets whether this <code>JInternalFrame</code> can be closed by
     * some user action.
     * @param b a boolean value, where <code>true</code> means this internal frame can be closed
     * @beaninfo
     *     preferred: true
     *           bound: true
     *     description: Indicates whether this internal frame can be closed.
     */
    public void setClosable(boolean b) {
        Boolean oldValue = closable ? Boolean.TRUE : Boolean.FALSE;
        Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
        closable = b;
        firePropertyChange("closable", oldValue, newValue);
    }

    /**
     * Returns whether this <code>JInternalFrame</code> can be closed by
     * some user action.
     * @return <code>true</code> if this internal frame can be closed
     */
    public boolean isClosable() {
        return closable;
    }

    /**
     * Returns whether this <code>JInternalFrame</code> is currently closed.
     * @return <code>true</code> if this internal frame is closed, <code>false</code> otherwise
     */
    public boolean isClosed() {
        return isClosed;
    }

    /**
     * Closes this internal frame if the argument is <code>true</code>.
     * Do not invoke this method with a <code>false</code> argument;
     * the result of invoking <code>setClosed(false)</code>
     * is unspecified.
     *
     * <p>
     *
     * If the internal frame is already closed,
     * this method does nothing and returns immediately.
     * Otherwise,
     * this method begins by firing
     * an <code>INTERNAL_FRAME_CLOSING</code> event.
     * Then this method sets the <code>closed</code> property to <code>true</code>
     * unless a listener vetoes the property change.
     * This method finishes by making the internal frame
     * invisible and unselected,
     * and then firing an <code>INTERNAL_FRAME_CLOSED</code> event.
     *
     * <p>
     *
     * <b>Note:</b>
     * To reuse an internal frame that has been closed,
     * you must add it to a container
     * (even if you never removed it from its previous container).
     * Typically, this container will be the <code>JDesktopPane</code>
     * that previously contained the internal frame.
     *
     * @param b must be <code>true</code>
     *
     * @exception PropertyVetoException when the attempt to set the
     *            property is vetoed by the <code>JInternalFrame</code>
     *
     * @see #isClosed()
     * @see #setDefaultCloseOperation
     * @see #dispose
     * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSING
     *
     * @beaninfo
     *           bound: true
     *     constrained: true
     *     description: Indicates whether this internal frame has been closed.
     */
    public void setClosed(boolean b) throws PropertyVetoException {
        if (isClosed == b) {
            return;
        }

        Boolean oldValue = isClosed ? Boolean.TRUE : Boolean.FALSE;
        Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
        if (b) {
          fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
        }
        fireVetoableChange(IS_CLOSED_PROPERTY, oldValue, newValue);
        isClosed = b;
        if (isClosed) {
          setVisible(false);
        }
        firePropertyChange(IS_CLOSED_PROPERTY, oldValue, newValue);
        if (isClosed) {
          dispose();
        } else if (!opened) {
          /* this bogus -- we haven't defined what
             setClosed(false) means. */
          //        fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
          //            opened = true;
        }
    }

    /**
     * Sets whether the <code>JInternalFrame</code> can be resized by some
     * user action.
     *
     * @param b  a boolean, where <code>true</code> means this internal frame can be resized
     * @beaninfo
     *     preferred: true
     *           bound: true
     *     description: Determines whether this internal frame can be resized
     *                  by the user.
     */
    public void setResizable(boolean b) {
        Boolean oldValue = resizable ? Boolean.TRUE : Boolean.FALSE;
        Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
        resizable = b;
        firePropertyChange("resizable", oldValue, newValue);
    }

    /**
     * Returns whether the <code>JInternalFrame</code> can be resized
     * by some user action.
     *
     * @return <code>true</code> if this internal frame can be resized, <code>false</code> otherwise
     */
    public boolean isResizable() {
        // don't allow resizing when maximized.
        return isMaximum ? false : resizable;
    }

    /**
     * Sets the <code>iconable</code> property,
     * which must be <code>true</code>
     * for the user to be able to
     * make the <code>JInternalFrame</code> an icon.
     * Some look and feels might not implement iconification;
     * they will ignore this property.
     *
     * @param b  a boolean, where <code>true</code> means this internal frame can be iconified
     * @beaninfo
     *     preferred: true
               bound: true
     *     description: Determines whether this internal frame can be iconified.
     */
    public void setIconifiable(boolean b) {
        Boolean oldValue = iconable ? Boolean.TRUE : Boolean.FALSE;
        Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
        iconable = b;
        firePropertyChange("iconable", oldValue, newValue);
    }

    /**
     * Gets the <code>iconable</code> property,
     * which by default is <code>false</code>.
     *
     * @return the value of the <code>iconable</code> property.
     *
     * @see #setIconifiable
     */
    public boolean isIconifiable() {
        return iconable;
    }

    /**
     * Returns whether the <code>JInternalFrame</code> is currently iconified.
     *
     * @return <code>true</code> if this internal frame is iconified
     */
    public boolean isIcon() {
        return isIcon;
    }

    /**
     * Iconifies or de-iconifies this internal frame,
     * if the look and feel supports iconification.
     * If the internal frame's state changes to iconified,
     * this method fires an <code>INTERNAL_FRAME_ICONIFIED</code> event.
     * If the state changes to de-iconified,
     * an <code>INTERNAL_FRAME_DEICONIFIED</code> event is fired.
     *
     * @param b a boolean, where <code>true</code> means to iconify this internal frame and
     *          <code>false</code> means to de-iconify it
     * @exception PropertyVetoException when the attempt to set the
     *            property is vetoed by the <code>JInternalFrame</code>
     *
     * @see InternalFrameEvent#INTERNAL_FRAME_ICONIFIED
     * @see InternalFrameEvent#INTERNAL_FRAME_DEICONIFIED
     *
     * @beaninfo
     *           bound: true
     *     constrained: true
     *     description: The image displayed when this internal frame is minimized.
     */
    public void setIcon(boolean b) throws PropertyVetoException {
        if (isIcon == b) {
            return;
        }

        /* If an internal frame is being iconified before it has a
           parent, (e.g., client wants it to start iconic), create the
           parent if possible so that we can place the icon in its
           proper place on the desktop. I am not sure the call to
           validate() is necessary, since we are not going to display
           this frame yet */
        firePropertyChange("ancestor", null, getParent());

        Boolean oldValue = isIcon ? Boolean.TRUE : Boolean.FALSE;
        Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
        fireVetoableChange(IS_ICON_PROPERTY, oldValue, newValue);
        isIcon = b;
        firePropertyChange(IS_ICON_PROPERTY, oldValue, newValue);
        if (b)
          fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
        else
          fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
    }

    /**
     * Sets the <code>maximizable</code> property,
     * which determines whether the <code>JInternalFrame</code>
     * can be maximized by
     * some user action.
     * Some look and feels might not support maximizing internal frames;
     * they will ignore this property.
     *
     * @param b <code>true</code> to specify that this internal frame should be maximizable; <code>false</code> to specify that it should not be
     * @beaninfo
     *         bound: true
     *     preferred: true
     *     description: Determines whether this internal frame can be maximized.
     */
    public void setMaximizable(boolean b) {
        Boolean oldValue = maximizable ? Boolean.TRUE : Boolean.FALSE;
        Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
        maximizable = b;
        firePropertyChange("maximizable", oldValue, newValue);
    }

    /**
     * Gets the value of the <code>maximizable</code> property.
     *
     * @return the value of the <code>maximizable</code> property
     * @see #setMaximizable
     */
    public boolean isMaximizable() {
        return maximizable;
    }

    /**
     * Returns whether the <code>JInternalFrame</code> is currently maximized.
     *
     * @return <code>true</code> if this internal frame is maximized, <code>false</code> otherwise
     */
    public boolean isMaximum() {
        return isMaximum;
    }

    /**
     * Maximizes and restores this internal frame.  A maximized frame is resized to
     * fully fit the <code>JDesktopPane</code> area associated with the
     * <code>JInternalFrame</code>.
     * A restored frame's size is set to the <code>JInternalFrame</code>'s
     * actual size.
     *
     * @param b  a boolean, where <code>true</code> maximizes this internal frame and <code>false</code>
     *           restores it
     * @exception PropertyVetoException when the attempt to set the
     *            property is vetoed by the <code>JInternalFrame</code>
     * @beaninfo
     *     bound: true
     *     constrained: true
     *     description: Indicates whether this internal frame is maximized.
     */
    public void setMaximum(boolean b) throws PropertyVetoException {
        if (isMaximum == b) {
            return;
        }

        Boolean oldValue = isMaximum ? Boolean.TRUE : Boolean.FALSE;
        Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
        fireVetoableChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
        /* setting isMaximum above the event firing means that
           property listeners that, for some reason, test it will
           get it wrong... See, for example, getNormalBounds() */
        isMaximum = b;
        firePropertyChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
    }

    /**
     * Returns the title of the <code>JInternalFrame</code>.
     *
     * @return a <code>String</code> containing this internal frame's title
     * @see #setTitle
     */
    public String getTitle() {
        return title;
    }

    /**
     * Sets the <code>JInternalFrame</code> title. <code>title</code>
     * may have a <code>null</code> value.
     * @see #getTitle
     *
     * @param title  the <code>String</code> to display in the title bar
     * @beaninfo
     *     preferred: true
     *     bound: true
     *     description: The text displayed in the title bar.
     */
    public void setTitle(String title) {
        String oldValue = this.title;
        this.title = title;
        firePropertyChange(TITLE_PROPERTY, oldValue, title);
    }

    /**
     * Selects or deselects the internal frame
     * if it's showing.
     * A <code>JInternalFrame</code> normally draws its title bar
     * differently if it is
     * the selected frame, which indicates to the user that this
     * internal frame has the focus.
     * When this method changes the state of the internal frame
     * from deselected to selected, it fires an
     * <code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code> event.
     * If the change is from selected to deselected,
     * an <code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code> event
     * is fired.
     *
     * @param selected  a boolean, where <code>true</code> means this internal frame
     *                  should become selected (currently active)
     *                  and <code>false</code> means it should become deselected
     * @exception PropertyVetoException when the attempt to set the
     *            property is vetoed by the <code>JInternalFrame</code>
     *
     * @see #isShowing
     * @see InternalFrameEvent#INTERNAL_FRAME_ACTIVATED
     * @see InternalFrameEvent#INTERNAL_FRAME_DEACTIVATED
     *
     * @beaninfo
     *     constrained: true
     *           bound: true
     *     description: Indicates whether this internal frame is currently
     *                  the active frame.
     */
    public void setSelected(boolean selected) throws PropertyVetoException {
       // The InternalFrame may already be selected, but the focus
       // may be outside it, so restore the focus to the subcomponent
       // which previously had it. See Bug 4302764.
        if (selected && isSelected) {
            restoreSubcomponentFocus();
            return;
        }
        // The internal frame or the desktop icon must be showing to allow
        // selection.  We may deselect even if neither is showing.
        if ((isSelected == selected) || (selected &&
            (isIcon ? !desktopIcon.isShowing() : !isShowing()))) {
            return;
        }

        Boolean oldValue = isSelected ? Boolean.TRUE : Boolean.FALSE;
        Boolean newValue = selected ? Boolean.TRUE : Boolean.FALSE;
        fireVetoableChange(IS_SELECTED_PROPERTY, oldValue, newValue);

        /* We don't want to leave focus in the previously selected
           frame, so we have to set it to *something* in case it
           doesn't get set in some other way (as if a user clicked on
           a component that doesn't request focus).  If this call is
           happening because the user clicked on a component that will
           want focus, then it will get transfered there later.

           We test for parent.isShowing() above, because AWT throws a
           NPE if you try to request focus on a lightweight before its
           parent has been made visible */

        if (selected) {
            restoreSubcomponentFocus();
        }

        isSelected = selected;
        firePropertyChange(IS_SELECTED_PROPERTY, oldValue, newValue);
        if (isSelected)
          fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED);
        else
          fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
        repaint();
    }

    /**
     * Returns whether the <code>JInternalFrame</code> is the
     * currently "selected" or active frame.
     *
     * @return <code>true</code> if this internal frame is currently selected (active)
     * @see #setSelected
     */
    public boolean isSelected() {
        return isSelected;
    }

    /**
     * Sets an image to be displayed in the titlebar of this internal frame (usually
     * in the top-left corner).
     * This image is not the <code>desktopIcon</code> object, which
     * is the image displayed in the <code>JDesktop</code> when
     * this internal frame is iconified.
     *
     * Passing <code>null</code> to this function is valid,
     * but the look and feel
     * can choose the
     * appropriate behavior for that situation, such as displaying no icon
     * or a default icon for the look and feel.
     *
     * @param icon the <code>Icon</code> to display in the title bar
     * @see #getFrameIcon
     * @beaninfo
     *           bound: true
     *     description: The icon shown in the top-left corner of this internal frame.
     */
  public void setFrameIcon(Icon icon) {
        Icon oldIcon = frameIcon;
        frameIcon = icon;
        firePropertyChange(FRAME_ICON_PROPERTY, oldIcon, icon);
    }

    /**
     * Returns the image displayed in the title bar of this internal frame (usually
     * in the top-left corner).
     *
     * @return the <code>Icon</code> displayed in the title bar
     * @see #setFrameIcon
     */
    public Icon getFrameIcon()  {
        return frameIcon;
    }

    /**
      * Convenience method that moves this component to position 0 if its
      * parent is a <code>JLayeredPane</code>.
      */
    public void moveToFront() {
        if (isIcon()) {
            if (getDesktopIcon().getParent() instanceof JLayeredPane) {
                ((JLayeredPane)getDesktopIcon().getParent()).
                    moveToFront(getDesktopIcon());
            }
        }
        else if (getParent() instanceof JLayeredPane) {
            ((JLayeredPane)getParent()).moveToFront(this);
        }
    }

    /**
      * Convenience method that moves this component to position -1 if its
      * parent is a <code>JLayeredPane</code>.
      */
    public void moveToBack() {
        if (isIcon()) {
            if (getDesktopIcon().getParent() instanceof JLayeredPane) {
                ((JLayeredPane)getDesktopIcon().getParent()).
                    moveToBack(getDesktopIcon());
            }
        }
        else if (getParent() instanceof JLayeredPane) {
            ((JLayeredPane)getParent()).moveToBack(this);
        }
    }

    /**
     * Returns the last <code>Cursor</code> that was set by the
     * <code>setCursor</code> method that is not a resizable
     * <code>Cursor</code>.
     *
     * @return the last non-resizable <code>Cursor</code>
     * @since 1.6
     */
    public Cursor getLastCursor() {
        return lastCursor;
    }

    /**
     * {@inheritDoc}
     * @since 1.6
     */
    public void setCursor(Cursor cursor) {
        if (cursor == null) {
            lastCursor = null;
            super.setCursor(cursor);
            return;
        }
        int type = cursor.getType();
        if (!(type == Cursor.SW_RESIZE_CURSOR  ||
              type == Cursor.SE_RESIZE_CURSOR  ||
              type == Cursor.NW_RESIZE_CURSOR  ||
              type == Cursor.NE_RESIZE_CURSOR  ||
              type == Cursor.N_RESIZE_CURSOR   ||
              type == Cursor.S_RESIZE_CURSOR   ||
              type == Cursor.W_RESIZE_CURSOR   ||
              type == Cursor.E_RESIZE_CURSOR)) {
            lastCursor = cursor;
        }
        super.setCursor(cursor);
    }

    /**
     * Convenience method for setting the layer attribute of this component.
     *
     * @param layer  an <code>Integer</code> object specifying this
     *          frame's desktop layer
     * @see JLayeredPane
     * @beaninfo
     *     expert: true
     *     description: Specifies what desktop layer is used.
     */
    public void setLayer(Integer layer) {
        if(getParent() != null && getParent() instanceof JLayeredPane) {
            // Normally we want to do this, as it causes the LayeredPane
            // to draw properly.
            JLayeredPane p = (JLayeredPane)getParent();
            p.setLayer(this, layer.intValue(), p.getPosition(this));
        } else {
             // Try to do the right thing
             JLayeredPane.putLayer(this, layer.intValue());
             if(getParent() != null)
                 getParent().repaint(getX(), getY(), getWidth(), getHeight());
        }
    }

    /**
     * Convenience method for setting the layer attribute of this component.
     * The method <code>setLayer(Integer)</code> should be used for
     * layer values predefined in <code>JLayeredPane</code>.
     * When using <code>setLayer(int)</code>, care must be taken not to
     * accidentally clash with those values.
     *
     * @param layer  an integer specifying this internal frame's desktop layer
     *
     * @since 1.3
     *
     * @see #setLayer(Integer)
     * @see JLayeredPane
     * @beaninfo
     *     expert: true
     *     description: Specifies what desktop layer is used.
     */
    public void setLayer(int layer) {
      this.setLayer(Integer.valueOf(layer));
    }

    /**
     * Convenience method for getting the layer attribute of this component.
     *
     * @return  an <code>Integer</code> object specifying this
     *          frame's desktop layer
     * @see JLayeredPane
      */
    public int getLayer() {
        return JLayeredPane.getLayer(this);
    }

    /**
      * Convenience method that searches the ancestor hierarchy for a
      * <code>JDesktop</code> instance. If <code>JInternalFrame</code>
      * finds none, the <code>desktopIcon</code> tree is searched.
      *
      * @return the <code>JDesktopPane</code> this internal frame belongs to,
      *         or <code>null</code> if none is found
      */
    public JDesktopPane getDesktopPane() {
        Container p;

        // Search upward for desktop
        p = getParent();
        while(p != null && !(p instanceof JDesktopPane))
            p = p.getParent();

        if(p == null) {
           // search its icon parent for desktop
           p = getDesktopIcon().getParent();
           while(p != null && !(p instanceof JDesktopPane))
                p = p.getParent();
        }

        return (JDesktopPane)p;
    }

    /**
     * Sets the <code>JDesktopIcon</code> associated with this
     * <code>JInternalFrame</code>.
     *
     * @param d the <code>JDesktopIcon</code> to display on the desktop
     * @see #getDesktopIcon
     * @beaninfo
     *           bound: true
     *     description: The icon shown when this internal frame is minimized.
     */
    public void setDesktopIcon(JDesktopIcon d) {
        JDesktopIcon oldValue = getDesktopIcon();
        desktopIcon = d;
        firePropertyChange("desktopIcon", oldValue, d);
    }

    /**
     * Returns the <code>JDesktopIcon</code> used when this
     * <code>JInternalFrame</code> is iconified.
     *
     * @return the <code>JDesktopIcon</code> displayed on the desktop
     * @see #setDesktopIcon
     */
    public JDesktopIcon getDesktopIcon() {
        return desktopIcon;
    }

    /**
     * If the <code>JInternalFrame</code> is not in maximized state, returns
     * <code>getBounds()</code>; otherwise, returns the bounds that the
     * <code>JInternalFrame</code> would be restored to.
     *
     * @return a <code>Rectangle</code> containing the bounds of this
     *          frame when in the normal state
     * @since 1.3
     */
    public Rectangle getNormalBounds() {

      /* we used to test (!isMaximum) here, but since this
         method is used by the property listener for the
         IS_MAXIMUM_PROPERTY, it ended up getting the wrong
         answer... Since normalBounds get set to null when the
         frame is restored, this should work better */

      if (normalBounds != null) {
        return normalBounds;
      } else {
        return getBounds();
      }
    }

    /**
     * Sets the normal bounds for this internal frame, the bounds that
     * this internal frame would be restored to from its maximized state.
     * This method is intended for use only by desktop managers.
     *
     * @param r the bounds that this internal frame should be restored to
     * @since 1.3
     */
    public void setNormalBounds(Rectangle r) {
        normalBounds = r;
    }

    /**
     * If this <code>JInternalFrame</code> is active,
     * returns the child that has focus.
     * Otherwise, returns <code>null</code>.
     *
     * @return the component with focus, or <code>null</code> if no children have focus
     * @since 1.3
     */
    public Component getFocusOwner() {
        if (isSelected()) {
            return lastFocusOwner;
        }
        return null;
    }

    /**
     * Returns the child component of this <code>JInternalFrame</code>
     * that will receive the
     * focus when this <code>JInternalFrame</code> is selected.
     * If this <code>JInternalFrame</code> is
     * currently selected, this method returns the same component as
     * the <code>getFocusOwner</code> method.
     * If this <code>JInternalFrame</code> is not selected,
     * then the child component that most recently requested focus will be
     * returned. If no child component has ever requested focus, then this
     * <code>JInternalFrame</code>'s initial focusable component is returned.
     * If no such
     * child exists, then this <code>JInternalFrame</code>'s default component
     * to focus is returned.
     *
     * @return the child component that will receive focus when this
     *         <code>JInternalFrame</code> is selected
     * @see #getFocusOwner
     * @see #isSelected
     * @since 1.4
     */
    public Component getMostRecentFocusOwner() {
        if (isSelected()) {
            return getFocusOwner();
        }

        if (lastFocusOwner != null) {
            return lastFocusOwner;
        }

        FocusTraversalPolicy policy = getFocusTraversalPolicy();
        if (policy instanceof InternalFrameFocusTraversalPolicy) {
            return ((InternalFrameFocusTraversalPolicy)policy).
                getInitialComponent(this);
        }

        Component toFocus = policy.getDefaultComponent(this);
        if (toFocus != null) {
            return toFocus;
        }
        return getContentPane();
    }

    /**
     * Requests the internal frame to restore focus to the
     * last subcomponent that had focus. This is used by the UI when
     * the user selected this internal frame --
     * for example, by clicking on the title bar.
     *
     * @since 1.3
     */
    public void restoreSubcomponentFocus() {
        if (isIcon()) {
            SwingUtilities2.compositeRequestFocus(getDesktopIcon());
        }
        else {
            Component component = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
            if ((component == null) || !SwingUtilities.isDescendingFrom(component, this)) {
                // FocusPropertyChangeListener will eventually update
                // lastFocusOwner. As focus requests are asynchronous
                // lastFocusOwner may be accessed before it has been correctly
                // updated. To avoid any problems, lastFocusOwner is immediately
                // set, assuming the request will succeed.
                setLastFocusOwner(getMostRecentFocusOwner());
                if (lastFocusOwner == null) {
                    // Make sure focus is restored somewhere, so that
                    // we don't leave a focused component in another frame while
                    // this frame is selected.
                    setLastFocusOwner(getContentPane());
                }
                lastFocusOwner.requestFocus();
            }
        }
    }

    private void setLastFocusOwner(Component component) {
        lastFocusOwner = component;
    }

    /**
     * Moves and resizes this component.  Unlike other components,
     * this implementation also forces re-layout, so that frame
     * decorations such as the title bar are always redisplayed.
     *
     * @param x  an integer giving the component's new horizontal position
     *           measured in pixels from the left of its container
     * @param y  an integer giving the component's new vertical position,
     *           measured in pixels from the bottom of its container
     * @param width  an integer giving the component's new width in pixels
     * @param height an integer giving the component's new height in pixels
     */
    public void reshape(int x, int y, int width, int height) {
        super.reshape(x, y, width, height);
        validate();
        repaint();
    }

///////////////////////////
// Frame/Window equivalents
///////////////////////////

    /**
     * Adds the specified listener to receive internal
     * frame events from this internal frame.
     *
     * @param l the internal frame listener
     */
    public void addInternalFrameListener(InternalFrameListener l) {  // remind: sync ??
      listenerList.add(InternalFrameListener.class, l);
      // remind: needed?
      enableEvents(0);   // turn on the newEventsOnly flag in Component.
    }

    /**
     * Removes the specified internal frame listener so that it no longer
     * receives internal frame events from this internal frame.
     *
     * @param l the internal frame listener
     */
    public void removeInternalFrameListener(InternalFrameListener l) {  // remind: sync??
      listenerList.remove(InternalFrameListener.class, l);
    }

    /**
     * Returns an array of all the <code>InternalFrameListener</code>s added
     * to this <code>JInternalFrame</code> with
     * <code>addInternalFrameListener</code>.
     *
     * @return all of the <code>InternalFrameListener</code>s added or an empty
     *         array if no listeners have been added
     * @since 1.4
     *
     * @see #addInternalFrameListener
     */
    public InternalFrameListener[] getInternalFrameListeners() {
        return listenerList.getListeners(InternalFrameListener.class);
    }

    // remind: name ok? all one method ok? need to be synchronized?
    /**
     * Fires an internal frame event.
     *
     * @param id  the type of the event being fired; one of the following:
     * <ul>
     * <li><code>InternalFrameEvent.INTERNAL_FRAME_OPENED</code>
     * <li><code>InternalFrameEvent.INTERNAL_FRAME_CLOSING</code>
     * <li><code>InternalFrameEvent.INTERNAL_FRAME_CLOSED</code>
     * <li><code>InternalFrameEvent.INTERNAL_FRAME_ICONIFIED</code>
     * <li><code>InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED</code>
     * <li><code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code>
     * <li><code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code>
     * </ul>
     * If the event type is not one of the above, nothing happens.
     */
    protected void fireInternalFrameEvent(int id){
      Object[] listeners = listenerList.getListenerList();
      InternalFrameEvent e = null;
      for (int i = listeners.length -2; i >=0; i -= 2){
        if (listeners[i] == InternalFrameListener.class){
          if (e == null){
            e = new InternalFrameEvent(this, id);
            //      System.out.println("InternalFrameEvent: " + e.paramString());
          }
          switch(e.getID()) {
          case InternalFrameEvent.INTERNAL_FRAME_OPENED:
            ((InternalFrameListener)listeners[i+1]).internalFrameOpened(e);
            break;
          case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
            ((InternalFrameListener)listeners[i+1]).internalFrameClosing(e);
            break;
          case InternalFrameEvent.INTERNAL_FRAME_CLOSED:
            ((InternalFrameListener)listeners[i+1]).internalFrameClosed(e);
            break;
          case InternalFrameEvent.INTERNAL_FRAME_ICONIFIED:
            ((InternalFrameListener)listeners[i+1]).internalFrameIconified(e);
            break;
          case InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED:
            ((InternalFrameListener)listeners[i+1]).internalFrameDeiconified(e);
            break;
          case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
            ((InternalFrameListener)listeners[i+1]).internalFrameActivated(e);
            break;
          case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
            ((InternalFrameListener)listeners[i+1]).internalFrameDeactivated(e);
            break;
          default:
            break;
          }
        }
      }
      /* we could do it off the event, but at the moment, that's not how
         I'm implementing it */
      //      if (id == InternalFrameEvent.INTERNAL_FRAME_CLOSING) {
      //          doDefaultCloseAction();
      //      }
    }

    /**
     * Fires an
     * <code>INTERNAL_FRAME_CLOSING</code> event
     * and then performs the action specified by
     * the internal frame's default close operation.
     * This method is typically invoked by the
     * look-and-feel-implemented action handler
     * for the internal frame's close button.
     *
     * @since 1.3
     * @see #setDefaultCloseOperation
     * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSING
     */
    public void doDefaultCloseAction() {
        fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
        switch(defaultCloseOperation) {
          case DO_NOTHING_ON_CLOSE:
            break;
          case HIDE_ON_CLOSE:
            setVisible(false);
            if (isSelected())
                try {
                    setSelected(false);
                } catch (PropertyVetoException pve) {}

            /* should this activate the next frame? that's really
               desktopmanager's policy... */
            break;
          case DISPOSE_ON_CLOSE:
              try {
                fireVetoableChange(IS_CLOSED_PROPERTY, Boolean.FALSE,
                                   Boolean.TRUE);
                isClosed = true;
                setVisible(false);
                firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE,
                                   Boolean.TRUE);
                dispose();
              } catch (PropertyVetoException pve) {}
              break;
          default:
              break;
        }
    }

    /**
     * Sets the operation that will happen by default when
     * the user initiates a "close" on this internal frame.
     * The possible choices are:
     * <p>
     * <dl>
     * <dt><code>DO_NOTHING_ON_CLOSE</code>
     * <dd> Do nothing.
     *      This requires the program to handle the operation
     *      in the <code>windowClosing</code> method
     *      of a registered <code>InternalFrameListener</code> object.
     * <dt><code>HIDE_ON_CLOSE</code>
     * <dd> Automatically make the internal frame invisible.
     * <dt><code>DISPOSE_ON_CLOSE</code>
     * <dd> Automatically dispose of the internal frame.
     * </dl>
     * <p>
     * The default value is <code>DISPOSE_ON_CLOSE</code>.
     * Before performing the specified close operation,
     * the internal frame fires
     * an <code>INTERNAL_FRAME_CLOSING</code> event.
     *
     * @param operation one of the following constants defined in
     *                  <code>javax.swing.WindowConstants</code>
     *                  (an interface implemented by
     *                  <code>JInternalFrame</code>):
     *                  <code>DO_NOTHING_ON_CLOSE</code>,
     *                  <code>HIDE_ON_CLOSE</code>, or
     *                  <code>DISPOSE_ON_CLOSE</code>
     *
     * @see #addInternalFrameListener
     * @see #getDefaultCloseOperation
     * @see #setVisible
     * @see #dispose
     * @see InternalFrameEvent#INTERNAL_FRAME_CLOSING
     */
    public void setDefaultCloseOperation(int operation) {
        this.defaultCloseOperation = operation;
    }

   /**
    * Returns the default operation that occurs when the user
    * initiates a "close" on this internal frame.
    * @return the operation that will occur when the user closes the internal
    *         frame
    * @see #setDefaultCloseOperation
    */
    public int getDefaultCloseOperation() {
        return defaultCloseOperation;
    }

    /**
     * Causes subcomponents of this <code>JInternalFrame</code>
     * to be laid out at their preferred size.  Internal frames that are
     * iconized or maximized are first restored and then packed.  If the
     * internal frame is unable to be restored its state is not changed
     * and will not be packed.
     *
     * @see       java.awt.Window#pack
     */
    public void pack() {
        try {
            if (isIcon()) {
                setIcon(false);
            } else if (isMaximum()) {
                setMaximum(false);
            }
        } catch(PropertyVetoException e) {
            return;
        }
        setSize(getPreferredSize());
        validate();
    }

    /**
     * If the internal frame is not visible,
     * brings the internal frame to the front,
     * makes it visible,
     * and attempts to select it.
     * The first time the internal frame is made visible,
     * this method also fires an <code>INTERNAL_FRAME_OPENED</code> event.
     * This method does nothing if the internal frame is already visible.
     * Invoking this method
     * has the same result as invoking
     * <code>setVisible(true)</code>.
     *
     * @see #moveToFront
     * @see #setSelected
     * @see InternalFrameEvent#INTERNAL_FRAME_OPENED
     * @see #setVisible
     */
    public void show() {
        // bug 4312922
        if (isVisible()) {
            //match the behavior of setVisible(true): do nothing
            return;
        }

        // bug 4149505
        if (!opened) {
          fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
          opened = true;
        }

        /* icon default visibility is false; set it to true so that it shows
           up when user iconifies frame */
        getDesktopIcon().setVisible(true);

        toFront();
        super.show();

        if (isIcon) {
            return;
        }

        if (!isSelected()) {
            try {
                setSelected(true);
            } catch (PropertyVetoException pve) {}
        }
    }

    public void hide() {
        if (isIcon()) {
            getDesktopIcon().setVisible(false);
        }
        super.hide();
    }

    /**
     * Makes this internal frame
     * invisible, unselected, and closed.
     * If the frame is not already closed,
     * this method fires an
     * <code>INTERNAL_FRAME_CLOSED</code> event.
     * The results of invoking this method are similar to
     * <code>setClosed(true)</code>,
     * but <code>dispose</code> always succeeds in closing
     * the internal frame and does not fire
     * an <code>INTERNAL_FRAME_CLOSING</code> event.
     *
     * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSED
     * @see #setVisible
     * @see #setSelected
     * @see #setClosed
     */
    public void dispose() {
        if (isVisible()) {
            setVisible(false);
        }
        if (isSelected()) {
            try {
                setSelected(false);
            } catch (PropertyVetoException pve) {}
        }
        if (!isClosed) {
          firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE, Boolean.TRUE);
          isClosed = true;
        }
        fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
    }

    /**
     * Brings this internal frame to the front.
     * Places this internal frame  at the top of the stacking order
     * and makes the corresponding adjustment to other visible internal
     * frames.
     *
     * @see       java.awt.Window#toFront
     * @see       #moveToFront
     */
    public void toFront() {
        moveToFront();
    }

    /**
     * Sends this internal frame to the back.
     * Places this internal frame at the bottom of the stacking order
     * and makes the corresponding adjustment to other visible
     * internal frames.
     *
     * @see       java.awt.Window#toBack
     * @see       #moveToBack
     */
    public void toBack() {
        moveToBack();
    }

    /**
     * Does nothing because <code>JInternalFrame</code>s must always be roots of a focus
     * traversal cycle.
     *
     * @param focusCycleRoot this value is ignored
     * @see #isFocusCycleRoot
     * @see java.awt.Container#setFocusTraversalPolicy
     * @see java.awt.Container#getFocusTraversalPolicy
     * @since 1.4
     */
    public final void setFocusCycleRoot(boolean focusCycleRoot) {
    }

    /**
     * Always returns <code>true</code> because all <code>JInternalFrame</code>s must be
     * roots of a focus traversal cycle.
     *
     * @return <code>true</code>
     * @see #setFocusCycleRoot
     * @see java.awt.Container#setFocusTraversalPolicy
     * @see java.awt.Container#getFocusTraversalPolicy
     * @since 1.4
     */
    public final boolean isFocusCycleRoot() {
        return true;
    }

    /**
     * Always returns <code>null</code> because <code>JInternalFrame</code>s
     * must always be roots of a focus
     * traversal cycle.
     *
     * @return <code>null</code>
     * @see java.awt.Container#isFocusCycleRoot()
     * @since 1.4
     */
    public final Container getFocusCycleRootAncestor() {
        return null;
    }

    /**
     * Gets the warning string that is displayed with this internal frame.
     * Since an internal frame is always secure (since it's fully
     * contained within a window that might need a warning string)
     * this method always returns <code>null</code>.
     * @return    <code>null</code>
     * @see       java.awt.Window#getWarningString
     */
    public final String getWarningString() {
        return null;
    }

    /**
     * See <code>readObject</code> and <code>writeObject</code>
     * in <code>JComponent</code> for more
     * information about serialization in Swing.
     */
    private void writeObject(ObjectOutputStream s) throws IOException {
        s.defaultWriteObject();
        if (getUIClassID().equals(uiClassID)) {
            byte count = JComponent.getWriteObjCounter(this);
            JComponent.setWriteObjCounter(this, --count);
            if (count == 0 && ui != null) {
                boolean old = isRootPaneCheckingEnabled();
                try {
                    setRootPaneCheckingEnabled(false);
                    ui.installUI(this);
                } finally {
                    setRootPaneCheckingEnabled(old);
                }
            }
        }
    }

    /* Called from the JComponent's EnableSerializationFocusListener to
     * do any Swing-specific pre-serialization configuration.
     */
    void compWriteObjectNotify() {
      // need to disable rootpane checking for InternalFrame: 4172083
      boolean old = isRootPaneCheckingEnabled();
      try {
        setRootPaneCheckingEnabled(false);
        super.compWriteObjectNotify();
      }
      finally {
        setRootPaneCheckingEnabled(old);
      }
    }

    /**
     * Returns a string representation of this <code>JInternalFrame</code>.
     * This method
     * is intended to be used only for debugging purposes, and the
     * content and format of the returned string may vary between
     * implementations. The returned string may be empty but may not
     * be <code>null</code>.
     *
     * @return  a string representation of this <code>JInternalFrame</code>
     */
    protected String paramString() {
        String rootPaneString = (rootPane != null ?
                                 rootPane.toString() : "");
        String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
                                                "true" : "false");
        String closableString = (closable ? "true" : "false");
        String isClosedString = (isClosed ? "true" : "false");
        String maximizableString = (maximizable ? "true" : "false");
        String isMaximumString = (isMaximum ? "true" : "false");
        String iconableString = (iconable ? "true" : "false");
        String isIconString = (isIcon ? "true" : "false");
        String resizableString = (resizable ? "true" : "false");
        String isSelectedString = (isSelected ? "true" : "false");
        String frameIconString = (frameIcon != null ?
                                  frameIcon.toString() : "");
        String titleString = (title != null ?
                              title : "");
        String desktopIconString = (desktopIcon != null ?
                                    desktopIcon.toString() : "");
        String openedString = (opened ? "true" : "false");
        String defaultCloseOperationString;
        if (defaultCloseOperation == HIDE_ON_CLOSE) {
            defaultCloseOperationString = "HIDE_ON_CLOSE";
        } else if (defaultCloseOperation == DISPOSE_ON_CLOSE) {
            defaultCloseOperationString = "DISPOSE_ON_CLOSE";
        } else if (defaultCloseOperation == DO_NOTHING_ON_CLOSE) {
            defaultCloseOperationString = "DO_NOTHING_ON_CLOSE";
        } else defaultCloseOperationString = "";

        return super.paramString() +
        ",closable=" + closableString +
        ",defaultCloseOperation=" + defaultCloseOperationString +
        ",desktopIcon=" + desktopIconString +
        ",frameIcon=" + frameIconString +
        ",iconable=" + iconableString +
        ",isClosed=" + isClosedString +
        ",isIcon=" + isIconString +
        ",isMaximum=" + isMaximumString +
        ",isSelected=" + isSelectedString +
        ",maximizable=" + maximizableString +
        ",opened=" + openedString +
        ",resizable=" + resizableString +
        ",rootPane=" + rootPaneString +
        ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString +
        ",title=" + titleString;
    }

    // ======= begin optimized frame dragging defence code ==============

    boolean isDragging = false;
    boolean danger = false;

    /**
     * Overridden to allow optimized painting when the
     * internal frame is being dragged.
     */
    protected void paintComponent(Graphics g) {
      if (isDragging) {
        //         System.out.println("ouch");
         danger = true;
      }

      super.paintComponent(g);
   }

    // ======= end optimized frame dragging defence code ==============

/////////////////
// Accessibility support
////////////////

    /**
     * Gets the <code>AccessibleContext</code> associated with this
     * <code>JInternalFrame</code>.
     * For internal frames, the <code>AccessibleContext</code>
     * takes the form of an
     * <code>AccessibleJInternalFrame</code> object.
     * A new <code>AccessibleJInternalFrame</code> instance is created if necessary.
     *
     * @return an <code>AccessibleJInternalFrame</code> that serves as the
     *         <code>AccessibleContext</code> of this
     *         <code>JInternalFrame</code>
     * @see AccessibleJInternalFrame
     */
    public AccessibleContext getAccessibleContext() {
        if (accessibleContext == null) {
            accessibleContext = new AccessibleJInternalFrame();
        }
        return accessibleContext;
    }

    /**
     * This class implements accessibility support for the
     * <code>JInternalFrame</code> class.  It provides an implementation of the
     * Java Accessibility API appropriate to internal frame user-interface
     * elements.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans<sup><font size="-2">TM</font></sup>
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     */
    protected class AccessibleJInternalFrame extends AccessibleJComponent
        implements AccessibleValue {

        /**
         * Get the accessible name of this object.
         *
         * @return the localized name of the object -- can be <code>null</code> if this
         * object does not have a name
         * @see #setAccessibleName
         */
        public String getAccessibleName() {
            String name = accessibleName;

            if (name == null) {
                name = (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
            }
            if (name == null) {
                name = getTitle();
            }
            return name;
        }

        /**
         * Get the role of this object.
         *
         * @return an instance of AccessibleRole describing the role of the
         * object
         * @see AccessibleRole
         */
        public AccessibleRole getAccessibleRole() {
            return AccessibleRole.INTERNAL_FRAME;
        }

        /**
         * Gets the AccessibleValue associated with this object.  In the
         * implementation of the Java Accessibility API for this class,
         * returns this object, which is responsible for implementing the
         * <code>AccessibleValue</code> interface on behalf of itself.
         *
         * @return this object
         */
        public AccessibleValue getAccessibleValue() {
            return this;
        }


        //
        // AccessibleValue methods
        //

        /**
         * Get the value of this object as a Number.
         *
         * @return value of the object -- can be <code>null</code> if this object does not
         * have a value
         */
        public Number getCurrentAccessibleValue() {
            return Integer.valueOf(getLayer());
        }

        /**
         * Set the value of this object as a Number.
         *
         * @return <code>true</code> if the value was set
         */
        public boolean setCurrentAccessibleValue(Number n) {
            // TIGER - 4422535
            if (n == null) {
                return false;
            }
            setLayer(new Integer(n.intValue()));
            return true;
        }

        /**
         * Get the minimum value of this object as a Number.
         *
         * @return Minimum value of the object; <code>null</code> if this object does not
         * have a minimum value
         */
        public Number getMinimumAccessibleValue() {
            return Integer.MIN_VALUE;
        }

        /**
         * Get the maximum value of this object as a Number.
         *
         * @return Maximum value of the object; <code>null</code> if this object does not
         * have a maximum value
         */
        public Number getMaximumAccessibleValue() {
            return Integer.MAX_VALUE;
        }

    } // AccessibleJInternalFrame

    /**
     * This component represents an iconified version of a
     * <code>JInternalFrame</code>.
     * This API should NOT BE USED by Swing applications, as it will go
     * away in future versions of Swing as its functionality is moved into
     * <code>JInternalFrame</code>.  This class is public only so that
     * UI objects can display a desktop icon.  If an application
     * wants to display a desktop icon, it should create a
     * <code>JInternalFrame</code> instance and iconify it.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans<sup><font size="-2">TM</font></sup>
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     *
     * @author David Kloba
     */
    static public class JDesktopIcon extends JComponent implements Accessible
    {
        JInternalFrame internalFrame;

        /**
         * Creates an icon for an internal frame.
         *
         * @param f  the <code>JInternalFrame</code>
         *              for which the icon is created
         */
        public JDesktopIcon(JInternalFrame f) {
            setVisible(false);
            setInternalFrame(f);
            updateUI();
        }

        /**
         * Returns the look-and-feel object that renders this component.
         *
         * @return the <code>DesktopIconUI</code> object that renders
         *              this component
         */
        public DesktopIconUI getUI() {
            return (DesktopIconUI)ui;
        }

        /**
         * Sets the look-and-feel object that renders this component.
         *
         * @param ui  the <code>DesktopIconUI</code> look-and-feel object
         * @see UIDefaults#getUI
         */
        public void setUI(DesktopIconUI ui) {
            super.setUI(ui);
        }

        /**
         * Returns the <code>JInternalFrame</code> that this
         * <code>DesktopIcon</code> is associated with.
         *
         * @return the <code>JInternalFrame</code> with which this icon
         *              is associated
         */
        public JInternalFrame getInternalFrame() {
            return internalFrame;
        }

        /**
         * Sets the <code>JInternalFrame</code> with which this
         * <code>DesktopIcon</code> is associated.
         *
         * @param f  the <code>JInternalFrame</code> with which this icon
         *              is associated
         */
        public void setInternalFrame(JInternalFrame f) {
            internalFrame = f;
        }

        /**
         * Convenience method to ask the icon for the <code>Desktop</code>
         * object it belongs to.
         *
         * @return the <code>JDesktopPane</code> that contains this
         *           icon's internal frame, or <code>null</code> if none found
         */
        public JDesktopPane getDesktopPane() {
            if(getInternalFrame() != null)
                return getInternalFrame().getDesktopPane();
            return null;
        }

        /**
         * Notification from the <code>UIManager</code> that the look and feel
         * has changed.
         * Replaces the current UI object with the latest version from the
         * <code>UIManager</code>.
         *
         * @see JComponent#updateUI
         */
        public void updateUI() {
            boolean hadUI = (ui != null);
            setUI((DesktopIconUI)UIManager.getUI(this));
            invalidate();

            Dimension r = getPreferredSize();
            setSize(r.width, r.height);


            if (internalFrame != null && internalFrame.getUI() != null) {  // don't do this if UI not created yet
                SwingUtilities.updateComponentTreeUI(internalFrame);
            }
        }

        /* This method is called if updateUI was called on the associated
         * JInternalFrame.  It's necessary to avoid infinite recursion.
         */
        void updateUIWhenHidden() {
            /* Update this UI and any associated internal frame */
            setUI((DesktopIconUI)UIManager.getUI(this));

            Dimension r = getPreferredSize();
            setSize(r.width, r.height);

            invalidate();
            Component[] children = getComponents();
            if (children != null) {
                for (Component child : children) {
                    SwingUtilities.updateComponentTreeUI(child);
                }
            }
        }

        /**
         * Returns the name of the look-and-feel
         * class that renders this component.
         *
         * @return the string "DesktopIconUI"
         * @see JComponent#getUIClassID
         * @see UIDefaults#getUI
         */
        public String getUIClassID() {
            return "DesktopIconUI";
        }
        ////////////////
        // Serialization support
        ////////////////
        private void writeObject(ObjectOutputStream s) throws IOException {
            s.defaultWriteObject();
            if (getUIClassID().equals("DesktopIconUI")) {
                byte count = JComponent.getWriteObjCounter(this);
                JComponent.setWriteObjCounter(this, --count);
                if (count == 0 && ui != null) {
                    ui.installUI(this);
                }
            }
        }

       /////////////////
       // Accessibility support
       ////////////////

        /**
         * Gets the AccessibleContext associated with this JDesktopIcon.
         * For desktop icons, the AccessibleContext takes the form of an
         * AccessibleJDesktopIcon.
         * A new AccessibleJDesktopIcon instance is created if necessary.
         *
         * @return an AccessibleJDesktopIcon that serves as the
         *         AccessibleContext of this JDesktopIcon
         */
        public AccessibleContext getAccessibleContext() {
            if (accessibleContext == null) {
                accessibleContext = new AccessibleJDesktopIcon();
            }
            return accessibleContext;
        }

        /**
         * This class implements accessibility support for the
         * <code>JInternalFrame.JDesktopIcon</code> class.  It provides an
         * implementation of the Java Accessibility API appropriate to
         * desktop icon user-interface elements.
         * <p>
         * <strong>Warning:</strong>
         * Serialized objects of this class will not be compatible with
         * future Swing releases. The current serialization support is
         * appropriate for short term storage or RMI between applications running
         * the same version of Swing.  As of 1.4, support for long term storage
         * of all JavaBeans<sup><font size="-2">TM</font></sup>
         * has been added to the <code>java.beans</code> package.
         * Please see {@link java.beans.XMLEncoder}.
         */
        protected class AccessibleJDesktopIcon extends AccessibleJComponent
            implements AccessibleValue {

            /**
             * Gets the role of this object.
             *
             * @return an instance of AccessibleRole describing the role of the
             * object
             * @see AccessibleRole
             */
            public AccessibleRole getAccessibleRole() {
                return AccessibleRole.DESKTOP_ICON;
            }

            /**
             * Gets the AccessibleValue associated with this object.  In the
             * implementation of the Java Accessibility API for this class,
             * returns this object, which is responsible for implementing the
             * <code>AccessibleValue</code> interface on behalf of itself.
             *
             * @return this object
             */
            public AccessibleValue getAccessibleValue() {
                return this;
            }

            //
            // AccessibleValue methods
            //

            /**
             * Gets the value of this object as a <code>Number</code>.
             *
             * @return value of the object -- can be <code>null</code> if this object does not
             * have a value
             */
            public Number getCurrentAccessibleValue() {
                AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
                AccessibleValue v = a.getAccessibleValue();
                if (v != null) {
                    return v.getCurrentAccessibleValue();
                } else {
                    return null;
                }
            }

            /**
             * Sets the value of this object as a <code>Number</code>.
             *
             * @return <code>true</code> if the value was set
             */
            public boolean setCurrentAccessibleValue(Number n) {
                // TIGER - 4422535
                if (n == null) {
                    return false;
                }
                AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
                AccessibleValue v = a.getAccessibleValue();
                if (v != null) {
                    return v.setCurrentAccessibleValue(n);
                } else {
                    return false;
                }
            }

            /**
             * Gets the minimum value of this object as a <code>Number</code>.
             *
             * @return minimum value of the object; <code>null</code> if this object does not
             * have a minimum value
             */
            public Number getMinimumAccessibleValue() {
                AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
                if (a instanceof AccessibleValue) {
                    return ((AccessibleValue)a).getMinimumAccessibleValue();
                } else {
                    return null;
                }
            }

            /**
             * Gets the maximum value of this object as a <code>Number</code>.
             *
             * @return maximum value of the object; <code>null</code> if this object does not
             * have a maximum value
             */
            public Number getMaximumAccessibleValue() {
                AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
                if (a instanceof AccessibleValue) {
                    return ((AccessibleValue)a).getMaximumAccessibleValue();
                } else {
                    return null;
                }
            }

        } // AccessibleJDesktopIcon
    }
}
