alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (JInternalFrame.java)

This example Java source code file (JInternalFrame.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

accessiblecontext, accessiblevalue, awt, bean, boolean, component, desktopiconui, event, gui, javabean, jdesktopicon, jdesktoppane, jinternalframe, jlayeredpane, jmenubar, jrootpane, number, propertyvetoexception, string, swing

The JInternalFrame.java Java example source code

/*
 * Copyright (c) 1997, 2013, 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://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html" target="_top">How to Use Internal Frames</a>,
 * a section in <em>The Java Tutorial.
 *
 * <p>
 *
 * Generally,
 * you add <code>JInternalFrames to a JDesktopPane. The UI
 * delegates the look-and-feel-specific actions to the
 * <code>DesktopManager
 * object maintained by the <code>JDesktopPane.
 * <p>
 * The <code>JInternalFrame content pane
 * is where you add child components.
 * As a convenience, the {@code add}, {@code remove}, and {@code setLayout}
 * methods of this class are overridden, so that they delegate calls
 * to the corresponding methods of the {@code ContentPane}.
 * For example, you can add a child component to an internal frame as follows:
 * <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,
 * which also manages a layout pane, glass pane, and
 * optional menu bar for the internal frame. Please see the
 * <code>JRootPane
 * documentation for a complete description of these components.
 * Refer to {@link javax.swing.RootPaneContainer}
 * for details on adding, removing and setting the <code>LayoutManager
 * of a <code>JInternalFrame.
 * <p>
 * <strong>Warning: Swing is not thread safe. For more
 * information see <a
 * href="package-summary.html#threading">Swing's Threading
 * Policy</a>.
 * <p>
 * <strong>Warning:
 * 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™
 * has been added to the <code>java.beans 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 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 and setLayout
     * will be forwarded to the <code>contentPane. This is initially
     * false, but is set to true when the <code>JInternalFrame 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 is invoked, that is,
     * <code>restoreSubcomponentFocus sets this to the value returned
     * from <code>getMostRecentFocusOwner.
     */
    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 with no title.
     */
    public JInternalFrame() {
        this("", false, false, false, false);
    }

    /**
     * Creates a non-resizable, non-closable, non-maximizable,
     * non-iconifiable <code>JInternalFrame with the specified title.
     * Note that passing in a <code>null title results in
     * unspecified behavior and possibly an exception.
     *
     * @param title  the non-<code>null String
     *     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 with the specified title
     * and resizability.
     *
     * @param title      the <code>String to display in the title bar
     * @param resizable  if <code>true, 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
     * with the specified title, resizability, and
     * closability.
     *
     * @param title      the <code>String to display in the title bar
     * @param resizable  if <code>true, the internal frame can be resized
     * @param closable   if <code>true, 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
     * with the specified title,
     * resizability, closability, and maximizability.
     *
     * @param title       the <code>String to display in the title bar
     * @param resizable   if <code>true, the internal frame can be resized
     * @param closable    if <code>true, the internal frame can be closed
     * @param maximizable if <code>true, 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 with the specified title,
     * resizability, closability, maximizability, and iconifiability.
     * All <code>JInternalFrame constructors use this one.
     *
     * @param title       the <code>String to display in the title bar
     * @param resizable   if <code>true, the internal frame can be resized
     * @param closable    if <code>true, the internal frame can be closed
     * @param maximizable if <code>true, the internal frame can be maximized
     * @param iconifiable if <code>true, 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);
        addPropertyChangeListenerIfNecessary();
    }

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

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

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

    /* This method is called if <code>updateUI 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 and
     * <code>setLayout are forwarded to the contentPane.
     *
     * @return true if <code>add and setLayout
     *         are forwarded; false otherwise
     *
     * @see #addImpl
     * @see #setLayout
     * @see #setRootPaneCheckingEnabled
     * @see javax.swing.RootPaneContainer
     */
    protected boolean isRootPaneCheckingEnabled() {
        return rootPaneCheckingEnabled;
    }

    /**
     * Sets whether calls to <code>add and
     * <code>setLayout are forwarded to the contentPane.
     *
     * @param enabled  true if <code>add and setLayout
     *        are forwarded, false if they should operate directly on the
     *        <code>JInternalFrame.
     *
     * @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.
     * This method is overridden to conditionally forward calls to the
     * <code>contentPane.
     * By default, children are added to the <code>contentPane 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 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 is not a child of the JInternalFrame
     * this will forward the call to the <code>contentPane.
     *
     * @param comp the component to be removed
     * @throws NullPointerException if <code>comp 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.
     * Refer to {@link javax.swing.RootPaneContainer} for
     * more information.
     *
     * @param manager the <code>LayoutManager
     * @see #setRootPaneCheckingEnabled
     */
    public void setLayout(LayoutManager manager) {
        if(isRootPaneCheckingEnabled()) {
            getContentPane().setLayout(manager);
        }
        else {
            super.setLayout(manager);
        }
    }


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

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

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

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

    /**
     * Sets the <code>menuBar property for this JInternalFrame.
     *
     * @param m  the <code>JMenuBar 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's contentPane
     * 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
     * @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 object
     * @see RootPaneContainer#setLayeredPane
     * @see RootPaneContainer#getLayeredPane
     */
    public JLayeredPane getLayeredPane() {
        return getRootPane().getLayeredPane();
    }

    /**
     * Sets this <code>JInternalFrame's
     * <code>layeredPane property.
     *
     * @param layered the <code>JLayeredPane for this internal frame
     *
     * @exception java.awt.IllegalComponentStateException (a runtime
     *           exception) if the layered pane parameter is <code>null
     * @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's
     * <code>glassPane 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 object for this internal frame.
     *
     * @return the <code>rootPane property
     * @see RootPaneContainer#getRootPane
     */
    public JRootPane getRootPane() {
        return rootPane;
    }


    /**
     * Sets the <code>rootPane property
     * for this <code>JInternalFrame.
     * This method is called by the constructor.
     *
     * @param root  the new <code>JRootPane 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 can be closed by
     * some user action.
     * @param b a boolean value, where <code>true 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 can be closed by
     * some user action.
     * @return <code>true if this internal frame can be closed
     */
    public boolean isClosable() {
        return closable;
    }

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

    /**
     * Closes this internal frame if the argument is <code>true.
     * Do not invoke this method with a <code>false argument;
     * the result of invoking <code>setClosed(false)
     * 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 event.
     * Then this method sets the <code>closed property to true
     * 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 event.
     *
     * <p>
     *
     * <b>Note:
     * 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
     * that previously contained the internal frame.
     *
     * @param b must be <code>true
     *
     * @exception PropertyVetoException when the attempt to set the
     *            property is vetoed by the <code>JInternalFrame
     *
     * @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 can be resized by some
     * user action.
     *
     * @param b  a boolean, where <code>true 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 can be resized
     * by some user action.
     *
     * @return <code>true if this internal frame can be resized, false otherwise
     */
    public boolean isResizable() {
        // don't allow resizing when maximized.
        return isMaximum ? false : resizable;
    }

    /**
     * Sets the <code>iconable property,
     * which must be <code>true
     * for the user to be able to
     * make the <code>JInternalFrame an icon.
     * Some look and feels might not implement iconification;
     * they will ignore this property.
     *
     * @param b  a boolean, where <code>true 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 property,
     * which by default is <code>false.
     *
     * @return the value of the <code>iconable property.
     *
     * @see #setIconifiable
     */
    public boolean isIconifiable() {
        return iconable;
    }

    /**
     * Returns whether the <code>JInternalFrame is currently iconified.
     *
     * @return <code>true 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 event.
     * If the state changes to de-iconified,
     * an <code>INTERNAL_FRAME_DEICONIFIED event is fired.
     *
     * @param b a boolean, where <code>true means to iconify this internal frame and
     *          <code>false means to de-iconify it
     * @exception PropertyVetoException when the attempt to set the
     *            property is vetoed by the <code>JInternalFrame
     *
     * @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 property,
     * which determines whether the <code>JInternalFrame
     * 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 to specify that this internal frame should be maximizable; false 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 property.
     *
     * @return the value of the <code>maximizable property
     * @see #setMaximizable
     */
    public boolean isMaximizable() {
        return maximizable;
    }

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

    /**
     * Maximizes and restores this internal frame.  A maximized frame is resized to
     * fully fit the <code>JDesktopPane area associated with the
     * <code>JInternalFrame.
     * A restored frame's size is set to the <code>JInternalFrame's
     * actual size.
     *
     * @param b  a boolean, where <code>true maximizes this internal frame and false
     *           restores it
     * @exception PropertyVetoException when the attempt to set the
     *            property is vetoed by the <code>JInternalFrame
     * @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.
     *
     * @return a <code>String containing this internal frame's title
     * @see #setTitle
     */
    public String getTitle() {
        return title;
    }

    /**
     * Sets the <code>JInternalFrame title. title
     * may have a <code>null value.
     * @see #getTitle
     *
     * @param title  the <code>String 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 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 event.
     * If the change is from selected to deselected,
     * an <code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED event
     * is fired.
     *
     * @param selected  a boolean, where <code>true means this internal frame
     *                  should become selected (currently active)
     *                  and <code>false means it should become deselected
     * @exception PropertyVetoException when the attempt to set the
     *            property is vetoed by the <code>JInternalFrame
     *
     * @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 is the
     * currently "selected" or active frame.
     *
     * @return <code>true 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 object, which
     * is the image displayed in the <code>JDesktop when
     * this internal frame is iconified.
     *
     * Passing <code>null 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 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 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.
      */
    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.
      */
    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 that was set by the
     * <code>setCursor method that is not a resizable
     * <code>Cursor.
     *
     * @return the last non-resizable <code>Cursor
     * @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 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) should be used for
     * layer values predefined in <code>JLayeredPane.
     * When using <code>setLayer(int), 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 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 instance. If JInternalFrame
      * finds none, the <code>desktopIcon tree is searched.
      *
      * @return the <code>JDesktopPane this internal frame belongs to,
      *         or <code>null 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 associated with this
     * <code>JInternalFrame.
     *
     * @param d the <code>JDesktopIcon 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 used when this
     * <code>JInternalFrame is iconified.
     *
     * @return the <code>JDesktopIcon displayed on the desktop
     * @see #setDesktopIcon
     */
    public JDesktopIcon getDesktopIcon() {
        return desktopIcon;
    }

    /**
     * If the <code>JInternalFrame is not in maximized state, returns
     * <code>getBounds(); otherwise, returns the bounds that the
     * <code>JInternalFrame would be restored to.
     *
     * @return a <code>Rectangle 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 is active,
     * returns the child that has focus.
     * Otherwise, returns <code>null.
     *
     * @return the component with focus, or <code>null 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
     * that will receive the
     * focus when this <code>JInternalFrame is selected.
     * If this <code>JInternalFrame is
     * currently selected, this method returns the same component as
     * the <code>getFocusOwner method.
     * If this <code>JInternalFrame 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's initial focusable component is returned.
     * If no such
     * child exists, then this <code>JInternalFrame's default component
     * to focus is returned.
     *
     * @return the child component that will receive focus when this
     *         <code>JInternalFrame 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>InternalFrameListeners added
     * to this <code>JInternalFrame with
     * <code>addInternalFrameListener.
     *
     * @return all of the <code>InternalFrameListeners 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>InternalFrameEvent.INTERNAL_FRAME_OPENED
     * <li>InternalFrameEvent.INTERNAL_FRAME_CLOSING
     * <li>InternalFrameEvent.INTERNAL_FRAME_CLOSED
     * <li>InternalFrameEvent.INTERNAL_FRAME_ICONIFIED
     * <li>InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED
     * <li>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED
     * <li>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED
     * </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 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:
     * <br>
* <dl> * <dt>DO_NOTHING_ON_CLOSE * <dd> Do nothing. * This requires the program to handle the operation * in the <code>windowClosing method * of a registered <code>InternalFrameListener object. * <dt>HIDE_ON_CLOSE * <dd> Automatically make the internal frame invisible. * <dt>DISPOSE_ON_CLOSE * <dd> Automatically dispose of the internal frame. * </dl> * <p> * The default value is <code>DISPOSE_ON_CLOSE. * Before performing the specified close operation, * the internal frame fires * an <code>INTERNAL_FRAME_CLOSING event. * * @param operation one of the following constants defined in * <code>javax.swing.WindowConstants * (an interface implemented by * <code>JInternalFrame): * <code>DO_NOTHING_ON_CLOSE, * <code>HIDE_ON_CLOSE, or * <code>DISPOSE_ON_CLOSE * * @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 * 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 event. * This method does nothing if the internal frame is already visible. * Invoking this method * has the same result as invoking * <code>setVisible(true). * * @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 event. * The results of invoking this method are similar to * <code>setClosed(true), * but <code>dispose always succeeds in closing * the internal frame and does not fire * an <code>INTERNAL_FRAME_CLOSING 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>JInternalFrames 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 because all JInternalFrames must be * roots of a focus traversal cycle. * * @return <code>true * @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 because JInternalFrames * must always be roots of a focus * traversal cycle. * * @return <code>null * @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. * @return <code>null * @see java.awt.Window#getWarningString */ public final String getWarningString() { return null; } /** * See <code>readObject and writeObject * in <code>JComponent 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. * 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. * * @return a string representation of this <code>JInternalFrame */ 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 associated with this * <code>JInternalFrame. * For internal frames, the <code>AccessibleContext * takes the form of an * <code>AccessibleJInternalFrame object. * A new <code>AccessibleJInternalFrame instance is created if necessary. * * @return an <code>AccessibleJInternalFrame that serves as the * <code>AccessibleContext of this * <code>JInternalFrame * @see AccessibleJInternalFrame */ public AccessibleContext getAccessibleContext() { if (accessibleContext == null) { accessibleContext = new AccessibleJInternalFrame(); } return accessibleContext; } /** * This class implements accessibility support for the * <code>JInternalFrame class. It provides an implementation of the * Java Accessibility API appropriate to internal frame user-interface * elements. * <p> * <strong>Warning: * 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™ * has been added to the <code>java.beans 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 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 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 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 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 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 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. * 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. 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 instance and iconify it. * <p> * <strong>Warning: * 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™ * has been added to the <code>java.beans 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 * 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 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 look-and-feel object * @see UIDefaults#getUI */ public void setUI(DesktopIconUI ui) { super.setUI(ui); } /** * Returns the <code>JInternalFrame that this * <code>DesktopIcon is associated with. * * @return the <code>JInternalFrame with which this icon * is associated */ public JInternalFrame getInternalFrame() { return internalFrame; } /** * Sets the <code>JInternalFrame with which this * <code>DesktopIcon is associated. * * @param f the <code>JInternalFrame with which this icon * is associated */ public void setInternalFrame(JInternalFrame f) { internalFrame = f; } /** * Convenience method to ask the icon for the <code>Desktop * object it belongs to. * * @return the <code>JDesktopPane that contains this * icon's internal frame, or <code>null if none found */ public JDesktopPane getDesktopPane() { if(getInternalFrame() != null) return getInternalFrame().getDesktopPane(); return null; } /** * Notification from the <code>UIManager that the look and feel * has changed. * Replaces the current UI object with the latest version from the * <code>UIManager. * * @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 class. It provides an * implementation of the Java Accessibility API appropriate to * desktop icon user-interface elements. * <p> * <strong>Warning: * 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™ * has been added to the <code>java.beans 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 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. * * @return value of the object -- can be <code>null 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. * * @return <code>true 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. * * @return minimum value of the object; <code>null 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. * * @return maximum value of the object; <code>null 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 } }

Other Java examples (source code examples)

Here is a short list of links related to this Java JInternalFrame.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.