- /*
- * @(#)JInternalFrame.java 1.147 04/05/18
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- package javax.swing;
-
- import java.awt.*;
- import java.awt.event.*;
-
- import java.beans.PropertyVetoException;
- import java.beans.PropertyChangeEvent;
- import java.util.EventListener;
-
- import javax.swing.border.Border;
- import javax.swing.event.InternalFrameEvent;
- import javax.swing.event.InternalFrameListener;
- import javax.swing.plaf.*;
-
- import javax.accessibility.*;
-
- import java.io.ObjectOutputStream;
- import java.io.ObjectInputStream;
- import java.io.IOException;
-
-
- /**
- * 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>
- * 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
- *
- * @version 1.147 05/18/04
- * @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 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";
-
-
- /**
- * 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());
- getGlassPane().setVisible(true);
- 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);
- }
-
- /**
- * 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(int i = 0; i < children.length; i++) {
- SwingUtilities.updateComponentTreeUI(children[i]);
- }
- }
- }
-
-
- /**
- * 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 forwad 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;
- 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 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 */
-
- lastFocusOwner = null;
- if (selected) {
- restoreSubcomponentFocus();
- } else {
- getRootPane().setMostRecentFocusOwner(getFocusOwner());
- }
-
- isSelected = selected;
- firePropertyChange(IS_SELECTED_PROPERTY, oldValue, newValue);
- if (isSelected)
- fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED);
- else
- fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
- lastFocusOwner = null;
- 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(getParent() != null && getParent() instanceof JLayeredPane) {
- JLayeredPane l = (JLayeredPane)getParent();
- // Because move to front typically involves adding and removing
- // Components, it will often times result in focus changes. We
- // either install focus to the lastFocusOwner, or our desendant
- // that has focus. We use the ivar for lastFocusOwner as in
- // some cases requestFocus is async and won't have completed from
- // the requestFocus call in setSelected so that getFocusOwner
- // will return the wrong component.
- Component focusOwner = (lastFocusOwner != null) ? lastFocusOwner :
- KeyboardFocusManager.getCurrentKeyboardFocusManager().
- getFocusOwner();
-
- if (focusOwner != null &&
- !SwingUtilities.isDescendingFrom(focusOwner, this)) {
- focusOwner = null;
- }
- l.moveToFront(this);
- if (focusOwner != null) {
- focusOwner.requestFocus();
- }
- }
- }
-
- /**
- * Convenience method that moves this component to position -1 if its
- * parent is a <code>JLayeredPane</code>.
- */
- public void moveToBack() {
- if(getParent() != null && getParent() instanceof JLayeredPane) {
- JLayeredPane l = (JLayeredPane)getParent();
- l.moveToBack(this);
- }
- }
-
- /**
- * 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(new Integer(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()) {
- Component focusOwner = KeyboardFocusManager.
- getCurrentKeyboardFocusManager().getFocusOwner();
-
- if (focusOwner != null && !SwingUtilities.
- isDescendingFrom(focusOwner, this)) {
- // Sanity check, may sure we don't return a bogus value here.
- focusOwner = null;
- }
- return focusOwner;
- }
- 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();
- }
-
- Component mostRecentFocusOwner =
- getRootPane().getMostRecentFocusOwner();
- if (mostRecentFocusOwner != null) {
- return mostRecentFocusOwner;
- }
-
- FocusTraversalPolicy policy = getFocusTraversalPolicy();
- if (policy instanceof InternalFrameFocusTraversalPolicy) {
- return ((InternalFrameFocusTraversalPolicy)policy).
- getInitialComponent(this);
- }
-
- return policy.getDefaultComponent(this);
- }
-
- /**
- * 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() {
- lastFocusOwner = 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.
- lastFocusOwner = getContentPane();
- }
- lastFocusOwner.requestFocus();
- }
-
- /**
- * 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 (InternalFrameListener[])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;
- 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() {
- if (accessibleName != null) {
- return accessibleName;
- } else {
- return getTitle();
- }
- }
-
- /**
- * 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 new Integer(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 new Integer(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 new Integer(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(int i = 0; i < children.length; i++) {
- SwingUtilities.updateComponentTreeUI(children[i]);
- }
- }
- }
-
- /**
- * 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
- }
- }