summaryrefslogtreecommitdiff
path: root/libjava/classpath/java/awt/CardLayout.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/java/awt/CardLayout.java')
-rw-r--r--libjava/classpath/java/awt/CardLayout.java483
1 files changed, 483 insertions, 0 deletions
diff --git a/libjava/classpath/java/awt/CardLayout.java b/libjava/classpath/java/awt/CardLayout.java
new file mode 100644
index 00000000000..8582c5f099b
--- /dev/null
+++ b/libjava/classpath/java/awt/CardLayout.java
@@ -0,0 +1,483 @@
+/* CardLayout.java -- Card-based layout engine
+ Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation
+
+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 java.awt;
+
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * This class implements a card-based layout scheme. Each included
+ * component is treated as a card. Only one card can be shown at a
+ * time. This class includes methods for changing which card is
+ * shown.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class CardLayout implements LayoutManager2, Serializable
+{
+ private static final long serialVersionUID = -4328196481005934313L;
+
+ /**
+ * Initializes a new instance of <code>CardLayout</code> with horizontal
+ * and vertical gaps of 0.
+ */
+ public CardLayout ()
+ {
+ this (0, 0);
+ }
+
+ /**
+ * Create a new <code>CardLayout</code> object with the specified
+ * horizontal and vertical gaps.
+ *
+ * @param hgap The horizontal gap
+ * @param vgap The vertical gap
+ */
+ public CardLayout (int hgap, int vgap)
+ {
+ this.hgap = hgap;
+ this.vgap = vgap;
+ this.tab = new Hashtable ();
+ }
+
+ /**
+ * Add a new component to the layout. The constraint must be a
+ * string which is used to name the component. This string can
+ * later be used to refer to the particular component.
+ *
+ * @param comp The component to add
+ * @param constraints The name by which the component can later be called
+ *
+ * @exception IllegalArgumentException If `constraints' is not a
+ * <code>String</code>
+ */
+ public void addLayoutComponent (Component comp, Object constraints)
+ {
+ if (! (constraints instanceof String))
+ throw new IllegalArgumentException ("Object " + constraints
+ + " is not a string");
+ addLayoutComponent ((String) constraints, comp);
+ }
+
+ /**
+ * Add a new component to the layout. The name can be used later
+ * to refer to the component.
+ *
+ * @param name The name by which the component can later be called
+ * @param comp The component to add
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>addLayoutComponent(Component, Object)</code>.
+ */
+ public void addLayoutComponent (String name, Component comp)
+ {
+ tab.put (name, comp);
+ // First component added is the default component.
+ comp.setVisible(tab.size() == 1);
+ }
+
+ /**
+ * Cause the first component in the container to be displayed.
+ *
+ * @param parent The parent container
+ */
+ public void first (Container parent)
+ {
+ gotoComponent (parent, FIRST);
+ }
+
+ /**
+ * Return this layout manager's horizontal gap.
+ *
+ * @return the horizontal gap
+ */
+ public int getHgap ()
+ {
+ return hgap;
+ }
+
+ /**
+ * Return this layout manager's x alignment. This method always
+ * returns Component.CENTER_ALIGNMENT.
+ *
+ * @param parent Container using this layout manager instance
+ *
+ * @return the x-axis alignment
+ */
+ public float getLayoutAlignmentX (Container parent)
+ {
+ return Component.CENTER_ALIGNMENT;
+ }
+
+ /**
+ * Returns this layout manager's y alignment. This method always
+ * returns Component.CENTER_ALIGNMENT.
+ *
+ * @param parent Container using this layout manager instance
+ *
+ * @return the y-axis alignment
+ */
+ public float getLayoutAlignmentY (Container parent)
+ {
+ return Component.CENTER_ALIGNMENT;
+ }
+
+ /**
+ * Return this layout manager's vertical gap.
+ *
+ * @return the vertical gap
+ */
+ public int getVgap ()
+ {
+ return vgap;
+ }
+
+ /**
+ * Invalidate this layout manager's state.
+ */
+ public void invalidateLayout (Container target)
+ {
+ // Do nothing.
+ }
+
+ /**
+ * Cause the last component in the container to be displayed.
+ *
+ * @param parent The parent container
+ */
+ public void last (Container parent)
+ {
+ gotoComponent (parent, LAST);
+ }
+
+ /**
+ * Lays out the container. This is done by resizing the child components
+ * to be the same size as the parent, less insets and gaps.
+ *
+ * @param parent The parent container.
+ */
+ public void layoutContainer (Container parent)
+ {
+ synchronized (parent.getTreeLock ())
+ {
+ int width = parent.width;
+ int height = parent.height;
+
+ Insets ins = parent.getInsets ();
+
+ int num = parent.ncomponents;
+ Component[] comps = parent.component;
+
+ int x = ins.left + hgap;
+ int y = ins.top + vgap;
+ width = width - 2 * hgap - ins.left - ins.right;
+ height = height - 2 * vgap - ins.top - ins.bottom;
+
+ for (int i = 0; i < num; ++i)
+ comps[i].setBounds (x, y, width, height);
+ }
+ }
+
+ /**
+ * Get the maximum layout size of the container.
+ *
+ * @param target The parent container
+ *
+ * @return the maximum layout size
+ */
+ public Dimension maximumLayoutSize (Container target)
+ {
+ // The JCL says that this returns Integer.MAX_VALUE for both
+ // dimensions. But that just seems wrong to me.
+ return getSize (target, MAX);
+ }
+
+ /**
+ * Get the minimum layout size of the container.
+ *
+ * @param target The parent container
+ *
+ * @return the minimum layout size
+ */
+ public Dimension minimumLayoutSize (Container target)
+ {
+ return getSize (target, MIN);
+ }
+
+ /**
+ * Cause the next component in the container to be displayed. If
+ * this current card is the last one in the deck, the first
+ * component is displayed.
+ *
+ * @param parent The parent container
+ */
+ public void next (Container parent)
+ {
+ gotoComponent (parent, NEXT);
+ }
+
+ /**
+ * Get the preferred layout size of the container.
+ *
+ * @param parent The parent container
+ *
+ * @return the preferred layout size
+ */
+ public Dimension preferredLayoutSize (Container parent)
+ {
+ return getSize (parent, PREF);
+ }
+
+ /**
+ * Cause the previous component in the container to be displayed.
+ * If this current card is the first one in the deck, the last
+ * component is displayed.
+ *
+ * @param parent The parent container
+ */
+ public void previous (Container parent)
+ {
+ gotoComponent (parent, PREV);
+ }
+
+ /**
+ * Remove the indicated component from this layout manager.
+ *
+ * @param comp The component to remove
+ */
+ public void removeLayoutComponent (Component comp)
+ {
+ Enumeration e = tab.keys ();
+ while (e.hasMoreElements ())
+ {
+ Object key = e.nextElement ();
+ if (tab.get (key) == comp)
+ {
+ tab.remove (key);
+ Container parent = comp.getParent();
+ next(parent);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Set this layout manager's horizontal gap.
+ *
+ * @param hgap The new gap
+ */
+ public void setHgap (int hgap)
+ {
+ this.hgap = hgap;
+ }
+
+ /**
+ * Set this layout manager's vertical gap.
+ *
+ * @param vgap The new gap
+ */
+ public void setVgap (int vgap)
+ {
+ this.vgap = vgap;
+ }
+
+ /**
+ * Cause the named component to be shown. If the component name is
+ * unknown, this method does nothing.
+ *
+ * @param parent The parent container
+ * @param name The name of the component to show
+ */
+ public void show (Container parent, String name)
+ {
+ Object target = tab.get (name);
+ if (target != null)
+ {
+ int num = parent.ncomponents;
+ // This is more efficient than calling getComponents().
+ Component[] comps = parent.component;
+ for (int i = 0; i < num; ++i)
+ {
+ if (comps[i].isVisible())
+ {
+ if (target == comps[i])
+ return;
+ comps[i].setVisible (false);
+ }
+ }
+ ((Component) target).setVisible (true);
+ }
+ }
+
+ /**
+ * Returns a string representation of this layout manager.
+ *
+ * @return A string representation of this object.
+ */
+ public String toString ()
+ {
+ return getClass ().getName () + "[" + hgap + "," + vgap + "]";
+ }
+
+ /**
+ * This implements first(), last(), next(), and previous().
+ *
+ * @param parent The parent container
+ * @param what The type of goto: FIRST, LAST, NEXT or PREV
+ */
+ private void gotoComponent (Container parent, int what)
+ {
+ synchronized (parent.getTreeLock ())
+ {
+ int num = parent.ncomponents;
+ // This is more efficient than calling getComponents().
+ Component[] comps = parent.component;
+
+ if (num == 1)
+ {
+ comps[0].setVisible(true);
+ return;
+ }
+
+ int choice = -1;
+
+ if (what == FIRST)
+ choice = 0;
+ else if (what == LAST)
+ choice = num - 1;
+
+ for (int i = 0; i < num; ++i)
+ {
+ if (comps[i].isVisible ())
+ {
+ if (what == NEXT)
+ {
+ choice = i + 1;
+ if (choice == num)
+ choice = 0;
+ }
+ else if (what == PREV)
+ {
+ choice = i - 1;
+ if (choice < 0)
+ choice = num - 1;
+ }
+ else if (choice == i)
+ {
+ // Do nothing if we're already looking at the right
+ // component.
+ return;
+ }
+ comps[i].setVisible (false);
+
+ if (choice >= 0)
+ break;
+ }
+ }
+
+ if (choice >= 0 && choice < num)
+ comps[choice].setVisible (true);
+ }
+ }
+
+ // Compute the size according to WHAT.
+ private Dimension getSize (Container parent, int what)
+ {
+ synchronized (parent.getTreeLock ())
+ {
+ int w = 0, h = 0, num = parent.ncomponents;
+ Component[] comps = parent.component;
+
+ for (int i = 0; i < num; ++i)
+ {
+ Dimension d;
+
+ if (what == MIN)
+ d = comps[i].getMinimumSize ();
+ else if (what == MAX)
+ d = comps[i].getMaximumSize ();
+ else
+ d = comps[i].getPreferredSize ();
+
+ w = Math.max (d.width, w);
+ h = Math.max (d.height, h);
+ }
+
+ Insets i = parent.getInsets ();
+ w += 2 * hgap + i.right + i.left;
+ h += 2 * vgap + i.bottom + i.top;
+
+ // Handle overflow.
+ if (w < 0)
+ w = Integer.MAX_VALUE;
+ if (h < 0)
+ h = Integer.MAX_VALUE;
+
+ return new Dimension (w, h);
+ }
+ }
+
+ /**
+ * @serial Horizontal gap value.
+ */
+ private int hgap;
+
+ /**
+ * @serial Vertical gap value.
+ */
+ private int vgap;
+
+ /**
+ * @serial Table of named components.
+ */
+ private Hashtable tab;
+
+ // These constants are used by the private gotoComponent method.
+ private static final int FIRST = 0;
+ private static final int LAST = 1;
+ private static final int NEXT = 2;
+ private static final int PREV = 3;
+
+ // These constants are used by the private getSize method.
+ private static final int MIN = 0;
+ private static final int MAX = 1;
+ private static final int PREF = 2;
+}