Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libjava / java / awt / CardLayout.java
blobe1f3831b30fed0cb2a1079ea0e82335638fa1bd0
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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 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
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
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
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
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, this method does nothing.
326 * @param parent The parent container
327 * @param name The name of the component to show
329 public void show (Container parent, String name)
331 Object target = tab.get (name);
332 if (target != null)
334 int num = parent.ncomponents;
335 // This is more efficient than calling getComponents().
336 Component[] comps = parent.component;
337 for (int i = 0; i < num; ++i)
339 if (comps[i].isVisible())
341 if (target == comps[i])
342 return;
343 comps[i].setVisible (false);
346 ((Component) target).setVisible (true);
351 * Returns a string representation of this layout manager.
353 * @return A string representation of this object.
355 public String toString ()
357 return getClass ().getName () + "[" + hgap + "," + vgap + "]";
361 * This implements first(), last(), next(), and previous().
363 * @param parent The parent container
364 * @param what The type of goto: FIRST, LAST, NEXT or PREV
366 private void gotoComponent (Container parent, int what)
368 synchronized (parent.getTreeLock ())
370 int num = parent.ncomponents;
371 // This is more efficient than calling getComponents().
372 Component[] comps = parent.component;
374 if (num == 1)
376 comps[0].setVisible(true);
377 return;
380 int choice = -1;
382 if (what == FIRST)
383 choice = 0;
384 else if (what == LAST)
385 choice = num - 1;
387 for (int i = 0; i < num; ++i)
389 if (comps[i].isVisible ())
391 if (what == NEXT)
393 choice = i + 1;
394 if (choice == num)
395 choice = 0;
397 else if (what == PREV)
399 choice = i - 1;
400 if (choice < 0)
401 choice = num - 1;
403 else if (choice == i)
405 // Do nothing if we're already looking at the right
406 // component.
407 return;
409 comps[i].setVisible (false);
411 if (choice >= 0)
412 break;
416 if (choice >= 0 && choice < num)
417 comps[choice].setVisible (true);
421 // Compute the size according to WHAT.
422 private Dimension getSize (Container parent, int what)
424 synchronized (parent.getTreeLock ())
426 int w = 0, h = 0, num = parent.ncomponents;
427 Component[] comps = parent.component;
429 for (int i = 0; i < num; ++i)
431 Dimension d;
433 if (what == MIN)
434 d = comps[i].getMinimumSize ();
435 else if (what == MAX)
436 d = comps[i].getMaximumSize ();
437 else
438 d = comps[i].getPreferredSize ();
440 w = Math.max (d.width, w);
441 h = Math.max (d.height, h);
444 Insets i = parent.getInsets ();
445 w += 2 * hgap + i.right + i.left;
446 h += 2 * vgap + i.bottom + i.top;
448 // Handle overflow.
449 if (w < 0)
450 w = Integer.MAX_VALUE;
451 if (h < 0)
452 h = Integer.MAX_VALUE;
454 return new Dimension (w, h);
459 * @serial Horizontal gap value.
461 private int hgap;
464 * @serial Vertical gap value.
466 private int vgap;
469 * @serial Table of named components.
471 private Hashtable tab;
473 // These constants are used by the private gotoComponent method.
474 private static final int FIRST = 0;
475 private static final int LAST = 1;
476 private static final int NEXT = 2;
477 private static final int PREV = 3;
479 // These constants are used by the private getSize method.
480 private static final int MIN = 0;
481 private static final int MAX = 1;
482 private static final int PREF = 2;