OSDN Git Service

* Makefile.in: Rebuilt.
[pf3gnuchains/gcc-fork.git] / libjava / java / awt / GridLayout.java
1 // GridLayout.java - Grid-based layout engine
2
3 /* Copyright (C) 2000  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.io.Serializable;
14
15 /** This class implements a grid-based layout scheme.  Components are
16  * all given the same size and are laid out from left to right and top
17  * to bottom.  A GridLayout is configured with a number of rows and a
18  * number of columns.  If either is zero then that dimension is
19  * computed based on the actual size of the container.  An exception
20  * is thrown if an attempt is made to set both the number of rows and
21  * the number of columns to 0.  This class also support horizontal and
22  * vertical gaps; these are used as spacing between cells.
23  */
24 public class GridLayout implements LayoutManager, Serializable
25 {
26   /** Add a new component to the layout.  This particular implementation
27    * does nothing.
28    */
29   public void addLayoutComponent (String name, Component comp)
30   {
31     // Nothing.
32   }
33
34   /** Return the number of columns in this layout.  */
35   public int getColumns ()
36   {
37     return cols;
38   }
39
40   /** Return the horizontal gap.  */
41   public int getHgap ()
42   {
43     return hgap;
44   }
45
46   /** Return the number of rows in this layout.  */
47   public int getRows ()
48   {
49     return rows;
50   }
51
52   /** Return the vertical gap.  */
53   public int getVgap ()
54   {
55     return vgap;
56   }
57
58   /** Create a new GridLayout with one row and any number of columns.
59    * Both gaps are set to 0.
60    */
61   public GridLayout ()
62   {
63     this (1, 0, 0, 0);
64   }
65
66   /** Create a new GridLayout with the specified number of rows and
67    * columns.  Both gaps are set to 0.
68    * @param rows Number of rows
69    * @param cols Number of columns
70    * @exception IllegalArgumentException If rows and columns are both
71    *        0, or if either are negative
72    */
73   public GridLayout (int rows, int cols)
74   {
75     this (rows, cols, 0, 0);
76   }
77
78   /** Create a new GridLayout with the specified number of rows and
79    * columns and the specified gaps.
80    * @param rows Number of rows
81    * @param cols Number of columns
82    * @param hgap The horizontal gap
83    * @param vgap The vertical gap
84    * @exception IllegalArgumentException If rows and columns are both
85    *        0, if either are negative, or if either gap is negative
86    */
87   public GridLayout (int rows, int cols, int hgap, int vgap)
88   {
89     if (rows < 0)
90       throw new IllegalArgumentException ("number of rows cannot be negative");
91     if (cols < 0)
92       throw new IllegalArgumentException ("number of columns cannot be negative");
93     if (rows == 0 && cols == 0)
94       throw new IllegalArgumentException ("both rows and columns cannot be 0");
95     if (hgap < 0)
96       throw new IllegalArgumentException ("horizontal gap must be nonnegative");
97     if (vgap < 0)
98       throw new IllegalArgumentException ("vertical gap must be nonnegative");
99     this.rows = rows;
100     this.cols = cols;
101     this.hgap = hgap;
102     this.vgap = vgap;
103   }
104
105   /** Lay out the container's components based on current settings.
106    * @param parent The parent container
107    */
108   public void layoutContainer (Container parent)
109   {
110     int num = parent.getComponentCount ();
111     // This is more efficient than calling getComponents().
112     Component[] comps = parent.component;
113
114     int real_rows = rows;
115     int real_cols = cols;
116     if (real_rows == 0)
117       real_rows = (num + real_cols - 1) / real_cols;
118     else
119       real_cols = (num + real_rows - 1) / real_rows;
120
121     Dimension d = parent.getSize ();
122     Insets ins = parent.getInsets ();
123
124     int tw = d.width - ins.left - ins.right;
125     int th = d.height - ins.top - ins.bottom;
126
127     int w = (tw - (real_rows - 1) * hgap) / real_rows;
128     int h = (th - (real_cols - 1) * vgap) / real_cols;
129
130     int x = ins.left;
131     int y = ins.top;
132     int i = 0;
133     int recount = 0;
134
135     while (i < num)
136       {
137         comps[i].setBounds (x, y, tw, th);
138
139         ++i;
140         ++recount;
141         if (recount == real_cols)
142           {
143             recount = 0;
144             y += vgap + th;
145             x = ins.left;
146           }
147         else
148           x += hgap + tw;
149       }
150   }
151
152   /** Get the minimum layout size of the container.
153    * @param cont The parent container
154    */
155   public Dimension minimumLayoutSize (Container cont)
156   {
157     return getSize (cont, true);
158   }
159
160   /** Get the preferred layout size of the container.
161    * @param cont The parent container
162    */
163   public Dimension preferredLayoutSize (Container cont)
164   {
165     return getSize (cont, false);
166   }
167
168   /** Remove the indicated component from this layout manager.
169    * This particular implementation does nothing.
170    * @param comp The component to remove
171    */
172   public void removeLayoutComponent (Component comp)
173   {
174     // Nothing.
175   }
176
177   /** Set the number of columns.
178    * @param newCols
179    * @exception IllegalArgumentException If the number of columns is
180    *     negative, or if the number of columns is zero and the number
181    *     of rows is already 0.
182    */
183   public void setColumns (int newCols)
184   {
185     if (cols < 0)
186       throw new IllegalArgumentException ("number of columns cannot be negative");
187     if (newCols == 0 && rows == 0)
188       throw new IllegalArgumentException ("number of rows is already 0");
189     this.cols = newCols;
190   }
191
192   /** Set the horizontal gap
193    * @param hgap The horizontal gap
194    */
195   public void setHgap (int hgap)
196   {
197     if (hgap < 0)
198       throw new IllegalArgumentException ("horizontal gap must be nonnegative");
199     this.hgap = hgap;
200   }
201
202   /** Set the number of rows
203    * @param newRows
204    * @exception IllegalArgumentException If the number of rows is
205    *     negative, or if the number of rows is zero and the number
206    *     of columns is already 0.
207    */
208   public void setRows (int newRows)
209   {
210     if (rows < 0)
211       throw new IllegalArgumentException ("number of rows cannot be negative");
212     if (newRows == 0 && cols == 0)
213       throw new IllegalArgumentException ("number of columns is already 0");
214     this.rows = newRows;
215   }
216
217   /** Set the vertical gap.
218    * @param vgap The vertical gap
219    */
220   public void setVgap (int vgap)
221   {
222     if (vgap < 0)
223       throw new IllegalArgumentException ("vertical gap must be nonnegative");
224     this.vgap = vgap;
225   }
226
227   // This method is used to compute the various sizes.
228   private Dimension getSize (Container parent, boolean is_min)
229   {
230     int w = 0, h = 0, num = parent.getComponentCount ();
231     // This is more efficient than calling getComponents().
232     Component[] comps = parent.component;
233
234     for (int i = 0; i < num; ++i)
235       {
236         // FIXME: can we just directly read the fields in Component?
237         // Or will that not work with subclassing?
238         Dimension d;
239
240         if (is_min)
241           d = comps[i].getMinimumSize ();
242         else
243           d = comps[i].getPreferredSize ();
244
245         w = Math.max (d.width, w);
246         h = Math.max (d.height, h);
247       }
248
249     int real_rows = rows;
250     int real_cols = cols;
251     if (real_rows == 0)
252       real_rows = (num + real_cols - 1) / real_cols;
253     else
254       real_cols = (num + real_rows - 1) / real_rows;
255
256     // We subtract out an extra gap here because the gaps are only
257     // between cells.
258     return new Dimension (real_rows * (w + hgap) - hgap,
259                           real_cols * (h + vgap) - vgap);
260   }
261
262   // The gaps.
263   private int hgap;
264   private int vgap;
265   // Number of rows and columns.
266   private int rows;
267   private int cols;
268 }