807 lines · 28.2 KB · Java
RawDownload
/* * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */  package javax.swing; import com.sun.awt.AWTUtilities;import sun.awt.AWTAccessor;import sun.awt.SunToolkit; import java.awt.*;import java.beans.PropertyVetoException; /** This is an implementation of the <code>DesktopManager</code>.  * It currently implements the basic behaviors for managing  * <code>JInternalFrame</code>s in an arbitrary parent.  * <code>JInternalFrame</code>s that are not children of a  * <code>JDesktop</code> will use this component  * to handle their desktop-like actions.  * <p>This class provides a policy for the various JInternalFrame methods,  * it is not meant to be called directly rather the various JInternalFrame  * methods will call into the DesktopManager.</p>  * @see JDesktopPane  * @see JInternalFrame  * @author David Kloba  * @author Steve Wilson  */public class DefaultDesktopManager implements DesktopManager, java.io.Serializable {    final static String HAS_BEEN_ICONIFIED_PROPERTY = "wasIconOnce";     final static int DEFAULT_DRAG_MODE = 0;    final static int OUTLINE_DRAG_MODE = 1;    final static int FASTER_DRAG_MODE = 2;     int dragMode = DEFAULT_DRAG_MODE;     private transient Rectangle currentBounds = null;    private transient Graphics desktopGraphics = null;    private transient Rectangle desktopBounds = null;    private transient Rectangle[] floatingItems = {};     /**     * Set to true when the user actually drags a frame vs clicks on it     * to start the drag operation.  This is only used when dragging with     * FASTER_DRAG_MODE.     */    private transient boolean didDrag;     /** Normally this method will not be called. If it is, it      * try to determine the appropriate parent from the desktopIcon of the frame.      * Will remove the desktopIcon from its parent if it successfully adds the frame.      */    public void openFrame(JInternalFrame f) {        if(f.getDesktopIcon().getParent() != null) {            f.getDesktopIcon().getParent().add(f);            removeIconFor(f);        }    }     /**     * Removes the frame, and, if necessary, the     * <code>desktopIcon</code>, from its parent.     * @param f the <code>JInternalFrame</code> to be removed     */    public void closeFrame(JInternalFrame f) {        JDesktopPane d = f.getDesktopPane();        if (d == null) {            return;        }        boolean findNext = f.isSelected();        Container c = f.getParent();        JInternalFrame nextFrame = null;        if (findNext) {            nextFrame = d.getNextFrame(f);            try { f.setSelected(false); } catch (PropertyVetoException e2) { }        }        if(c != null) {            c.remove(f); // Removes the focus.            c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight());        }        removeIconFor(f);        if(f.getNormalBounds() != null)            f.setNormalBounds(null);        if(wasIcon(f))            setWasIcon(f, null);        if (nextFrame != null) {            try { nextFrame.setSelected(true); }            catch (PropertyVetoException e2) { }        } else if (findNext && d.getComponentCount() == 0) {            // It was selected and was the last component on the desktop.            d.requestFocus();        }    }     /**     * Resizes the frame to fill its parents bounds.     * @param f the frame to be resized     */    public void maximizeFrame(JInternalFrame f) {        if (f.isIcon()) {            try {                // In turn calls deiconifyFrame in the desktop manager.                // That method will handle the maximization of the frame.                f.setIcon(false);            } catch (PropertyVetoException e2) {            }        } else {            f.setNormalBounds(f.getBounds());            Rectangle desktopBounds = f.getParent().getBounds();            setBoundsForFrame(f, 0, 0,                desktopBounds.width, desktopBounds.height);        }         // Set the maximized frame as selected.        try {            f.setSelected(true);        } catch (PropertyVetoException e2) {        }    }     /**     * Restores the frame back to its size and position prior     * to a <code>maximizeFrame</code> call.     * @param f the <code>JInternalFrame</code> to be restored     */    public void minimizeFrame(JInternalFrame f) {        // If the frame was an icon restore it back to an icon.        if (f.isIcon()) {            iconifyFrame(f);            return;        }         if ((f.getNormalBounds()) != null) {            Rectangle r = f.getNormalBounds();            f.setNormalBounds(null);            try { f.setSelected(true); } catch (PropertyVetoException e2) { }            setBoundsForFrame(f, r.x, r.y, r.width, r.height);        }    }     /**     * Removes the frame from its parent and adds its     * <code>desktopIcon</code> to the parent.     * @param f the <code>JInternalFrame</code> to be iconified     */    public void iconifyFrame(JInternalFrame f) {        JInternalFrame.JDesktopIcon desktopIcon;        Container c = f.getParent();        JDesktopPane d = f.getDesktopPane();        boolean findNext = f.isSelected();        desktopIcon = f.getDesktopIcon();        if(!wasIcon(f)) {            Rectangle r = getBoundsForIconOf(f);            desktopIcon.setBounds(r.x, r.y, r.width, r.height);            // we must validate the hierarchy to not break the hw/lw mixing            desktopIcon.revalidate();            setWasIcon(f, Boolean.TRUE);        }         if (c == null || d == null) {            return;        }         if (c instanceof JLayeredPane) {            JLayeredPane lp = (JLayeredPane)c;            int layer = lp.getLayer(f);            lp.putLayer(desktopIcon, layer);        }         // If we are maximized we already have the normal bounds recorded        // don't try to re-record them, otherwise we incorrectly set the        // normal bounds to maximized state.        if (!f.isMaximum()) {            f.setNormalBounds(f.getBounds());        }        d.setComponentOrderCheckingEnabled(false);        c.remove(f);        c.add(desktopIcon);        d.setComponentOrderCheckingEnabled(true);        c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight());        if (findNext) {            if (d.selectFrame(true) == null) {                // The icon is the last frame.                f.restoreSubcomponentFocus();            }        }    }     /**     * Removes the desktopIcon from its parent and adds its frame     * to the parent.     * @param f the <code>JInternalFrame</code> to be de-iconified     */    public void deiconifyFrame(JInternalFrame f) {        JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon();        Container c = desktopIcon.getParent();        JDesktopPane d = f.getDesktopPane();        if (c != null && d != null) {            c.add(f);            // If the frame is to be restored to a maximized state make            // sure it still fills the whole desktop.            if (f.isMaximum()) {                Rectangle desktopBounds = c.getBounds();                if (f.getWidth() != desktopBounds.width ||                        f.getHeight() != desktopBounds.height) {                    setBoundsForFrame(f, 0, 0,                        desktopBounds.width, desktopBounds.height);                }            }            removeIconFor(f);            if (f.isSelected()) {                f.moveToFront();                f.restoreSubcomponentFocus();            }            else {                try {                    f.setSelected(true);                } catch (PropertyVetoException e2) {}             }        }    }     /** This will activate <b>f</b> moving it to the front. It will      * set the current active frame's (if any)      * <code>IS_SELECTED_PROPERTY</code> to <code>false</code>.      * There can be only one active frame across all Layers.      * @param f the <code>JInternalFrame</code> to be activated      */    public void activateFrame(JInternalFrame f) {        Container p = f.getParent();        Component[] c;        JDesktopPane d = f.getDesktopPane();        JInternalFrame currentlyActiveFrame =          (d == null) ? null : d.getSelectedFrame();        // fix for bug: 4162443        if(p == null) {            // If the frame is not in parent, its icon maybe, check it            p = f.getDesktopIcon().getParent();            if(p == null)                return;        }        // we only need to keep track of the currentActive InternalFrame, if any        if (currentlyActiveFrame == null){          if (d != null) { d.setSelectedFrame(f);}        } else if (currentlyActiveFrame != f) {          // if not the same frame as the current active          // we deactivate the current          if (currentlyActiveFrame.isSelected()) {            try {              currentlyActiveFrame.setSelected(false);            }            catch(PropertyVetoException e2) {}          }          if (d != null) { d.setSelectedFrame(f);}        }        f.moveToFront();    }     // implements javax.swing.DesktopManager    public void deactivateFrame(JInternalFrame f) {      JDesktopPane d = f.getDesktopPane();      JInternalFrame currentlyActiveFrame =          (d == null) ? null : d.getSelectedFrame();      if (currentlyActiveFrame == f)        d.setSelectedFrame(null);    }     // implements javax.swing.DesktopManager    public void beginDraggingFrame(JComponent f) {        setupDragMode(f);         if (dragMode == FASTER_DRAG_MODE) {          Component desktop = f.getParent();          floatingItems = findFloatingItems(f);          currentBounds = f.getBounds();          if (desktop instanceof JComponent) {              desktopBounds = ((JComponent)desktop).getVisibleRect();          }          else {              desktopBounds = desktop.getBounds();              desktopBounds.x = desktopBounds.y = 0;          }          desktopGraphics = JComponent.safelyGetGraphics(desktop);          ((JInternalFrame)f).isDragging = true;          didDrag = false;        }     }     private void setupDragMode(JComponent f) {        JDesktopPane p = getDesktopPane(f);        Container parent = f.getParent();        dragMode = DEFAULT_DRAG_MODE;        if (p != null) {            String mode = (String)p.getClientProperty("JDesktopPane.dragMode");            Window window = SwingUtilities.getWindowAncestor(f);            if (window != null && !AWTUtilities.isWindowOpaque(window)) {                dragMode = DEFAULT_DRAG_MODE;            } else if (mode != null && mode.equals("outline")) {                dragMode = OUTLINE_DRAG_MODE;            } else if (mode != null && mode.equals("faster")                    && f instanceof JInternalFrame                    && ((JInternalFrame)f).isOpaque() &&                       (parent == null || parent.isOpaque())) {                dragMode = FASTER_DRAG_MODE;            } else {                if (p.getDragMode() == JDesktopPane.OUTLINE_DRAG_MODE ) {                    dragMode = OUTLINE_DRAG_MODE;                } else if ( p.getDragMode() == JDesktopPane.LIVE_DRAG_MODE                        && f instanceof JInternalFrame                        && ((JInternalFrame)f).isOpaque()) {                    dragMode = FASTER_DRAG_MODE;                } else {                    dragMode = DEFAULT_DRAG_MODE;                }            }        }    }     private transient Point currentLoc = null;     /**      * Moves the visible location of the frame being dragged      * to the location specified.  The means by which this occurs can vary depending      * on the dragging algorithm being used.  The actual logical location of the frame      * might not change until <code>endDraggingFrame</code> is called.      */    public void dragFrame(JComponent f, int newX, int newY) {         if (dragMode == OUTLINE_DRAG_MODE) {            JDesktopPane desktopPane = getDesktopPane(f);            if (desktopPane != null){              Graphics g = JComponent.safelyGetGraphics(desktopPane);               g.setXORMode(Color.white);              if (currentLoc != null) {                g.drawRect(currentLoc.x, currentLoc.y,                        f.getWidth()-1, f.getHeight()-1);              }              g.drawRect( newX, newY, f.getWidth()-1, f.getHeight()-1);              /* Work around for 6635462: XOR mode may cause a SurfaceLost on first use.              * Swing doesn't expect that its XOR drawRect did              * not complete, so believes that on re-entering at              * the next update location, that there is an XOR rect              * to draw out at "currentLoc". But in fact              * its now got a new clean surface without that rect,              * so drawing it "out" in fact draws it on, leaving garbage.              * So only update/set currentLoc if the draw completed.              */              sun.java2d.SurfaceData sData =                  ((sun.java2d.SunGraphics2D)g).getSurfaceData();               if (!sData.isSurfaceLost()) {                  currentLoc = new Point (newX, newY);              };              g.dispose();            }        } else if (dragMode == FASTER_DRAG_MODE) {            dragFrameFaster(f, newX, newY);        } else {            setBoundsForFrame(f, newX, newY, f.getWidth(), f.getHeight());        }    }     // implements javax.swing.DesktopManager    public void endDraggingFrame(JComponent f) {        if ( dragMode == OUTLINE_DRAG_MODE && currentLoc != null) {            setBoundsForFrame(f, currentLoc.x, currentLoc.y, f.getWidth(), f.getHeight() );            currentLoc = null;        } else if (dragMode == FASTER_DRAG_MODE) {            currentBounds = null;            if (desktopGraphics != null) {                desktopGraphics.dispose();                desktopGraphics = null;            }            desktopBounds = null;            ((JInternalFrame)f).isDragging = false;        }    }     // implements javax.swing.DesktopManager    public void beginResizingFrame(JComponent f, int direction) {        setupDragMode(f);    }     /**     * Calls <code>setBoundsForFrame</code> with the new values.     * @param f the component to be resized     * @param newX the new x-coordinate     * @param newY the new y-coordinate     * @param newWidth the new width     * @param newHeight the new height     */    public void resizeFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {         if ( dragMode == DEFAULT_DRAG_MODE || dragMode == FASTER_DRAG_MODE ) {            setBoundsForFrame(f, newX, newY, newWidth, newHeight);        } else {            JDesktopPane desktopPane = getDesktopPane(f);            if (desktopPane != null){              Graphics g = JComponent.safelyGetGraphics(desktopPane);               g.setXORMode(Color.white);              if (currentBounds != null) {                g.drawRect( currentBounds.x, currentBounds.y, currentBounds.width-1, currentBounds.height-1);              }              g.drawRect( newX, newY, newWidth-1, newHeight-1);               // Work around for 6635462, see comment in dragFrame()              sun.java2d.SurfaceData sData =                  ((sun.java2d.SunGraphics2D)g).getSurfaceData();              if (!sData.isSurfaceLost()) {                  currentBounds = new Rectangle (newX, newY, newWidth, newHeight);              }               g.setPaintMode();              g.dispose();            }        }     }     // implements javax.swing.DesktopManager    public void endResizingFrame(JComponent f) {        if ( dragMode == OUTLINE_DRAG_MODE && currentBounds != null) {            setBoundsForFrame(f, currentBounds.x, currentBounds.y, currentBounds.width, currentBounds.height );            currentBounds = null;        }    }      /** This moves the <code>JComponent</code> and repaints the damaged areas. */    public void setBoundsForFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {        f.setBounds(newX, newY, newWidth, newHeight);        // we must validate the hierarchy to not break the hw/lw mixing        f.revalidate();    }     /** Convenience method to remove the desktopIcon of <b>f</b> is necessary. */    protected void removeIconFor(JInternalFrame f) {        JInternalFrame.JDesktopIcon di = f.getDesktopIcon();        Container c = di.getParent();        if(c != null) {            c.remove(di);            c.repaint(di.getX(), di.getY(), di.getWidth(), di.getHeight());        }    }     /** The iconifyFrame() code calls this to determine the proper bounds      * for the desktopIcon.      */     protected Rectangle getBoundsForIconOf(JInternalFrame f) {      //      // Get the icon for this internal frame and its preferred size      //       JInternalFrame.JDesktopIcon icon = f.getDesktopIcon();      Dimension prefSize = icon.getPreferredSize();      //      // Get the parent bounds and child components.      //       Container c = f.getParent();      if (c == null) {          c = f.getDesktopIcon().getParent();      }       if (c == null) {        /* the frame has not yet been added to the parent; how about (0,0) ?*/        return new Rectangle(0, 0, prefSize.width, prefSize.height);      }       Rectangle parentBounds = c.getBounds();      Component [] components = c.getComponents(); 

Lines 1–500 of 807.