summaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/swing/DefaultDesktopManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/DefaultDesktopManager.java')
-rw-r--r--libjava/classpath/javax/swing/DefaultDesktopManager.java644
1 files changed, 644 insertions, 0 deletions
diff --git a/libjava/classpath/javax/swing/DefaultDesktopManager.java b/libjava/classpath/javax/swing/DefaultDesktopManager.java
new file mode 100644
index 000000000..9613449ff
--- /dev/null
+++ b/libjava/classpath/javax/swing/DefaultDesktopManager.java
@@ -0,0 +1,644 @@
+/* DefaultDesktopManager.java --
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.beans.PropertyVetoException;
+import java.io.Serializable;
+
+import javax.swing.JInternalFrame.JDesktopIcon;
+
+/**
+ * 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! */
+ private static final long serialVersionUID = 4657624909838017887L;
+
+ /** 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()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * 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();
+ if (c != null)
+ {
+ if (frame.isIcon())
+ c.remove(frame.getDesktopIcon());
+ else
+ c.remove(frame);
+ c.repaint();
+ }
+ }
+
+ /**
+ * 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.
+ }
+ }
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * 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)
+ {
+ // Do nothing if attempt is vetoed.
+ }
+ }
+
+ Container c = frame.getParent();
+
+ if (!wasIcon(frame))
+ {
+ Rectangle r = getBoundsForIconOf(frame);
+ icon.setBounds(r);
+ setWasIcon(frame, Boolean.TRUE);
+ }
+
+ if (c != null)
+ {
+ if (icon != null)
+ {
+ c.add(icon);
+ icon.setVisible(true);
+ }
+ Rectangle b = frame.getBounds();
+ c.remove(frame);
+ c.repaint(b.x, b.y, b.width, b.height);
+ }
+ }
+
+ /**
+ * 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();
+ }
+
+ /**
+ * 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();
+ JInternalFrame active = null;
+ if (p != null)
+ active = p.getSelectedFrame();
+ if (active == null)
+ {
+ if (p != null)
+ {
+ p.setSelectedFrame(frame);
+ }
+ }
+ else if (active != frame)
+ {
+ if (active.isSelected())
+ {
+ try
+ {
+ active.setSelected(false);
+ }
+ catch (PropertyVetoException ex)
+ {
+ // Not allowed.
+ }
+ }
+ if (p != null)
+ {
+ p.setSelectedFrame(frame);
+ }
+
+ }
+ frame.toFront();
+ }
+
+ /**
+ * 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)
+ {
+ // Do nothing if attempt is vetoed.
+ }
+ }
+ }
+
+ /**
+ * 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();
+ }
+
+ /**
+ * 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);
+ }
+ }
+
+ /**
+ * 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();
+ }
+ }
+
+ /**
+ * 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();
+ }
+
+ /**
+ * 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);
+
+ if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE)
+ {
+ // FIXME: Do outline drag painting.
+ }
+ else
+ setBoundsForFrame(component, dragCache.x, dragCache.y, dragCache.width,
+ dragCache.height);
+ }
+
+ /**
+ * 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();
+ }
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * 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)
+ {
+ Rectangle b = icon.getBounds();
+ c.remove(icon);
+ c.repaint(b.x, b.y, b.width, b.height);
+ }
+ }
+
+ /**
+ * 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();
+
+ if (desktopPane == null)
+ return frame.getDesktopIcon().getBounds();
+
+ Rectangle paneBounds = desktopPane.getBounds();
+ Insets insets = desktopPane.getInsets();
+ Dimension pref = frame.getDesktopIcon().getPreferredSize();
+
+ 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;
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * 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();
+ }
+
+ /**
+ * 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.booleanValue(), WAS_ICON_ONCE_PROPERTY);
+ }
+
+ /**
+ * 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();
+ }
+}