OSDN Git Service

9445bf7820f76097625fd818a6368ea382be44fa
[pf3gnuchains/gcc-fork.git] / libjava / java / awt / CardLayout.java
1 // CardLayout.java - Card-based layout engine
2
3 /* Copyright (C) 2000, 2002  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 package java.awt;
12
13 import java.util.Enumeration;
14 import java.util.Hashtable;
15 import java.io.Serializable;
16
17 /** This class implements a card-based layout scheme.  Each included
18  * component is treated as a card.  Only one card can be shown at a
19  * time.  This class includes methods for changing which card is
20  * shown.
21  *
22  * @version 0.0
23  * @author Tom Tromey <tromey@redhat.com>
24  * @date December 2, 2000
25  */
26 public class CardLayout implements LayoutManager2, Serializable
27 {
28   /** Create a new CardLayout object with both gaps zero.  */
29   public CardLayout ()
30   {
31     this (0, 0);
32   }
33
34   /** Create a new CardLayout object with the specified horizontal and
35    * vertical gaps.
36    * @param hgap The horizontal gap
37    * @param vgap The vertical gap
38    */
39   public CardLayout (int hgap, int vgap)
40   {
41     this.hgap = hgap;
42     this.vgap = vgap;
43     this.map = new Hashtable ();
44   }
45
46   /** Add a new component to the layout.  The constraint must be a
47    * string which is used to name the component.  This string can
48    * later be used to refer to the particular component.
49    * @param comp The component to add
50    * @param constraints The name by which the component can later be called
51    * @exception IllegalArgumentException If `constraints' is not a string
52    */
53   public void addLayoutComponent (Component comp, Object constraints)
54   {
55     if (! (constraints instanceof String))
56       throw new IllegalArgumentException ("Object " + constraints
57                                           + " is not a string");
58     map.put (constraints, comp);
59   }
60
61   /** Add a new component to the layout.  The name can be used later
62    * to refer to the component.
63    * @param name The name by which the component can later be called
64    * @param comp The component to add
65    * @deprecated
66    */
67   public void addLayoutComponent (String name, Component comp)
68   {
69     addLayoutComponent (comp, name);
70   }
71
72   /** Cause the first component in the container to be displayed.
73    * @param parent The parent container
74    */
75   public void first (Container parent)
76   {
77     gotoComponent (parent, FIRST, null);
78   }
79
80   /** Return this layout manager's horizontal gap.  */
81   public int getHgap ()
82   {
83     return hgap;
84   }
85
86   /** Return this layout manager's x alignment.  This method always
87    * returns Component.CENTER_ALIGNMENT.
88    * @param parent Container using this layout manager instance
89    */
90   public float getLayoutAlignmentX (Container parent)
91   {
92     return Component.CENTER_ALIGNMENT;
93   }
94
95   /** Returns this layout manager's y alignment.  This method always
96    * returns Component.CENTER_ALIGNMENT.
97    * @param parent Container using this layout manager instance
98    */
99   public float getLayoutAlignmentY (Container parent)
100   {
101     return Component.CENTER_ALIGNMENT;
102   }
103
104   /** Return this layout manager's vertical gap.  */
105   public int getVgap ()
106   {
107     return vgap;
108   }
109
110   /** Invalidate this layout manager's state.  */
111   public void invalidateLayout (Container target)
112   {
113     // Do nothing.
114   }
115
116   /** Cause the last component in the container to be displayed.
117    * @param parent The parent container
118    */
119   public void last (Container parent)
120   {
121     gotoComponent (parent, LAST, null);
122   }
123
124   /** Lay out the container's components based on the current
125    * settings.
126    * @param parent The parent container
127    */
128   public void layoutContainer (Container parent)
129   {
130     int width = parent.width;
131     int height = parent.height;
132
133     Insets ins = parent.getInsets ();
134
135     int num = parent.ncomponents;
136     Component[] comps = parent.component;
137
138     for (int i = 0; i < num; ++i)
139       {
140         comps[i].setBounds (hgap + ins.left, vgap + ins.top,
141                             width - 2 * hgap - ins.left - ins.right,
142                             height - 2 * vgap - ins.top - ins.bottom);
143       }
144   }
145
146   /** Get the maximum layout size of the container.
147    * @param target The parent container
148    */
149   public Dimension maximumLayoutSize (Container target)
150   {
151     // The JCL says that this returns Integer.MAX_VALUE for both
152     // dimensions.  But that just seems wrong to me.
153     return getSize (target, MAX);
154   }
155
156   /** Get the minimum layout size of the container.
157    * @param target The parent container
158    */
159   public Dimension minimumLayoutSize (Container target)
160   {
161     return getSize (target, MIN);
162   }
163
164   /** Cause the next component in the container to be displayed.
165    * @param parent The parent container
166    */
167   public void next (Container parent)
168   {
169     gotoComponent (parent, NEXT, null);
170   }
171
172   /** Get the preferred layout size of the container.
173    * @param target The parent container
174    */
175   public Dimension preferredLayoutSize (Container parent)
176   {
177     return getSize (parent, PREF);
178   }
179
180   /** Cause the previous component in the container to be displayed.
181    * @param parent The parent container
182    */
183   public void previous (Container parent)
184   {
185     gotoComponent (parent, PREV, null);
186   }
187
188   /** Remove the indicated component from this layout manager.
189    * @param comp The component to remove
190    */
191   public void removeLayoutComponent (Component comp)
192   {
193     Enumeration e = map.keys ();
194     while (e.hasMoreElements ())
195       {
196         Object key = e.nextElement ();
197         if (map.get (key) == comp)
198           {
199             map.remove (key);
200             break;
201           }
202       }
203   }
204
205   /** Set this layout manager's horizontal gap.
206    * @param hgap The new gap
207    */
208   public void setHgap (int hgap)
209   {
210     this.hgap = hgap;
211   }
212
213   /** Set this layout manager's vertical gap.
214    * @param vgap The new gap
215    */
216   public void setVgap (int vgap)
217   {
218     this.vgap = vgap;
219   }
220
221   /** Cause the named component to be shown.  If the component name is
222    * unknown, this method does nothing.
223    * @param parent The parent container
224    * @param name The name of the component to show
225    */
226   public void show (Container parent, String name)
227   {
228     Object target = map.get (name);
229     if (target != null)
230       gotoComponent (parent, NONE, (Component) target);
231   }
232
233   public String toString ()
234   {
235     return getClass ().getName () + "[" + hgap + "," + vgap + "]";
236   }
237
238   // This implements first(), last(), next(), and previous().
239   private void gotoComponent (Container parent, int what,
240                               Component target)
241   {
242     int num = parent.getComponentCount ();
243     // This is more efficient than calling getComponents().
244     Component[] comps = parent.component;
245     int choice = -1;
246
247     if (what == FIRST)
248       choice = 0;
249     else if (what == LAST)
250       choice = num;
251     else if (what >= 0)
252       choice = what;
253
254     for (int i = 0; i < num; ++i)
255       {
256         // If TARGET is set then we are looking for a specific
257         // component.
258         if (target != null)
259           {
260             if (target == comps[i])
261               choice = i;
262           }
263
264         if (comps[i].isVisible ())
265           {
266             if (what == NEXT)
267               {
268                 choice = i + 1;
269                 if (choice == num)
270                   choice = 0;
271               }
272             else if (what == PREV)
273               {
274                 choice = i - 1;
275                 if (choice < 0)
276                   choice = num - 1;
277               }
278             else
279               {
280                 // Do nothing if we're already looking at the right
281                 // component.
282                 if (choice == i)
283                   return;
284               }
285             comps[i].setVisible (false);
286
287             if (choice >= 0)
288               break;
289           }
290       }
291
292     comps[choice].setVisible (true);
293   }
294
295   // Compute the size according to WHAT.
296   private Dimension getSize (Container parent, int what)
297   {
298     int w = 0, h = 0, num = parent.ncomponents;
299     Component[] comps = parent.component;
300
301     for (int i = 0; i < num; ++i)
302       {
303         Dimension d;
304
305         if (what == MIN)
306           d = comps[i].getMinimumSize ();
307         else if (what == MAX)
308           d = comps[i].getMaximumSize ();
309         else
310           d = comps[i].getPreferredSize ();
311
312         w = Math.max (d.width, w);
313         h = Math.max (d.height, h);
314       }
315
316     Insets i = parent.getInsets ();
317     w += 2 * hgap + i.right + i.left;
318     h += 2 * vgap + i.bottom + i.top;
319
320     // Handle overflow.
321     if (w < 0)
322       w = Integer.MAX_VALUE;
323     if (h < 0)
324       h = Integer.MAX_VALUE;
325
326     return new Dimension (w, h);
327   }
328
329   // The gaps.
330   private int hgap;
331   private int vgap;
332
333   // This hashtable maps a name to a component.
334   private Hashtable map;
335
336   // These constants are used by the private gotoComponent method.
337   private int FIRST = 0;
338   private int LAST = 1;
339   private int NEXT = 2;
340   private int PREV = 3;
341   private int NONE = 4;
342
343   // These constants are used by the private getSize method.
344   private int MIN = 0;
345   private int MAX = 1;
346   private int PREF = 2;
347 }