/[classpath]/classpath/java/awt/CardLayout.java
ViewVC logotype

Diff of /classpath/java/awt/CardLayout.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by mark, Sun Jan 13 15:45:15 2002 UTC revision 1.4 by tromey, Wed Jan 16 05:18:52 2002 UTC
# Line 1  Line 1 
1  /* CardLayout.java -- Layout manager for a card stack  // CardLayout.java - Card-based layout engine
2     Copyright (C) 1999 Free Software Foundation, Inc.  
3    /* Copyright (C) 1999, 2000, 2002  Free Software Foundation
4    
5  This file is part of GNU Classpath.  This file is part of GNU Classpath.
6    
# Line 29  package java.awt; Line 30  package java.awt;
30    
31  import java.util.Enumeration;  import java.util.Enumeration;
32  import java.util.Hashtable;  import java.util.Hashtable;
33    import java.io.Serializable;
34    
35  /**  /** This class implements a card-based layout scheme.  Each included
36    * This class is a layout manager that treats components as cards in   * component is treated as a card.  Only one card can be shown at a
37    * a stack.  Only one is visible at a time.   * time.  This class includes methods for changing which card is
38    *   * shown.
39    * @author Aaron M. Renn (arenn@urbanophile.com)   *
40    */   * @author Tom Tromey <tromey@redhat.com>
41  public class CardLayout implements LayoutManager2, java.io.Serializable   * @author Aaron M. Renn (arenn@urbanophile.com)
 {  
   
 /*  
  * Static Variables  
  */  
   
 // Layout size constants  
 private static final int PREF = 0;  
 private static final int MAX = 1;  
 private static final int MIN = 2;  
   
 // Serialization constant  
 private static final long serialVersionUID = -4328196481005934313L;  
   
 /*************************************************************************/  
   
 /*  
  * Instance Variables  
  */  
   
 /**  
   * @serial Horitzontal gap value.  
   */  
 private int hgap;  
   
 /**  
   * @serial Vertical gap value.  
   */  
 private int vgap;  
   
 /**  
   * @serial Table of named components.  
   */  
 private Hashtable tab = new Hashtable();  
   
 /*************************************************************************/  
   
 /*  
  * Constructors  
  */  
   
 /**  
   * Initializes a new instance of <code>CardLayout</code> with horizontal  
   * and vertical gaps of 0.  
   */  
 public  
 CardLayout()  
 {  
   this(0,0);  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Initializes a new instance of <code>CardLayout</code> 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;  
 }  
   
 /*************************************************************************/  
   
 /*  
  * Instance Variables  
42   */   */
43    public class CardLayout implements LayoutManager2, Serializable
 /**  
   * Returns the horitzontal gap value.  
   *  
   * @return The horitzontal gap value.  
   */  
 public int  
 getHgap()  
 {  
   return(hgap);  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Sets the horizontal gap to the specified value.  
   *  
   * @param hgap The new horizontal gap.  
   */  
 public void  
 setHgap(int hgap)  
 {  
   this.hgap = hgap;  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Returns the vertical gap value.  
   *  
   * @return The vertical gap value.  
   */  
 public int  
 getVgap()  
 {  
   return(vgap);  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Sets the vertical gap to the specified value.  
   *  
   * @param vgap The new vertical gap value.  
   */  
 public void  
 setVgap(int vgap)  
 {  
   this.vgap = vgap;  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Adds the specified component to this object's table of components.  
   * Doing this allows random access by name.  
   *  
   * @param component The component to add.  
   * @param name The name of the component, which must be a <code>String</code>.  
   *  
   * @exception IllegalArgumentException If the name object is not a  
   * <code>String</code>.  
   */  
 public void  
 addLayoutComponent(Component component, Object name)  
 {  
   if (!(name instanceof String))  
     throw new IllegalArgumentException("Name must a string");  
   
   tab.put(name, component);  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Adds the specified component to this object's table of components.  
   * Doing this allows random access by name.  
   *  
   * @param name The name of the component.  
   * @param component The component to add.  
   *  
   * @deprecated This method is deprecated in favor of  
   * <code>addLayoutComponent(Component, Object)</code>.  
   */  
 public void  
 addLayoutComponent(String name, Component component)  
 {  
   addLayoutComponent(component, name);  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Removes the specified component from the table of internal names.  
   *  
   * @param Component The component to remove.  
   */  
 public void  
 removeLayoutComponent(Component component)  
 {  
   Enumeration keys = tab.keys();  
   while (keys.hasMoreElements())  
     {  
       String name = (String)keys.nextElement();  
       Object obj = tab.get(name);  
   
       if (obj == component)  
         {  
           tab.remove(name);  
           return;  
         }  
     }  
 }  
   
 /*************************************************************************/  
   
 // Internal layout size calculator  
 private Dimension  
 layoutSize(Container parent, int type)  
44  {  {
45    int width = 0, height = 0;    /**
46       * Initializes a new instance of <code>CardLayout</code> with horizontal
47    Component[] clist = parent.getComponents();     * and vertical gaps of 0.
48    if (clist.length > 0)     */
49      for (int i = 0; i < clist.length; i++)    public CardLayout ()
50      {
51        this (0, 0);
52      }
53    
54      /**
55       * Create a new <code>CardLayout</code> object with the specified
56       * horizontal and vertical gaps.
57       * @param hgap The horizontal gap
58       * @param vgap The vertical gap
59       */
60      public CardLayout (int hgap, int vgap)
61      {
62        this.hgap = hgap;
63        this.vgap = vgap;
64        this.tab = new Hashtable ();
65      }
66    
67      /** Add a new component to the layout.  The constraint must be a
68       * string which is used to name the component.  This string can
69       * later be used to refer to the particular component.
70       * @param comp The component to add
71       * @param constraints The name by which the component can later be called
72       * @exception IllegalArgumentException If `constraints' is not a
73       * <code>String</code>
74       */
75      public void addLayoutComponent (Component comp, Object constraints)
76      {
77        if (! (constraints instanceof String))
78          throw new IllegalArgumentException ("Object " + constraints
79                                              + " is not a string");
80        tab.put (constraints, comp);
81      }
82    
83      /** Add a new component to the layout.  The name can be used later
84       * to refer to the component.
85       * @param name The name by which the component can later be called
86       * @param comp The component to add
87       * @deprecated This method is deprecated in favor of
88       * <code>addLayoutComponent(Component, Object)</code>.
89       */
90      public void addLayoutComponent (String name, Component comp)
91      {
92        addLayoutComponent (comp, name);
93      }
94    
95      /** Cause the first component in the container to be displayed.
96       * @param parent The parent container
97       */
98      public void first (Container parent)
99      {
100        gotoComponent (parent, FIRST, null);
101      }
102    
103      /** Return this layout manager's horizontal gap.  */
104      public int getHgap ()
105      {
106        return hgap;
107      }
108    
109      /** Return this layout manager's x alignment.  This method always
110       * returns Component.CENTER_ALIGNMENT.
111       * @param parent Container using this layout manager instance
112       */
113      public float getLayoutAlignmentX (Container parent)
114      {
115        return Component.CENTER_ALIGNMENT;
116      }
117    
118      /** Returns this layout manager's y alignment.  This method always
119       * returns Component.CENTER_ALIGNMENT.
120       * @param parent Container using this layout manager instance
121       */
122      public float getLayoutAlignmentY (Container parent)
123      {
124        return Component.CENTER_ALIGNMENT;
125      }
126    
127      /** Return this layout manager's vertical gap.  */
128      public int getVgap ()
129      {
130        return vgap;
131      }
132    
133      /** Invalidate this layout manager's state.  */
134      public void invalidateLayout (Container target)
135      {
136        // Do nothing.
137      }
138    
139      /** Cause the last component in the container to be displayed.
140       * @param parent The parent container
141       */
142      public void last (Container parent)
143      {
144        gotoComponent (parent, LAST, null);
145      }
146    
147      /**
148       * Lays out the container.  This is done by resizing the child components
149       * to be the same size as the parent, less insets and gaps.
150       *
151       * @param parent The parent container.
152       */
153      public void layoutContainer (Container parent)
154      {
155        int width = parent.width;
156        int height = parent.height;
157    
158        Insets ins = parent.getInsets ();
159    
160        int num = parent.ncomponents;
161        Component[] comps = parent.component;
162    
163        int x = ins.left + hgap;
164        int y = ins.top + vgap;
165        width = width - 2 * hgap - ins.left - ins.right;
166        height = height - 2 * vgap - ins.top - ins.bottom;
167    
168        for (int i = 0; i < num; ++i)
169          comps[i].setBounds (x, y, width, height);
170      }
171    
172      /** Get the maximum layout size of the container.
173       * @param target The parent container
174       */
175      public Dimension maximumLayoutSize (Container target)
176      {
177        // The JCL says that this returns Integer.MAX_VALUE for both
178        // dimensions.  But that just seems wrong to me.
179        return getSize (target, MAX);
180      }
181    
182      /** Get the minimum layout size of the container.
183       * @param target The parent container
184       */
185      public Dimension minimumLayoutSize (Container target)
186      {
187        return getSize (target, MIN);
188      }
189    
190      /** Cause the next component in the container to be displayed.  If
191       * this current card is the  last one in the deck, the first
192       * component is displayed.
193       * @param parent The parent container
194       */
195      public void next (Container parent)
196      {
197        gotoComponent (parent, NEXT, null);
198      }
199    
200      /** Get the preferred layout size of the container.
201       * @param target The parent container
202       */
203      public Dimension preferredLayoutSize (Container parent)
204      {
205        return getSize (parent, PREF);
206      }
207    
208      /** Cause the previous component in the container to be displayed.
209       * If this current card is the first one in the deck, the last
210       * component is displayed.
211       * @param parent The parent container
212       */
213      public void previous (Container parent)
214      {
215        gotoComponent (parent, PREV, null);
216      }
217    
218      /** Remove the indicated component from this layout manager.
219       * @param comp The component to remove
220       */
221      public void removeLayoutComponent (Component comp)
222      {
223        Enumeration e = tab.keys ();
224        while (e.hasMoreElements ())
225        {        {
226          Component comp = clist[i];          Object key = e.nextElement ();
227          Dimension dim = null;          if (tab.get (key) == comp)
228              {
229          if (type == PREF)              tab.remove (key);
230             dim = comp.getPreferredSize();              break;
231          else if (type == MAX)            }
            dim = comp.getMaximumSize();  
         else if (type == MIN)  
            dim = comp.getMinimumSize();  
   
         if (dim.width > width)  
           width = dim.width;  
         if (dim.height > height)  
           width = dim.height;  
232        }        }
233      }
234    
235    Insets ins = parent.getInsets();    /** Set this layout manager's horizontal gap.
236       * @param hgap The new gap
237    width += (ins.left + ins.right);     */
238    height += (ins.top + ins.bottom);    public void setHgap (int hgap)
239      {
240    return(new Dimension(width, height));      this.hgap = hgap;
241  }    }
242    
243  /*************************************************************************/    /** Set this layout manager's vertical gap.
244       * @param vgap The new gap
245  /**     */
246    * Returns the preferred size of the container for supporting this    public void setVgap (int vgap)
247    * layout.    {
248    *      this.vgap = vgap;
249    * @param parent The parent container.    }
250    */  
251  public Dimension    /** Cause the named component to be shown.  If the component name is
252  preferredLayoutSize(Container parent)     * unknown, this method does nothing.
253  {     * @param parent The parent container
254    return(layoutSize(parent, PREF));     * @param name The name of the component to show
255  }     */
256      public void show (Container parent, String name)
257  /*************************************************************************/    {
258        Object target = tab.get (name);
259  /**      if (target != null)
260    * Returns the minimum size of the container for supporting this        gotoComponent (parent, NONE, (Component) target);
261    * layout.    }
262    *  
263    * @param parent The parent container.    /**
264    */     * Returns a string representation of this layout manager.
265  public Dimension     *
266  minimumLayoutSize(Container parent)     * @return A string representation of this object.
267  {     */
268    return(layoutSize(parent, MIN));    public String toString ()
269  }    {
270        return getClass ().getName () + "[" + hgap + "," + vgap + "]";
271  /*************************************************************************/    }
272    
273  /**    // This implements first(), last(), next(), and previous().
274    * Returns the maximum size of the container for supporting this    private void gotoComponent (Container parent, int what,
275    * layout.                                Component target)
276    *    {
277    * @param parent The parent container.      int num = parent.ncomponents;
278    */      // This is more efficient than calling getComponents().
279  public Dimension      Component[] comps = parent.component;
280  maximumLayoutSize(Container parent)      int choice = -1;
281  {  
282    return(layoutSize(parent, MAX));      if (what == FIRST)
283  }        choice = 0;
284        else if (what == LAST)
285  /*************************************************************************/        choice = num - 1;
286        else if (what >= 0)
287  /**        choice = what;
   * Returns the X axis alignment, which is a <code>float</code> indicating  
   * where along the X axis this container wishs to position its layout.  
   * 0 indicates align to the left, 1 indicates align to the right, and 0.5  
   * indicates align to the center.  
   *  
   * @param parent The parent container.  
   *  
   * @return The X alignment value.  
   */  
 public float  
 getLayoutAlignmentX(Container parent)  
 {  
   return(parent.getAlignmentX());  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Returns the Y axis alignment, which is a <code>float</code> indicating  
   * where along the Y axis this container wishs to position its layout.  
   * 0 indicates align to the top, 1 indicates align to the bottom, and 0.5  
   * indicates align to the center.  
   *  
   * @param parent The parent container.  
   *  
   * @return The Y alignment value.  
   */  
 public float  
 getLayoutAlignmentY(Container parent)  
 {  
   return(parent.getAlignmentY());  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Instructs this object to discard any layout information it might  
   * have cached.  
   *  
   * @param parent The parent container.  
   */  
 public void  
 invalidateLayout(Container parent)  
 {  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Goes to the first card in the container.  
   *  
   * @param parent The parent container.  
   */  
 public void  
 first(Container parent)  
 {  
   Component[] clist = parent.getComponents();  
   if (clist.length > 0)  
     {  
       for (int i = 0; i < clist.length; i++)  
         clist[i].setVisible(false);  
288    
289        clist[0].setVisible(true);      for (int i = 0; i < num; ++i)
290      }        {
291  }          // If TARGET is set then we are looking for a specific
292            // component.
293  /*************************************************************************/          if (target != null)
294              {
295  /**              if (target == comps[i])
296    * Goes to the last card in the container.                choice = i;
297    *            }
298    * @param parent The parent container.  
299    */          if (comps[i].isVisible ())
300  public void            {
301  last(Container parent)              if (what == NEXT)
302  {                {
303    Component[] clist = parent.getComponents();                  choice = i + 1;
304    if (clist.length > 0)                  if (choice == num)
305      {                    choice = 0;
306        for (int i = 0; i < clist.length; i++)                }
307          clist[i].setVisible(false);              else if (what == PREV)
308                  {
309        clist[clist.length-1].setVisible(true);                  choice = i - 1;
310      }                  if (choice < 0)
311  }                    choice = num - 1;
312                  }
313  /*************************************************************************/              else if (choice == i)
314                  {
315  /**                  // Do nothing if we're already looking at the right
316    * Goes to the next card in the container.  If this current card is the                  // component.
317    * last one in the deck, the first component is displayed.                  return;
318    *                }
319    * @param parent The parent container.              comps[i].setVisible (false);
320    */  
321  public void              if (choice >= 0)
322  next(Container parent)                break;
323  {            }
324    Component[] clist = parent.getComponents();        }
   if (clist.length > 0)  
     {  
       for (int i = 0; i < clist.length; i++)  
         {  
           if (clist[i].isVisible())  
             {  
                clist[i].setVisible(false);  
   
                if ((i + 1) == clist.length)  
                  clist[0].setVisible(true);  
                else  
                  clist[i+1].setVisible(true);  
   
                break;  
             }  
         }  
     }  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Goes to the next card in the container.  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)  
 {  
   Component[] clist = parent.getComponents();  
   if (clist.length > 0)  
     {  
       for (int i = 0; i < clist.length; i++)  
         {  
           if (clist[i].isVisible())  
             {  
                clist[i].setVisible(false);  
   
                if (i == 0)  
                  clist[clist.length-1].setVisible(true);  
                else  
                  clist[i-1].setVisible(true);  
   
                break;  
             }  
         }  
     }  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Displays the specified component that was previous added by name  
   * using the <code>addLayoutComponent()</code> method.  If the named  
   * component doesn't exist, this method returns silently.  
   *  
   * @param parent The parent container.  
   * @param name The name of the component to display.  
   */  
 public void  
 show(Container parent, String name)  
 {  
   Component comp = (Component)tab.get(name);  
   if (comp == null)  
     return;  
   
   Component[] clist = parent.getComponents();  
   if (clist.length > 0)  
     {  
       for (int i = 0; i < clist.length; i++)  
         {  
           if (clist[i] == comp)  
             continue;  
   
           if (clist[i].isVisible())  
             clist[i].setVisible(false);  
         }  
     }  
 }  
   
 /*************************************************************************/  
325    
326  /**      if (choice >= 0 && choice < num)
327    * Lays out the container.  This is done by resizing the child components        comps[choice].setVisible (true);
328    * to be the same size as the parent, less insets and gaps.    }
329    *  
330    * @param parent The parent container.    // Compute the size according to WHAT.
331    */    private Dimension getSize (Container parent, int what)
332  public void    {
333  layoutContainer(Container parent)      int w = 0, h = 0, num = parent.ncomponents;
334  {      Component[] comps = parent.component;
   Insets ins = parent.getInsets();  
   Dimension dim = parent.getSize();  
   Component[] clist = parent.getComponents();  
335    
336    if (clist.length > 0)      for (int i = 0; i < num; ++i)
     for (int i = 0; i < clist.length; i++)  
337        {        {
338          int x = ins.left + hgap;          Dimension d;
         int y = ins.top + vgap;  
         int width = dim.width - (ins.left + ins.right + hgap);  
         int height = dim.height - (ins.top + ins.bottom + vgap);  
339    
340          clist[i].setLocation(x, y);          if (what == MIN)
341          clist[i].setSize(width, height);            d = comps[i].getMinimumSize ();
342        }          else if (what == MAX)
343  }            d = comps[i].getMaximumSize ();
344            else
345              d = comps[i].getPreferredSize ();
346    
347  /*************************************************************************/          w = Math.max (d.width, w);
348            h = Math.max (d.height, h);
349          }
350    
351  /**      Insets i = parent.getInsets ();
352    * Returns a string representation of this layout manager.      w += 2 * hgap + i.right + i.left;
353    *      h += 2 * vgap + i.bottom + i.top;
354    * @return A string representation of this object.  
355    */      // Handle overflow.
356  public String      if (w < 0)
357  toString()        w = Integer.MAX_VALUE;
358  {      if (h < 0)
359    return(getClass().getName());        h = Integer.MAX_VALUE;
360    
361        return new Dimension (w, h);
362      }
363    
364      /**
365       * @serial Horizontal gap value.
366       */
367      private int hgap;
368    
369      /**
370       * @serial Vertical gap value.
371       */
372      private int vgap;
373    
374      /**
375       * @serial Table of named components.
376       */
377      private Hashtable tab;
378    
379      // These constants are used by the private gotoComponent method.
380      private int FIRST = 0;
381      private int LAST = 1;
382      private int NEXT = 2;
383      private int PREV = 3;
384      private int NONE = 4;
385    
386      // These constants are used by the private getSize method.
387      private int MIN = 0;
388      private int MAX = 1;
389      private int PREF = 2;
390  }  }
   
 } // class CardLayout  
   

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26