Package javax.swing

Source Code of javax.swing.JInternalFrame$AccessibleJInternalFrame

/*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package javax.swing;

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.KeyboardFocusManager;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.beans.PropertyVetoException;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleValue;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.plaf.DesktopIconUI;
import javax.swing.plaf.InternalFrameUI;
import org.apache.harmony.x.swing.BlitSupport;
import org.apache.harmony.x.swing.StringConstants;

/**
* <p>
* <i>JInternalFrame</i>
* </p>
* <h3>Implementation Notes:</h3>
* <ul>
* <li>The <code>serialVersionUID</code> fields are explicitly declared as a performance
* optimization, not as a guarantee of serialization compatibility.</li>
* </ul>
*/
public class JInternalFrame extends JComponent implements Accessible, WindowConstants,
        RootPaneContainer {
    private static final long serialVersionUID = 3837984427982803247L;

    /**
     * This class represents the internal frame when it is iconified.
     */
    public static class JDesktopIcon extends JComponent implements Accessible {
        private static final long serialVersionUID = -4923863980546870453L;

        // The internal frame for this icon.
        private JInternalFrame internalFrame;

        /**
         * Creates the desktop icon for the internal frame.
         *
         * @param frame the internal frame of the created desktop icon
         */
        public JDesktopIcon(final JInternalFrame frame) {
            setLayout(new BorderLayout());
            setVisible(frame.isVisible());
            setInternalFrame(frame);
            updateUIForIcon();
        }

        /**
         * This class implements accessibility support for
         * <code>JDesktopIcon</code>.
         */
        protected class AccessibleJDesktopIcon extends AccessibleJComponent implements
                AccessibleValue {
            private static final long serialVersionUID = -7418555324455474398L;

            private Number currentAccessibleValue = new Integer(0);

            protected AccessibleJDesktopIcon() {
            }

            @Override
            public AccessibleRole getAccessibleRole() {
                return AccessibleRole.DESKTOP_ICON;
            }

            @Override
            public AccessibleValue getAccessibleValue() {
                return this;
            }

            public Number getCurrentAccessibleValue() {
                return currentAccessibleValue;
            }

            public boolean setCurrentAccessibleValue(final Number n) {
                if (n == null) {
                    return false;
                }
                if (n instanceof Integer) {
                    currentAccessibleValue = n;
                } else {
                    // XXX: 1.5 migration: replace this line with the commented line
                    currentAccessibleValue = new Integer(n.intValue());
                    //currentAccessibleValue = Integer.valueOf(n.intValue());
                }
                return true;
            }

            public Number getMinimumAccessibleValue() {
                return MIN_VALUE;
            }

            public Number getMaximumAccessibleValue() {
                return MAX_VALUE;
            }
        }

        /**
         * Sets the UI object for this component.
         *
         * @param ui
         */
        public void setUI(final DesktopIconUI ui) {
            // setUI() from super (JComponent) should always be called
            super.setUI(ui);
        }

        /**
         * Returns the UI object for this component.
         *
         * @return UI object for this component
         */
        public DesktopIconUI getUI() {
            return (DesktopIconUI) ui;
        }

        /**
         * Sets the internal frame for this desktop icon
         *
         * @param frame the internal frame for this desktop icon
         */
        public void setInternalFrame(final JInternalFrame frame) {
            internalFrame = frame;
        }

        /**
         * Returns the internal frame for this desktop icon
         *
         * @return the internal frame for this desktop icon
         */
        public JInternalFrame getInternalFrame() {
            return internalFrame;
        }

        /**
         * Returns the desktop pane that contains the desktop icon.
         *
         * @return the desktop pane that contains the desktop icon
         */
        public JDesktopPane getDesktopPane() {
            // its theoretically possible that
            // this.getInternalFrame().getDesktopIcon() != this;
            // so, we cannot write here just
            // return getInternalFrame().getDesktopPane();
            Container result = SwingUtilities.getAncestorOfClass(JDesktopPane.class, this);

            if (result == null) {
                if(getInternalFrame() != null) {
                    result = getInternalFrame().getDesktopPane();
                }
            }

            return (JDesktopPane) result;
        }

        /**
         * Returns the accessible context for the icon.
         *
         * @return the accessible context for the icon
         */
        @Override
        public AccessibleContext getAccessibleContext() {
            if (accessibleContext == null) {
                accessibleContext = new AccessibleJDesktopIcon();
            }
            return accessibleContext;
        }

        /**
         * Returns the name of the L&F class that renders this component.
         *
         * @return the string "DesktopIconUI"
         */
        @Override
        public String getUIClassID() {
            return "DesktopIconUI";
        }

        /**
         * Updates <code>UI's</code> for both <code>JInternalFrame</code>
         * and <code>JDesktopIcon</code>.
         */
        @Override
        public void updateUI() {
            updateUIForIcon();
            getInternalFrame().updateUI();
        }

        void updateUIForIcon() {
            setUI((DesktopIconUI) UIManager.getUI(this));
        }
    }

    /**
     * The name of the bound property.
     */
    public static final String CONTENT_PANE_PROPERTY = "contentPane";

    /**
     * The name of the bound property.
     */
    public static final String MENU_BAR_PROPERTY = "JMenuBar";

    /**
     * The name of the bound property.
     */
    public static final String TITLE_PROPERTY = "title";

    /**
     * The name of the bound property.
     */
    public static final String LAYERED_PANE_PROPERTY = "layeredPane";

    /**
     * The name of the bound property.
     */
    public static final String ROOT_PANE_PROPERTY = "rootPane";

    /**
     * The name of the bound property.
     */
    public static final String GLASS_PANE_PROPERTY = "glassPane";

    /**
     * The name of the bound property.
     */
    public static final String FRAME_ICON_PROPERTY = "frameIcon";

    /**
     * The name of the constrained property which indicates whether
     * the internal frame is selected.
     */
    public static final String IS_SELECTED_PROPERTY = "selected";

    /**
     * The name of the constrained property which indicates whether
     * the internal frame is closed.
     */
    public static final String IS_CLOSED_PROPERTY = "closed";

    /**
     * The name of the constrained property which indicates whether
     * the internal frame is maximized.
     */
    public static final String IS_MAXIMUM_PROPERTY = "maximum";

    /**
     * The name of the constrained property which indicates whether
     * the internal frame is iconified.
     */
    public static final String IS_ICON_PROPERTY = "icon";

    private static final Integer MIN_VALUE = new Integer(Integer.MIN_VALUE);

    private static final Integer MAX_VALUE = new Integer(Integer.MAX_VALUE);

    /**
     * <code>JRootPane</code> containter of the internal frame.
     */
    protected JRootPane rootPane;

    protected boolean rootPaneCheckingEnabled;

    /**
     * The frame can be closed.
     */
    protected boolean closable;

    /**
     * The frame is closed.
     */
    protected boolean isClosed = false;

    /**
     * The frame can be maximized.
     */
    protected boolean maximizable;

    /**
     * The frame is maximized.
     */
    protected boolean isMaximum;

    /**
     * The frame can be icinified.
     */
    protected boolean iconable;

    /**
     * The frame is iconified.
     */
    protected boolean isIcon;

    /**
     * The frame is resizable.
     */
    protected boolean resizable;

    /**
     * The frame is selected now.
     */
    protected boolean isSelected;

    /**
     * The icon shown in the top-left corner of the frame.
     */
    protected Icon frameIcon;

    /**
     * The title of the frame.
     */
    protected String title = "";

    /**
     * The icon that is displayed when the frame is iconified.
     */
    protected JDesktopIcon desktopIcon;

    // normalBounds property
    private Rectangle normalBounds = new Rectangle();

    // defauld close operation
    private int defaultCloseOperation = DISPOSE_ON_CLOSE;

    // most recent focus owner
    private Component mostRecentFocusOwner;

    // shows if the internal frame is opened the first time
    private boolean firstTimeOpen = true;

    private BlitSupport blitSupport;

    /**
     * Constructs a non-resizable, non-closable, non-maximizable,
     * non-iconifiable internal frame with no title.
     */
    public JInternalFrame() {
        this("", false, false, false, false);
    }

    /**
     * Constructs a non-resizable, non-closable, non-maximizable,
     * non-iconifiable internal frame with the specified title.
     *
     * @param title the title of the internal frame
     */
    public JInternalFrame(final String title) {
        this(title, false, false, false, false);
    }

    /**
     * Constructs a non-closable, non-maximizable, non-iconifiable internal
     * frame with the specified title and resizability.
     *
     * @param title the title of the internal frame
     * @param resizable
     */
    public JInternalFrame(final String title, final boolean resizable) {
        this(title, resizable, false, false, false);
    }

    /**
     * Constructs a non-maximizable, non-iconifiable internal frame
     * with the specified title, resizability and closability.
     *
     * @param title the title of the internal frame
     * @param resizable
     * @param closable
     */
    public JInternalFrame(final String title, final boolean resizable, final boolean closable) {
        this(title, resizable, closable, false, false);
    }

    /**
     * Constructs a non-iconifiable internal frame with the specified title,
     * resizability, closability and maximizability.
     *
     * @param title the title of the internal frame
     * @param resizable
     * @param closable
     * @param maximizable
     */
    public JInternalFrame(final String title, final boolean resizable, final boolean closable,
            final boolean maximizable) {
        this(title, resizable, closable, maximizable, false);
    }

    /**
     * Constructs an internal frame with the specified title,
     * resizability, closability, maximizability and iconifiability.
     *
     * @param title the title of the internal frame
     * @param resizable
     * @param closable
     * @param maximizable
     * @param iconifiable
     */
    public JInternalFrame(final String title, final boolean resizable, final boolean closable,
            final boolean maximizable, final boolean iconifiable) {
        //super.hide();
        super.setVisible(false);
        this.title = title;
        this.resizable = resizable;
        this.closable = closable;
        this.maximizable = maximizable;
        this.iconable = iconifiable;
        // from frameInit()
        setRootPane(createRootPane());
        setLocale(JComponent.getDefaultLocale());
        // check isDefaultLookAndFeelDecorated()
        //if (isDefaultLookAndFeelDecorated()) {
        //    setUndecorated(true);
        //getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
        // }
        setBackground(getContentPane().getBackground());
        // enable events
        enableEvents(AWTEvent.WINDOW_EVENT_MASK);
        enableEvents(AWTEvent.KEY_EVENT_MASK);
        setFocusTraversalPolicy(KeyboardFocusManager.getCurrentKeyboardFocusManager()
                .getDefaultFocusTraversalPolicy());
        updateUI();
        this.desktopIcon = new JDesktopIcon(this);
        setRootPaneCheckingEnabled(true);
        // non-selected internalFrame must have visible glassPane
        getGlassPane().setVisible(true);
        // just to be sure
        super.setFocusCycleRoot(true);
    }

    /**
     * This class implements accessibility support for
     * <code>JInternalFrame</code>.
     */
    protected class AccessibleJInternalFrame extends AccessibleJComponent implements
            AccessibleValue {
        private static final long serialVersionUID = 8391910997005202445L;

        private Number currentAccessibleValue = new Integer(0);

        protected AccessibleJInternalFrame() {
        }

        @Override
        public String getAccessibleName() {
            return getTitle();
        }

        @Override
        public AccessibleRole getAccessibleRole() {
            return AccessibleRole.INTERNAL_FRAME;
        }

        @Override
        public AccessibleValue getAccessibleValue() {
            return this;
        }

        public Number getCurrentAccessibleValue() {
            return currentAccessibleValue;
        }

        public boolean setCurrentAccessibleValue(final Number n) {
            if (n == null) {
                return false;
            }
            if (n instanceof Integer) {
                currentAccessibleValue = n;
            } else {
                // XXX: 1.5 migration: replace this line with the commented line
                currentAccessibleValue = new Integer(n.intValue());
                //currentAccessibleValue = Integer.valueOf(n.intValue());
            }
            return true;
        }

        public Number getMinimumAccessibleValue() {
            return MIN_VALUE;
        }

        public Number getMaximumAccessibleValue() {
            return MAX_VALUE;
        }
    }

    /**
     * Children may not be added directly to the internal frame by default.
     * They must be added to its <code>contentPane</code>.
     *
     * @param comp - the component to be added
     * @param constraints - the constraints to be kept
     * @param index - the index
     */
    @Override
    protected void addImpl(final Component comp, final Object constraints, final int index) {
        if (isRootPaneCheckingEnabled()) {
            getContentPane().add(comp, constraints, index);
            return;
        }
        super.addImpl(comp, constraints, index);
    }

    /**
     * Sets the UI object for this component.
     *
     * @param ui the UI object to set
     */
    public void setUI(final InternalFrameUI ui) {
        // setUI() from super (JComponent) should always be called
        // strange manipulations with 'enabled', but they are necessary
        boolean enabled = isRootPaneCheckingEnabled();
        setRootPaneCheckingEnabled(false);
        super.setUI(ui);
        setRootPaneCheckingEnabled(enabled);
    }

    /**
     * Returns the UI object for this component.
     *
     * @return UI object for this component
     */
    public InternalFrameUI getUI() {
        return (InternalFrameUI) ui;
    }

    /**
     * Updates <code>UI's</code> for both <code>JInternalFrame</code>
     * and <code>JDesktopIcon</code>.
     */
    @Override
    public void updateUI() {
      setUI((InternalFrameUI) UIManager.getUI(this));
     
        if (getDesktopIcon() != null) {
            getDesktopIcon().updateUIForIcon();
        }
    }

    /**
     * Removes the internal frame listener.
     *
     * @param l internal frame listener to remove
     */
    public void removeInternalFrameListener(final InternalFrameListener l) {
        listenerList.remove(InternalFrameListener.class, l);
    }

    /**
     * Adds the internal frame listener.
     *
     * @param l internal frame listener to add
     */
    public void addInternalFrameListener(final InternalFrameListener l) {
        listenerList.add(InternalFrameListener.class, l);
    }

    /**
     * Returns all registered internal frame listeners.
     *
     * @return all registered internal frame listeners
     */
    public InternalFrameListener[] getInternalFrameListeners() {
        return listenerList.getListeners(InternalFrameListener.class);
    }

    /**
     * Fires the internal frame event.
     *
     * @param id identifier of the event to fire
     */
    protected void fireInternalFrameEvent(final 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);
                }
                InternalFrameListener l = (InternalFrameListener) listeners[i + 1];
                switch (id) {
                    case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
                        l.internalFrameActivated(e);
                        break;
                    case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
                        l.internalFrameDeactivated(e);
                        break;
                    case InternalFrameEvent.INTERNAL_FRAME_ICONIFIED:
                        l.internalFrameIconified(e);
                        break;
                    case InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED:
                        l.internalFrameDeiconified(e);
                        break;
                    case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
                        l.internalFrameClosing(e);
                        break;
                    case InternalFrameEvent.INTERNAL_FRAME_OPENED:
                        l.internalFrameOpened(e);
                        break;
                    case InternalFrameEvent.INTERNAL_FRAME_CLOSED:
                        l.internalFrameClosed(e);
                        break;
                }
            }
        }
    }

    /**
     * Set rootPane property.
     *
     * @param root the new rootPane property value
     */
    protected void setRootPane(final JRootPane root) {
        JRootPane oldValue = getRootPane();
        if (rootPane != null) {
            remove(rootPane);
        }
        rootPane = root;
        if (root != null) {
            super.addImpl(root, null, 0);
        }
        firePropertyChange(ROOT_PANE_PROPERTY, oldValue, root);
    }

    /**
     * Get rootPane property.
     *
     * @return rootPane property
     */
    @Override
    public JRootPane getRootPane() {
        return rootPane;
    }

    /**
     * Called by the constructors to create the default <code>rootPane</code>
     * property.
     *
     * @return default <code>rootPane</code>
     */
    protected JRootPane createRootPane() {
        return new JRootPane();
    }

    /**
     * @deprecated
     */
    @Deprecated
    public void setMenuBar(final JMenuBar menuBar) {
        setJMenuBar(menuBar);
    }

    /**
     * @deprecated
     */
    @Deprecated
    public JMenuBar getMenuBar() {
        return getJMenuBar();
    }

    /**
     * Sets the menu bar for the frame.
     *
     * @param menuBar the menu bar to be placed in the frame
     */
    public void setJMenuBar(final JMenuBar menuBar) {
        JMenuBar oldValue = getJMenuBar();
        getRootPane().setJMenuBar(menuBar);
        firePropertyChange(MENU_BAR_PROPERTY, oldValue, menuBar);
    }

    /**
     * Returns the menu bar for the frame.
     *
     * @return the menu bar for the frame
     */
    public JMenuBar getJMenuBar() {
        return getRootPane().getJMenuBar();
    }

    /**
     * Sets layeredPane property. This is a bound property.
     *
     * @param layeredPane the new layeredPane property value
     */
    public void setLayeredPane(final JLayeredPane layeredPane) {
        JLayeredPane oldValue = getLayeredPane();
        getRootPane().setLayeredPane(layeredPane);
        firePropertyChange(LAYERED_PANE_PROPERTY, oldValue, layeredPane);
    }

    /**
     * Returns layeredPane property.
     *
     * @return layeredPane property
     */
    public JLayeredPane getLayeredPane() {
        return getRootPane().getLayeredPane();
    }

    /**
     * Sets the desktop icon to be used when the internal frame is iconified.
     *
     * @param icon the desktop icon to be used when the internal frame is
     *             iconified
     */
    public void setDesktopIcon(final JDesktopIcon icon) {
        desktopIcon = icon;
    }

    /**
     * Returns the desktop icon used when the internal frame is iconified.
     *
     * @return  the desktop icon used when the internal frame is iconified
     */
    public JDesktopIcon getDesktopIcon() {
        return desktopIcon;
    }

    /**
     * Returns the desktop pane that contains the internal frame
     * or <code>desktoIcon</code>.
     *
     * @return desktop pane that contains the internal frame or
     * <code>desktoIcon</code>
     */
    public JDesktopPane getDesktopPane() {
        Container result = SwingUtilities.getAncestorOfClass(JDesktopPane.class, this);
        if (result == null) {
            result = SwingUtilities.getAncestorOfClass(JDesktopPane.class, getDesktopIcon());
        }
        return (JDesktopPane) result;
    }

    /**
     * Returns the accessible context for the internal frame.
     *
     * @return the accessible context for the internal frame
     */
    @Override
    public AccessibleContext getAccessibleContext() {
        if (accessibleContext == null) {
            accessibleContext = new AccessibleJInternalFrame();
        }
        return accessibleContext;
    }

    /**
     * Sets the icon to be displayed in the title bar of the internal frame.
     *
     * @param icon the icon to be displayed in the title bar of the internal
     *             frame
     */
    public void setFrameIcon(final Icon icon) {
        Icon oldValue = getFrameIcon();
        frameIcon = icon;
        firePropertyChange(FRAME_ICON_PROPERTY, oldValue, frameIcon);
    }

    /**
     * Returns the icon displayed in the title bar of the internal frame.
     *
     * @return the icon displayed in the title bar of the internal frame
     */
    public Icon getFrameIcon() {
        return frameIcon;
    }

    /**
     * Sets the title of the frame.
     * <code>title</code> can be <code>null</code>.
     * This is a bound property.
     *
     * @param title the title of the frame to be set
     */
    public void setTitle(final String title) {
        String oldValue = getTitle();
        this.title = title;
        firePropertyChange(TITLE_PROPERTY, oldValue, title);
    }

    /**
     * Returns the title of the frame.
     *
     * @return the title of the frame
     */
    public String getTitle() {
        return title;
    }

    /**
     * Returns string representation of this frame.
     *
     * @return string representation of this frame
     */
    @Override
    protected String paramString() {
        return super.paramString();
    }

    /**
     * Gets the warning string that is displayed with this internal frame.
     * Since internal frame is always fully contained within a window, this
     * method always returns <code>null</code>.
     *
     * @return <code>null</code>
     */
    public final String getWarningString() {
        return null;
    }

    /**
     * Returns the name of the L&F class that renders this component.
     *
     * @return the string "InternalFrameUI"
     */
    @Override
    public String getUIClassID() {
        return "InternalFrameUI";
    }

    /**
     * Sets the layer attribute of the internal frame.
     *
     * @param layer the value of layer attribute to be set
     */
    public void setLayer(final Integer layer) {
        setLayer(layer.intValue());
    }

    /**
     * Sets the layer attribute of the internal frame. The method
     * <code>setLayer(Integer)</code> should be used for layer values
     * predefined in <code>JLayeredPane</code>.
     *
     * @param layer the value of layer attribute to be set
     */
    public void setLayer(final int layer) {
        //if (getDesktopPane() == null) {
        if (getParent() instanceof JLayeredPane) {
            ((JLayeredPane) getParent()).setLayer(this, layer);
        } else {
            JLayeredPane.putLayer(this, layer);
        }
    }

    /**
     * Returns the layer attribute of the internal frame.
     *
     * @return the layer attribute of the internal frame
     */
    public int getLayer() {
        return JLayeredPane.getLayer(this);
    }

    /**
     * Sets normal bounds of this internal frame, the bounds that this frame
     * will be restored to from its maximized state.
     *
     * @param rect - normal bounds value
     */
    public void setNormalBounds(final Rectangle rect) {
        normalBounds = rect;
    }

    /**
     * Returns the normal bounds of this internal frame.
     *
     * @return the normal bounds of this internal frame
     */
    public Rectangle getNormalBounds() {
        return normalBounds;
    }

    @Override
    public void setLayout(final LayoutManager layout) {
        if (isRootPaneCheckingEnabled()) {
            getContentPane().setLayout(layout);
        } else {
            super.setLayout(layout);
        }
    }

    /**
     * Is overridden to allow optimized painting when the internal
     * frame is being dragged.
     *
     * @param g the <code>Graphics</code> object to paint
     */
    @Override
    protected void paintComponent(final Graphics g) {
        if (blitSupport != null) {
            blitSupport.onPaint();
        }
        super.paintComponent(g);
    }

    /**
     * Sets contentPane property. This is a bound property.
     *
     * @param contentPane the new contentPane property value
     */
    public void setContentPane(final Container contentPane) {
        Container oldValue = getContentPane();
        getRootPane().setContentPane(contentPane);
        firePropertyChange(CONTENT_PANE_PROPERTY, oldValue, contentPane);
    }

    /**
     * Returns the contentPane property.
     *
     * @return the contentPane property
     */
    public Container getContentPane() {
        return getRootPane().getContentPane();
    }

    /**
     * Set glassPane property. This is a bound property.
     *
     * @param glassPane the new glassPane property value
     */
    public void setGlassPane(final Component glassPane) {
        Component oldValue = getGlassPane();
        getRootPane().setGlassPane(glassPane);
        firePropertyChange(GLASS_PANE_PROPERTY, oldValue, glassPane);
    }

    /**
     * Returns glassPane property.
     *
     * @return glassPane property
     */
    public Component getGlassPane() {
        return getRootPane().getGlassPane();
    }

    @Override
    public void remove(final Component comp) {
        if (comp.getParent() == this) {
            // remove directly from JInternalFrame
            super.remove(comp);
        } else {
            getContentPane().remove(comp);
        }
    }

    /*
     * Remembers the focused component when the internal frame is unselected.
     */
    private void setMostRecentFocusOwner(final Component c) {
        // we really need this 'if' before the assignment.
        // Suppose we have JInternalFrame on
        // JDesktopPane inside of some window, which has JMenu.
        // If the user selects menu, JInternalFrame becomes unselected,
        // but this method is call with c == JRootPane of the global window.
        // We must not remember this component as mostRecentFocusOwner.
        if (this.isAncestorOf(c)) {
            mostRecentFocusOwner = c;
        }
    }

    /**
     * Returns the component that will receive the focus when the
     * internal frame is selected.
     *
     * @return the component that will receive the focus when the
     *         internal frame is selected
     */
    public Component getMostRecentFocusOwner() {
        if (isSelected()) {
            return getFocusOwner();
        }
        if (mostRecentFocusOwner != null) {
            return mostRecentFocusOwner;
        }
        Component result = null;
        if (getFocusTraversalPolicy() instanceof InternalFrameFocusTraversalPolicy) {
            result = ((InternalFrameFocusTraversalPolicy) getFocusTraversalPolicy())
                    .getInitialComponent(this);
        }
        if (result == null) {
            return getFocusTraversalPolicy().getDefaultComponent(this);
        }
        return result;
    }

    /**
     * Returns the component that currently has the focus.
     *
     * @return the component that currently has the focus, if the internal
     *         frame is selected; otherwise returns <code>null</code>
     */
    public Component getFocusOwner() {
        if (!isSelected()) {
            return null;
        }
        Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager()
                .getFocusOwner();
        return isAncestorOf(focusOwner) ? focusOwner : null;
    }

    /**
     * Restores focus to the last subcomponent that had focus.
     */
    public void restoreSubcomponentFocus() {
        Component comp = getMostRecentFocusOwner();
        if (comp != null) {
            comp.requestFocus();
        } else {
            getContentPane().requestFocus();
        }
    }

    /**
     * Selects or deselects the internal frame. If the internal frame is selected,
     * <code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code> event is fired.
     * If the internal frame is deselected,
     * <code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code> event is fired.
     *
     * @param b shows whether select or deselect the internal frame
     *
     * @throws PropertyVetoException if the attempt to set the property is vetoed
     */
    public void setSelected(final boolean b) throws PropertyVetoException {
        if (b && !isShowing() && !getDesktopIcon().isShowing()) {
            return; // can't select if the internal frame is not showing
        }
        if (b == isSelected()) {
            return;
        }
        Boolean oldValue = Boolean.valueOf(isSelected());
        Boolean newValue = Boolean.valueOf(b);
        fireVetoableChange(IS_SELECTED_PROPERTY, oldValue, newValue);
        // remember the focused component for the deactivated frame;
        // recall the last focused component for the activated frame;
        setMostRecentFocusOwner(getMostRecentFocusOwner());
        isSelected = b;
        if (isSelected()) {
            isSelected = false;
            restoreSubcomponentFocus();
            isSelected = true;
        }
        firePropertyChange(IS_SELECTED_PROPERTY, oldValue, newValue);
        // fire internal frame events
        fireInternalFrameEvent(isSelected() ? InternalFrameEvent.INTERNAL_FRAME_ACTIVATED
                : InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
    }

    /**
     * Returns whether the internal frame is selected.
     *
     * @return whether the internal frame is selected
     */
    public boolean isSelected() {
        return isSelected;
    }

    /**
     * Sets <code>rootPaneCheckingEnabled</code> property.
     *
     * @param enabled the new <code>rootPaneCheckingEnabled</code> value
     */
    protected void setRootPaneCheckingEnabled(final boolean enabled) {
        LookAndFeel.markPropertyNotInstallable(this, "rootPaneCheckingEnabled");
        rootPaneCheckingEnabled = enabled;
    }

    /**
     * Returns <code>rootPaneCheckingEnabled</code> value.
     *
     * @return the value of <code>rootPaneCheckingEnabled</code>
     */
    protected boolean isRootPaneCheckingEnabled() {
        return rootPaneCheckingEnabled;
    }

    /**
     * Sets the <code>resizable</code> property.
     *
     * @param b new value for the <code>resizable</code> property
     */
    public void setResizable(final boolean b) {
        boolean oldValue = isResizable();
        resizable = b;
        LookAndFeel.markPropertyNotInstallable(this,
                StringConstants.INTERNAL_FRAME_RESIZABLE_PROPERTY);
        firePropertyChange(StringConstants.INTERNAL_FRAME_RESIZABLE_PROPERTY, oldValue, b);
    }

    /**
     * Get the <code>resizable</code> property value.
     *
     * @return the <code>resizable</code> property value
     */
    public boolean isResizable() {
        return resizable;
    }

    /**
     * Maximizes or restores the internal frame.
     *
     * @param b indicates whether to maximize or restore the internal frame
     *
     * @throws PropertyVetoException
     */
    public void setMaximum(final boolean b) throws PropertyVetoException {
        Boolean oldValue = Boolean.valueOf(isMaximum());
        Boolean newValue = Boolean.valueOf(b);
        fireVetoableChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
        if (b && !isMaximum()) {
            setNormalBounds(getBounds());
        }
        isMaximum = b;
        firePropertyChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
    }

    /**
     * Returns whether the internal frame is currently maximized.
     *
     * @return whether the internal frame is currently maximized
     */
    public boolean isMaximum() {
        return isMaximum;
    }

    /**
     * Sets the <code>maximizable</code> property.
     *
     * @param b the new value for the <code>maximizable</code> property
     */
    public void setMaximizable(final boolean b) {
        boolean oldValue = isMaximizable();
        maximizable = b;
        LookAndFeel.markPropertyNotInstallable(this,
                StringConstants.INTERNAL_FRAME_MAXIMIZABLE_PROPERTY);
        firePropertyChange(StringConstants.INTERNAL_FRAME_MAXIMIZABLE_PROPERTY, oldValue, b);
    }

    /**
     * Get the <code>maximizable</code> property value.
     *
     * @return the <code>maximizable</code> property value
     */
    public boolean isMaximizable() {
        return maximizable;
    }

    /**
     * Sets the <code>iconable</code> property.
     *
     * @param b new value for the <code>iconable</code> property
     */
    public void setIconifiable(final boolean b) {
        boolean oldValue = isIconifiable();
        iconable = b;
        LookAndFeel.markPropertyNotInstallable(this,
                StringConstants.INTERNAL_FRAME_ICONABLE_PROPERTY);
        firePropertyChange(StringConstants.INTERNAL_FRAME_ICONABLE_PROPERTY, oldValue, b);
    }

    /**
     * Get the <code>iconable</code> property value.
     *
     * @return the <code>iconable</code> property value
     */
    public boolean isIconifiable() {
        return iconable;
    }

    /**
     * Iconifies or deiconifies the internal frame, if the L&F supports iconification.
     * If the internal frame state is iconified, this method fires an
     * <code>INTERNAL_FRAME_ICONIFIED</code> event.
     * If the internal frame is deiconified, an <code>INTERNAL_FRAME_DEICONIFIED</code>
     * event is fired.
     *
     * @param b shows whether iconify or deiconify the internal frame
     *
     * @throws PropertyVetoException if the attempt to set the property is vetoed
     */
    public void setIcon(final boolean b) throws PropertyVetoException {
        Boolean oldValue = Boolean.valueOf(isIcon());
        Boolean newValue = Boolean.valueOf(b);
        fireVetoableChange(IS_ICON_PROPERTY, oldValue, newValue);
        isIcon = b;
        firePropertyChange(IS_ICON_PROPERTY, oldValue, newValue);
        // fire internal frame events
        if (oldValue.booleanValue() != b) {
            if (oldValue.booleanValue()) {
                fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
            } else {
                fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
            }
        }
    }

    /**
     * Returns whether the frame is currently iconified.
     *
     * @return whether the frame is currently iconified
     */
    public boolean isIcon() {
        return isIcon;
    }

    /**
     * Does nothing because <code>JInternalFrame</code> must be always
     * a focus cycle root.
     *
     * @param b the value is ignored
     */
    @Override
    public final void setFocusCycleRoot(final boolean b) {
        // do nothing
    }

    /**
     * Always returns true because <code>JInternalFrame</code> is always
     * a focus cycle root.
     *
     * @return true
     */
    @Override
    public final boolean isFocusCycleRoot() {
        return true;
    }

    /**
     * Always returns null because <code>JInternalFrame</code> is always
     * a focus cycle root.
     *
     * @return null
     */
    @Override
    public final Container getFocusCycleRootAncestor() {
        return null;
    }

    /**
     * Closes the internal frame if <code>b</code> is <code>true</code>.
     *
     * @param b must be <code>true</code>
     *
     * @throws PropertyVetoException if the attempt to close the internal frame
     *         is vetoed
     */
    public void setClosed(final boolean b) throws PropertyVetoException {
        if (isClosed() || !b) {
            return;
        }
        fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
        fireVetoableChange(IS_CLOSED_PROPERTY, Boolean.valueOf(isClosed()), Boolean.valueOf(b));
        dispose();
    }

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

    /**
     * Sets the <code>closable</code> property.
     *
     * @param b new value for the <code>closable</code> property
     */
    public void setClosable(final boolean b) {
        boolean oldValue = isClosable();
        closable = b;
        LookAndFeel.markPropertyNotInstallable(this,
                StringConstants.INTERNAL_FRAME_CLOSABLE_PROPERTY);
        firePropertyChange(StringConstants.INTERNAL_FRAME_CLOSABLE_PROPERTY, oldValue, b);
    }

    /**
     * Get the <code>closable</code> property value.
     *
     * @return the <code>closable</code> property value
     */
    public boolean isClosable() {
        return closable;
    }

    /**
     * Sets the <code>defaultCloseOperation</code> property.
     *
     * @param operation the new <code>defaultCloseOperation</code> value
     */
    public void setDefaultCloseOperation(final int operation) {
        defaultCloseOperation = operation;
    }

    /**
     * Returns <code>defaultCloseOperation</code> value.
     *
     * @return the <code>defaultCloseOperation</code> value
     */
    public int getDefaultCloseOperation() {
        return defaultCloseOperation;
    }

    /**
     * Fires an <code>INTERNAL_FRAME_CLOSING</code> event and then performs
     * the action defined by the default close operation.
     */
    public void doDefaultCloseAction() {
        fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
        switch (getDefaultCloseOperation()) {
            case DISPOSE_ON_CLOSE: // dispose
                dispose();
                break;
            case HIDE_ON_CLOSE: // hide
                setVisible(false);
                break;
            case DO_NOTHING_ON_CLOSE: // do nothing
                break;
        }
    }

    /**
     * Moves the internal frame to the position 0 if its parent is
     * <code>JLayeredPane</code>
     */
    public void moveToFront() {
        if (getParent() instanceof JLayeredPane) {
            ((JLayeredPane) getParent()).setPosition(this, 0);
        }
    }

    /**
     * Moves the internal frame to the position -1 if its parent is
     * <code>JLayeredPane</code>
     */
    public void moveToBack() {
        if (getParent() instanceof JLayeredPane) {
            ((JLayeredPane) getParent()).setPosition(this, -1);
        }
    }

    /**
     * Moves the internal frame to the front.
     */
    public void toFront() {
        moveToFront();
        // Note: is there any difference between moveToFront() and toFront()
    }

    /**
     * Moves the internal frame to the back.
     */
    public void toBack() {
        moveToBack();
        // Note: is there any difference between moveToBack() and toBack()
    }

    /**
     * Subcomponents are layed out to their preferred sizes.
     */
    public void pack() {
        setSize(getPreferredSize());
        doLayout();
    }

    /**
     * If the internal frame is not visible, moves it to the front,
     * makes it visible, and attempts to select it. If the internal frame
     * is shown the first time, <code>INTERNAL_FRAME_OPENED</code> event
     * is fired. The method does nothing if the internal frame is already
     * visible.
     */
    @SuppressWarnings("deprecation")
    @Override
    @Deprecated
    public void show() {
        if (isVisible()) {
            return;
        }
        if (blitSupport == null) {
            blitSupport = new BlitSupport(this);
        }
        if (getDesktopIcon() != null) {
            getDesktopIcon().setVisible(true);
        }
        moveToFront();
        // Note: how to set isVisible to true without calling of obsolete method?
        // cannot use super.setVisibile(true) - stack overflow will occur
        super.show();
        try {
            setSelected(true);
        } catch (final PropertyVetoException e) {
        }
        // fire INTERNAL_FRAME_OPENED when opening the first time
        if (firstTimeOpen) {
            fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
            firstTimeOpen = false;
        }
    }

    @SuppressWarnings("deprecation")
    @Override
    @Deprecated
    public void hide() {
        super.hide();
        // the desktop icon becomes visible when the internal frame becomes
        // visible; the same is correct for hiding
        if (getDesktopIcon() != null) {
            getDesktopIcon().setVisible(false);
        }
    }

    /**
     * Makes the internal frame invisible, unselected and closed. If
     * the internal fram was not already closed, <code>INTERNAL_FRAME_CLOSED</code>
     * event is fired.
     */
    public void dispose() {
        setVisible(false);
        try {
            setSelected(false);
        } catch (final PropertyVetoException e) {
        }
        boolean oldValue = isClosed();
        isClosed = true;
        firePropertyChange(IS_CLOSED_PROPERTY, oldValue, true);
        if (!oldValue) {
            fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
        }
    }

    @Override
    public void setBounds(final int x, final int y, final int w, final int h) {
        Dimension oldSize = getSize();
        super.setBounds(x, y, w, h);
        if (oldSize.width != w || oldSize.height != h) {
            validate();
            return;
        }
        if (blitSupport != null) {
            blitSupport.paint();
        }
    }
}
TOP

Related Classes of javax.swing.JInternalFrame$AccessibleJInternalFrame

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.