diff options
Diffstat (limited to 'libjava/javax/swing/DefaultDesktopManager.java')
-rw-r--r-- | libjava/javax/swing/DefaultDesktopManager.java | 841 |
1 files changed, 605 insertions, 236 deletions
diff --git a/libjava/javax/swing/DefaultDesktopManager.java b/libjava/javax/swing/DefaultDesktopManager.java index f99abef..40b78b8 100644 --- a/libjava/javax/swing/DefaultDesktopManager.java +++ b/libjava/javax/swing/DefaultDesktopManager.java @@ -37,249 +37,618 @@ exception statement from your version. */ package javax.swing; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Insets; import java.awt.Rectangle; +import java.beans.PropertyVetoException; import java.io.Serializable; +import javax.swing.JDesktopPane; +import javax.swing.JInternalFrame; +import javax.swing.JInternalFrame.JDesktopIcon; + /** - * DefaultDesktopManager - * @author Andrew Selkirk - * @version 1.0 + * DefaultDesktopManager is the default implementation of DesktopManager for + * swing. It implements the basic beaviours for JInternalFrames in arbitrary + * parents. The methods provided by the class are not meant to be called by + * the user, instead, the JInternalFrame methods will call these methods. */ public class DefaultDesktopManager implements DesktopManager, Serializable { + /** DOCUMENT ME! */ static final long serialVersionUID = 4657624909838017887L; - //------------------------------------------------------------- - // Variables -------------------------------------------------- - //------------------------------------------------------------- - - /** - * HAS_BEEN_ICONIFIED_PROPERTY - */ - static final String HAS_BEEN_ICONIFIED_PROPERTY = ""; // TODO - - /** - * DEFAULT_DRAG_MODE - */ - static final int DEFAULT_DRAG_MODE = 0; // TODO - - /** - * OUTLINE_DRAG_MODE - */ - static final int OUTLINE_DRAG_MODE = 0; // TODO - - /** - * FASTER_DRAG_MODE - */ - static final int FASTER_DRAG_MODE = 0; // TODO - - /** - * dragMode - */ - int dragMode; - - - //------------------------------------------------------------- - // Initialization --------------------------------------------- - //------------------------------------------------------------- - - /** - * Constructor DefaultDesktopManager - */ - public DefaultDesktopManager() { - // TODO - } // DefaultDesktopManager() - - - //------------------------------------------------------------- - // Methods ---------------------------------------------------- - //------------------------------------------------------------- - - /** - * openFrame - * @param frame TODO - */ - public void openFrame(JInternalFrame frame) { - // TODO - } // openFrame() - - /** - * closeFrame - * @param frame TODO - */ - public void closeFrame(JInternalFrame frame) { - // TODO - } // closeFrame() - - /** - * maximizeFrame - * @param frame TODO - */ - public void maximizeFrame(JInternalFrame frame) { - // TODO - } // maximizeFrame() - - /** - * minimizeFrame - * @param frame TODO - */ - public void minimizeFrame(JInternalFrame frame) { - // TODO - } // minimizeFrame() - - /** - * iconifyFrame - * @param frame TODO - */ - public void iconifyFrame(JInternalFrame frame) { - // TODO - } // iconifyFrame() - - /** - * deiconifyFrame - * @param frame TODO - */ - public void deiconifyFrame(JInternalFrame frame) { - // TODO - } // deiconifyFrame() - - /** - * activateFrame - * @param frame TODO - */ - public void activateFrame(JInternalFrame frame) { - // TODO - } // activateFrame() - - /** - * deactivateFrame - * @param frame TODO - */ - public void deactivateFrame(JInternalFrame frame) { - // TODO - } // deactivateFrame() - - /** - * beginDraggingFrame - * @param component TODO - */ - public void beginDraggingFrame(JComponent component) { - // TODO - } // beginDraggingFrame() - - /** - * dragFrame - * @param component TODO - * @param newX TODO - * @param newY TODO - */ - public void dragFrame(JComponent component, int newX, int newY) { - // TODO - } // dragFrame() - - /** - * endDraggingFrame - * @param component TODO - */ - public void endDraggingFrame(JComponent component) { - // TODO - } // endDraggingFrame() - - /** - * beginResizingFrame - * @param component TODO - * @param direction TODO - */ - public void beginResizingFrame(JComponent component, int direction) { - // TODO - } // beginResizingFrame() - - /** - * resizeFrame - * @param component TODO - * @param newX TODO - * @param newY TODO - * @param newWidth TODO - * @param newHeight TODO - */ - public void resizeFrame(JComponent component, int newX, int newY, - int newWidth, int newHeight) { - // TODO - } // resizeFrame() - - /** - * endResizingFrame - * @param component TODO - */ - public void endResizingFrame(JComponent component) { - // TODO - } // endResizingFrame() - - /** - * setBoundsForFrame - * @param component TODO - * @param newX TODO - * @param newY TODO - * @param newWidth TODO - * @param newHeight TODO - */ - public void setBoundsForFrame(JComponent component, int newX, - int newY, int newWidth, int newHeight) { - // TODO - } // setBoundsForFrame() - - /** - * removeIconFor - * @param frame TODO - */ - protected void removeIconFor(JInternalFrame frame) { - // TODO - } // removeIconFor() - - /** - * getBoundsForIconOf - * @param frame TODO - * @returns Rectangle - */ - protected Rectangle getBoundsForIconOf(JInternalFrame frame) { - return null; // TODO - } // getBoundsForIconOf() - - /** - * setPreviousBounds - * @param frame TODO - * @param rect TODO - */ - protected void setPreviousBounds(JInternalFrame frame, Rectangle rect) { - // TODO - } // setPreviousBounds() - - /** - * getPreviousBounds - * @param frame TODO - * @returns Rectangle - */ - protected Rectangle getPreviousBounds(JInternalFrame frame) { - return null; // TODO - } // getPreviousBounds() - - /** - * setWasIcon - * @param frame TODO - * @param value TODO - */ - protected void setWasIcon(JInternalFrame frame, Boolean value) { - // TODO - } // setWasIcon() - - /** - * wasIcon - * @param frame TODO - * @returns boolean - */ - protected boolean wasIcon(JInternalFrame frame) { - return false; // TODO - } // wasIcon() - - + /** The property change event fired when the wasIcon property changes. */ + static final String WAS_ICON_ONCE_PROPERTY = "wasIconOnce"; + + /** + * The method of dragging used by the JDesktopPane that parents the + * JInternalFrame that is being dragged. + */ + private int currentDragMode = 0; + + /** + * The cache of the bounds used to draw the outline rectangle when + * OUTLINE_DRAG_MODE is used. + */ + private transient Rectangle dragCache = new Rectangle(); + + /** + * A cached JDesktopPane that is stored when the JInternalFrame is initially + * dragged. + */ + private transient Container pane; + + /** + * An array of Rectangles that holds the bounds of the JDesktopIcons in the + * JDesktopPane when looking for where to place a new icon. + */ + private transient Rectangle[] iconRects; + + /** + * This creates a new DefaultDesktopManager object. + */ + public DefaultDesktopManager() + { + } // DefaultDesktopManager() + + /** + * This method is not normally called since the user will typically add the + * JInternalFrame to a Container. If this is called, it will try to + * determine the parent of the JInternalFrame and remove any icon that + * represents this JInternalFrame and add this JInternalFrame. + * + * @param frame The JInternalFrame to open. + */ + public void openFrame(JInternalFrame frame) + { + Container c = frame.getParent(); + if (c == null) + c = frame.getDesktopIcon().getParent(); + if (c == null) + return; + + c.remove(frame.getDesktopIcon()); + c.add(frame); + frame.setVisible(true); + } // openFrame() + + /** + * This method removes the JInternalFrame and JDesktopIcon (if one is + * present) from their parents. + * + * @param frame The JInternalFrame to close. + */ + public void closeFrame(JInternalFrame frame) + { + Container c = frame.getParent(); + frame.doDefaultCloseAction(); + + if (c != null) + { + if (frame.isIcon()) + c.remove(frame.getDesktopIcon()); + else + c.remove(frame); + c.repaint(); + } + } // closeFrame() + + /** + * This method resizes the JInternalFrame to match its parent's bounds. + * + * @param frame The JInternalFrame to maximize. + */ + public void maximizeFrame(JInternalFrame frame) + { + // Can't maximize from iconified state. + // It can only return to maximized state, but that would fall under + // deiconify. + if (frame.isIcon()) + return; + frame.setNormalBounds(frame.getBounds()); + + Container p = frame.getParent(); + if (p != null) + { + Rectangle pBounds = p.getBounds(); + Insets insets = p.getInsets(); + pBounds.width -= insets.left + insets.right; + pBounds.height -= insets.top + insets.bottom; + + setBoundsForFrame(frame, 0, 0, pBounds.width, pBounds.height); + } + if (p instanceof JDesktopPane) + ((JDesktopPane) p).setSelectedFrame(frame); + else + { + try + { + frame.setSelected(true); + } + catch (PropertyVetoException e) + { + // Do nothing. + } + } + } // maximizeFrame() + + /** + * This method restores the JInternalFrame's bounds to what they were + * previous to the setMaximize call. + * + * @param frame The JInternalFrame to minimize. + */ + public void minimizeFrame(JInternalFrame frame) + { + Rectangle normalBounds = frame.getNormalBounds(); + + JDesktopPane p = frame.getDesktopPane(); + if (p != null) + p.setSelectedFrame(frame); + else + { + try + { + frame.setSelected(true); + } + catch (PropertyVetoException e) + { + // Do nothing. + } + } + + setBoundsForFrame(frame, normalBounds.x, normalBounds.y, + normalBounds.width, normalBounds.height); + } // minimizeFrame() + + /** + * This method removes the JInternalFrame from its parent and adds its + * JDesktopIcon representation. + * + * @param frame The JInternalFrame to iconify. + */ + public void iconifyFrame(JInternalFrame frame) + { + JDesktopPane p = frame.getDesktopPane(); + JDesktopIcon icon = frame.getDesktopIcon(); + if (p != null && p.getSelectedFrame() == frame) + p.setSelectedFrame(null); + else + { + try + { + frame.setSelected(false); + } + catch (PropertyVetoException e) + { + } + } + + Container c = frame.getParent(); + + if (! wasIcon(frame)) + { + Rectangle r = getBoundsForIconOf(frame); + icon.setBounds(r); + setWasIcon(frame, true); + } + + if (c != null) + { + if (icon != null) + { + c.add(icon); + icon.setVisible(true); + } + c.remove(frame); + } + } // iconifyFrame() + + /** + * This method removes the JInternalFrame's JDesktopIcon representation and + * adds the JInternalFrame back to its parent. + * + * @param frame The JInternalFrame to deiconify. + */ + public void deiconifyFrame(JInternalFrame frame) + { + JDesktopIcon icon = frame.getDesktopIcon(); + Container c = icon.getParent(); + + removeIconFor(frame); + c.add(frame); + frame.setVisible(true); + + if (! frame.isSelected()) + { + JDesktopPane p = frame.getDesktopPane(); + if (p != null) + p.setSelectedFrame(frame); + else + { + try + { + frame.setSelected(true); + } + catch (PropertyVetoException e) + { + // Do nothing. + } + } + } + + c.invalidate(); + } // deiconifyFrame() + + /** + * This method activates the JInternalFrame by moving it to the front and + * selecting it. + * + * @param frame The JInternalFrame to activate. + */ + public void activateFrame(JInternalFrame frame) + { + JDesktopPane p = frame.getDesktopPane(); + + if (p != null) + p.setSelectedFrame(frame); + else + { + try + { + frame.setSelected(true); + } + catch (PropertyVetoException e) + { + } + } + + frame.toFront(); + } // activateFrame() + + /** + * This method is called when the JInternalFrame loses focus. + * + * @param frame The JInternalFram to deactivate. + */ + public void deactivateFrame(JInternalFrame frame) + { + JDesktopPane p = frame.getDesktopPane(); + if (p != null) + { + if (p.getSelectedFrame() == frame) + p.setSelectedFrame(null); + } + else + { + try + { + frame.setSelected(false); + } + catch (PropertyVetoException e) + { + } + } + } // deactivateFrame() + + /** + * This method is called to indicate that the DesktopManager should prepare + * to drag the JInternalFrame. Any state information needed to drag the + * frame will be prepared now. + * + * @param component The JComponent to drag, usually a JInternalFrame. + */ + public void beginDraggingFrame(JComponent component) + { + if (component instanceof JDesktopIcon) + pane = ((JDesktopIcon) component).getInternalFrame().getDesktopPane(); + else + pane = ((JInternalFrame) component).getDesktopPane(); + if (pane == null) + return; + + dragCache = component.getBounds(); + + if (! (pane instanceof JDesktopPane)) + currentDragMode = JDesktopPane.LIVE_DRAG_MODE; + else + currentDragMode = ((JDesktopPane) pane).getDragMode(); + } // beginDraggingFrame() + + /** + * This method is called to drag the JInternalFrame to a new location. + * + * @param component The JComponent to drag, usually a JInternalFrame. + * @param newX The new x coordinate. + * @param newY The new y coordinate. + */ + public void dragFrame(JComponent component, int newX, int newY) + { + if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE) + { + // FIXME: Do outline drag mode painting. + } + else + { + Rectangle b = component.getBounds(); + if (component instanceof JDesktopIcon) + component.setBounds(newX, newY, b.width, b.height); + else + setBoundsForFrame((JInternalFrame) component, newX, newY, b.width, + b.height); + } + } // dragFrame() + + /** + * This method indicates that the dragging is done. Any state information + * stored by the DesktopManager can be cleared. + * + * @param component The JComponent that has finished dragging. + */ + public void endDraggingFrame(JComponent component) + { + if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE) + { + setBoundsForFrame((JInternalFrame) component, dragCache.x, + dragCache.y, dragCache.width, dragCache.height); + pane = null; + dragCache = null; + } + component.repaint(); + } // endDraggingFrame() + + /** + * This method is called to indicate that the given JComponent will be + * resized. Any state information necessary to resize the JComponent will + * be prepared now. + * + * @param component The JComponent to resize, usually a JInternalFrame. + * @param direction The direction to drag in (a SwingConstant). + */ + public void beginResizingFrame(JComponent component, int direction) + { + pane = ((JInternalFrame) component).getDesktopPane(); + if (pane == null) + return; + + dragCache = component.getBounds(); + if (! (pane instanceof JDesktopPane)) + currentDragMode = JDesktopPane.LIVE_DRAG_MODE; + else + currentDragMode = ((JDesktopPane) pane).getDragMode(); + } // beginResizingFrame() + + /** + * This method resizes the give JComponent. + * + * @param component The JComponent to resize. + * @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 component, int newX, int newY, + int newWidth, int newHeight) + { + dragCache.setBounds(newX, newY, newWidth, newHeight); + dragCache = findMinimum(dragCache, component); + + if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE) + { + // FIXME: Do outline drag painting. + } + else + setBoundsForFrame(component, dragCache.x, dragCache.y, dragCache.width, + dragCache.height); + } // resizeFrame() + + /** + * This method is called to indicate that the given JComponent has finished + * dragging. Any state information stored by the DesktopManager can be + * cleared. + * + * @param component The JComponent that finished resizing. + */ + public void endResizingFrame(JComponent component) + { + if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE) + { + setBoundsForFrame((JInternalFrame) component, dragCache.x, + dragCache.y, dragCache.width, dragCache.height); + pane = null; + dragCache = null; + } + component.repaint(); + } // endResizingFrame() + + /** + * This method calls setBounds with the given parameters and repaints the + * JComponent. + * + * @param component The JComponent to set bounds for. + * @param newX The new x coordinate. + * @param newY The new y coordinate. + * @param newWidth The new width. + * @param newHeight The new height. + */ + public void setBoundsForFrame(JComponent component, int newX, int newY, + int newWidth, int newHeight) + { + component.setBounds(newX, newY, newWidth, newHeight); + component.revalidate(); + + // If not null, I'd rather repaint the parent + if (component.getParent() != null) + component.getParent().repaint(); + else + component.repaint(); + } // setBoundsForFrame() + + /** + * This is a helper method that removes the JDesktopIcon of the given + * JInternalFrame from the parent. + * + * @param frame The JInternalFrame to remove an icon for. + */ + protected void removeIconFor(JInternalFrame frame) + { + JDesktopIcon icon = frame.getDesktopIcon(); + Container c = icon.getParent(); + if (c != null && icon != null) + c.remove(icon); + } // removeIconFor() + + /** + * This method is called by iconifyFrame to determine the bounds of the + * JDesktopIcon for the given JInternalFrame. + * + * @param frame The JInternalFrame to find the bounds of its JDesktopIcon + * for. + * + * @return The bounds of the JDesktopIcon. + */ + protected Rectangle getBoundsForIconOf(JInternalFrame frame) + { + // IconRects has no order to it. + // The icon _must_ be placed in the first free slot (working from + // the bottom left corner) + // The icon also must not be placed where another icon is placed + // (regardless whether that frame is an icon currently or not) + JDesktopPane desktopPane = frame.getDesktopPane(); + Rectangle paneBounds = desktopPane.getBounds(); + Insets insets = desktopPane.getInsets(); + Dimension pref = frame.getDesktopIcon().getPreferredSize(); + + if (desktopPane == null) + return frame.getDesktopIcon().getBounds(); + + Component[] frames = desktopPane.getComponents(); + + int count = 0; + for (int i = 0, j = 0; i < frames.length; i++) + if (frames[i] instanceof JDesktopIcon + || frames[i] instanceof JInternalFrame + && ((JInternalFrame) frames[i]).getWasIcon() && frames[i] != frame) + count++; + iconRects = new Rectangle[count]; + for (int i = 0, j = 0; i < frames.length; i++) + if (frames[i] instanceof JDesktopIcon) + iconRects[--count] = frames[i].getBounds(); + else if (frames[i] instanceof JInternalFrame + && ((JInternalFrame) frames[i]).getWasIcon() + && frames[i] != frame) + iconRects[--count] = ((JInternalFrame) frames[i]).getDesktopIcon() + .getBounds(); + + int startingX = insets.left; + int startingY = paneBounds.height - insets.bottom - pref.height; + Rectangle ideal = new Rectangle(startingX, startingY, pref.width, + pref.height); + boolean clear = true; + + while (iconRects.length > 0) + { + clear = true; + for (int i = 0; i < iconRects.length; i++) + { + if (iconRects[i] != null && iconRects[i].intersects(ideal)) + { + clear = false; + break; + } + } + if (clear) + return ideal; + + startingX += pref.width; + if (startingX + pref.width > paneBounds.width - insets.right) + { + startingX = insets.left; + startingY -= pref.height; + } + ideal.setBounds(startingX, startingY, pref.width, pref.height); + } + + return ideal; + } // getBoundsForIconOf() + + /** + * This method sets the bounds of the JInternalFrame right before the + * maximizeFrame call. + * + * @param frame The JInternalFrame being maximized. + * @param rect The normal bounds. + */ + protected void setPreviousBounds(JInternalFrame frame, Rectangle rect) + { + frame.setNormalBounds(rect); + } // setPreviousBounds() + + /** + * This method returns the normal bounds of the JInternalFrame from before + * the maximize call. + * + * @param frame The JInternalFrame that is being restored. + * + * @return The previous bounds of the JInternalFrame. + */ + protected Rectangle getPreviousBounds(JInternalFrame frame) + { + return frame.getNormalBounds(); + } // getPreviousBounds() + + /** + * This method sets the value to true if the given JInternalFrame has been + * iconized and the bounds of its DesktopIcon are valid. + * + * @param frame The JInternalFrame for the JDesktopIcon. + * @param value True if the JInternalFrame has been iconized and the bounds + * of the JDesktopIcon are valid. + */ + protected void setWasIcon(JInternalFrame frame, boolean value) + { + frame.setWasIcon(value, WAS_ICON_ONCE_PROPERTY); + } // setWasIcon() + + /** + * This method returns true if the given JInternalFrame has been iconized + * and the bounds of its DesktopIcon are valid. + * + * @param frame The JInternalFrame for the JDesktopIcon. + * + * @return True if the given JInternalFrame has been iconized and the bounds + * of its DesktopIcon are valid. + */ + protected boolean wasIcon(JInternalFrame frame) + { + return frame.getWasIcon(); + } // wasIcon() + + /** + * This is a helper method that determines the minimum size a + * JInternalFrame can be resized to. + * + * @param r The desired size. + * @param c The JComponent to find a minimum size for. + * + * @return The minimum size a JInternalFrame can be resized to. + */ + private Rectangle findMinimum(Rectangle r, JComponent c) + { + if (r != null && c != null) + { + Dimension d = c.getPreferredSize(); + if (d != null) + { + r.width = Math.max(d.width, r.width); + r.height = Math.max(d.height, r.height); + } + } + return r; + } } // DefaultDesktopManager |