Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / java / awt / CardLayout.java
blob8b3fea2ca23b4c21fe99461d7ead984a11148d9b
1 /* CardLayout.java -- Card-based layout engine
2 Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package java.awt;
41 import java.io.Serializable;
42 import java.util.Enumeration;
43 import java.util.Hashtable;
45 /**
46 * This class implements a card-based layout scheme. Each included
47 * component is treated as a card. Only one card can be shown at a
48 * time. This class includes methods for changing which card is
49 * shown.
51 * @author Tom Tromey (tromey@redhat.com)
52 * @author Aaron M. Renn (arenn@urbanophile.com)
54 public class CardLayout implements LayoutManager2, Serializable
56 private static final long serialVersionUID = -4328196481005934313L;
58 /**
59 * Initializes a new instance of <code>CardLayout</code> with horizontal
60 * and vertical gaps of 0.
62 public CardLayout ()
64 this (0, 0);
67 /**
68 * Create a new <code>CardLayout</code> object with the specified
69 * horizontal and vertical gaps.
71 * @param hgap The horizontal gap
72 * @param vgap The vertical gap
74 public CardLayout (int hgap, int vgap)
76 this.hgap = hgap;
77 this.vgap = vgap;
78 this.tab = new Hashtable ();
81 /**
82 * Add a new component to the layout. The constraint must be a
83 * string which is used to name the component. This string can
84 * later be used to refer to the particular component.
86 * @param comp The component to add
87 * @param constraints The name by which the component can later be called
89 * @exception IllegalArgumentException If `constraints' is not a
90 * <code>String</code>
92 public void addLayoutComponent (Component comp, Object constraints)
94 if (! (constraints instanceof String))
95 throw new IllegalArgumentException ("Object " + constraints
96 + " is not a string");
97 addLayoutComponent ((String) constraints, comp);
101 * Add a new component to the layout. The name can be used later
102 * to refer to the component.
104 * @param name The name by which the component can later be called
105 * @param comp The component to add
107 * @deprecated This method is deprecated in favor of
108 * <code>addLayoutComponent(Component, Object)</code>.
110 public void addLayoutComponent (String name, Component comp)
112 tab.put (name, comp);
113 // First component added is the default component.
114 comp.setVisible(tab.size() == 1);
118 * Cause the first component in the container to be displayed.
120 * @param parent The parent container, not <code>null</code>.
122 public void first (Container parent)
124 gotoComponent (parent, FIRST);
128 * Return this layout manager's horizontal gap.
130 * @return the horizontal gap
132 public int getHgap ()
134 return hgap;
138 * Return this layout manager's x alignment. This method always
139 * returns Component.CENTER_ALIGNMENT.
141 * @param parent Container using this layout manager instance
143 * @return the x-axis alignment
145 public float getLayoutAlignmentX (Container parent)
147 return Component.CENTER_ALIGNMENT;
151 * Returns this layout manager's y alignment. This method always
152 * returns Component.CENTER_ALIGNMENT.
154 * @param parent Container using this layout manager instance
156 * @return the y-axis alignment
158 public float getLayoutAlignmentY (Container parent)
160 return Component.CENTER_ALIGNMENT;
164 * Return this layout manager's vertical gap.
166 * @return the vertical gap
168 public int getVgap ()
170 return vgap;
174 * Invalidate this layout manager's state.
176 public void invalidateLayout (Container target)
178 // Do nothing.
182 * Cause the last component in the container to be displayed.
184 * @param parent The parent container, not <code>null</code>.
186 public void last (Container parent)
188 gotoComponent (parent, LAST);
192 * Lays out the container. This is done by resizing the child components
193 * to be the same size as the parent, less insets and gaps.
195 * @param parent The parent container.
197 public void layoutContainer (Container parent)
199 synchronized (parent.getTreeLock ())
201 int width = parent.width;
202 int height = parent.height;
204 Insets ins = parent.getInsets ();
206 int num = parent.ncomponents;
207 Component[] comps = parent.component;
209 int x = ins.left + hgap;
210 int y = ins.top + vgap;
211 width = width - 2 * hgap - ins.left - ins.right;
212 height = height - 2 * vgap - ins.top - ins.bottom;
214 for (int i = 0; i < num; ++i)
215 comps[i].setBounds (x, y, width, height);
220 * Get the maximum layout size of the container.
222 * @param target The parent container
224 * @return the maximum layout size
226 public Dimension maximumLayoutSize (Container target)
228 // The JCL says that this returns Integer.MAX_VALUE for both
229 // dimensions. But that just seems wrong to me.
230 return getSize (target, MAX);
234 * Get the minimum layout size of the container.
236 * @param target The parent container
238 * @return the minimum layout size
240 public Dimension minimumLayoutSize (Container target)
242 return getSize (target, MIN);
246 * Cause the next component in the container to be displayed. If
247 * this current card is the last one in the deck, the first
248 * component is displayed.
250 * @param parent The parent container, not <code>null</code>.
252 public void next (Container parent)
254 gotoComponent (parent, NEXT);
258 * Get the preferred layout size of the container.
260 * @param parent The parent container
262 * @return the preferred layout size
264 public Dimension preferredLayoutSize (Container parent)
266 return getSize (parent, PREF);
270 * Cause the previous component in the container to be displayed.
271 * If this current card is the first one in the deck, the last
272 * component is displayed.
274 * @param parent The parent container, not <code>null</code>.
276 public void previous (Container parent)
278 gotoComponent (parent, PREV);
282 * Remove the indicated component from this layout manager.
284 * @param comp The component to remove
286 public void removeLayoutComponent (Component comp)
288 Enumeration e = tab.keys ();
289 while (e.hasMoreElements ())
291 Object key = e.nextElement ();
292 if (tab.get (key) == comp)
294 tab.remove (key);
295 Container parent = comp.getParent();
296 next(parent);
297 break;
303 * Set this layout manager's horizontal gap.
305 * @param hgap The new gap
307 public void setHgap (int hgap)
309 this.hgap = hgap;
313 * Set this layout manager's vertical gap.
315 * @param vgap The new gap
317 public void setVgap (int vgap)
319 this.vgap = vgap;
323 * Cause the named component to be shown. If the component name is
324 * unknown or <code>null</code>, this method does nothing.
326 * @param parent The parent container, not <code>null</code>.
327 * @param name The name of the component to show
329 public void show (Container parent, String name)
331 if (name == null)
332 return;
334 if (parent.getLayout() != this)
335 throw new IllegalArgumentException("parent's layout is not this CardLayout");
337 Object target = tab.get (name);
338 if (target != null)
340 int num = parent.ncomponents;
341 // This is more efficient than calling getComponents().
342 Component[] comps = parent.component;
343 for (int i = 0; i < num; ++i)
345 if (comps[i].isVisible())
347 if (target == comps[i])
348 return;
349 comps[i].setVisible (false);
352 ((Component) target).setVisible (true);
357 * Returns a string representation of this layout manager.
359 * @return A string representation of this object.
361 public String toString ()
363 return getClass ().getName () + "[" + hgap + "," + vgap + "]";
367 * This implements first(), last(), next(), and previous().
369 * @param parent The parent container
370 * @param what The type of goto: FIRST, LAST, NEXT or PREV
372 * @throws IllegalArgumentException if parent has not this
373 * CardLayout set as its layout.
375 private void gotoComponent (Container parent, int what)
377 if (parent.getLayout() != this)
378 throw new IllegalArgumentException("parent's layout is not this CardLayout");
380 synchronized (parent.getTreeLock ())
382 int num = parent.ncomponents;
383 // This is more efficient than calling getComponents().
384 Component[] comps = parent.component;
386 if (num == 1)
388 comps[0].setVisible(true);
389 return;
392 int choice = -1;
394 if (what == FIRST)
395 choice = 0;
396 else if (what == LAST)
397 choice = num - 1;
399 for (int i = 0; i < num; ++i)
401 if (comps[i].isVisible ())
403 if (what == NEXT)
405 choice = i + 1;
406 if (choice == num)
407 choice = 0;
409 else if (what == PREV)
411 choice = i - 1;
412 if (choice < 0)
413 choice = num - 1;
415 else if (choice == i)
417 // Do nothing if we're already looking at the right
418 // component.
419 return;
421 comps[i].setVisible (false);
423 if (choice >= 0)
424 break;
428 if (choice >= 0 && choice < num)
429 comps[choice].setVisible (true);
433 // Compute the size according to WHAT.
434 private Dimension getSize (Container parent, int what)
436 synchronized (parent.getTreeLock ())
438 int w = 0, h = 0, num = parent.ncomponents;
439 Component[] comps = parent.component;
441 for (int i = 0; i < num; ++i)
443 Dimension d;
445 if (what == MIN)
446 d = comps[i].getMinimumSize ();
447 else if (what == MAX)
448 d = comps[i].getMaximumSize ();
449 else
450 d = comps[i].getPreferredSize ();
452 w = Math.max (d.width, w);
453 h = Math.max (d.height, h);
456 Insets i = parent.getInsets ();
457 w += 2 * hgap + i.right + i.left;
458 h += 2 * vgap + i.bottom + i.top;
460 // Handle overflow.
461 if (w < 0)
462 w = Integer.MAX_VALUE;
463 if (h < 0)
464 h = Integer.MAX_VALUE;
466 return new Dimension (w, h);
471 * @serial Horizontal gap value.
473 private int hgap;
476 * @serial Vertical gap value.
478 private int vgap;
481 * @serial Table of named components.
483 private Hashtable tab;
485 // These constants are used by the private gotoComponent method.
486 private static final int FIRST = 0;
487 private static final int LAST = 1;
488 private static final int NEXT = 2;
489 private static final int PREV = 3;
491 // These constants are used by the private getSize method.
492 private static final int MIN = 0;
493 private static final int MAX = 1;
494 private static final int PREF = 2;