Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libjava / java / awt / GridLayout.java
blob95980e6ca0b1802e3afde2053acce498978e6fd6
1 /* GridLayout.java -- Grid-based layout engine
2 Copyright (C) 1999, 2000, 2002, 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;
43 /** This class implements a grid-based layout scheme. Components are
44 * all given the same size and are laid out from left to right and top
45 * to bottom. A GridLayout is configured with a number of rows and a
46 * number of columns. If both are specified, then the number of
47 * columns is ignored and is derived from the number of rows and the
48 * total number of components. If either is zero then that dimension
49 * is computed based on the actual size of the container. An
50 * exception is thrown if an attempt is made to set both the number of
51 * rows and the number of columns to 0. This class also supports
52 * horizontal and vertical gaps; these are used as spacing between
53 * cells.
55 * @author Tom Tromey (tromey@redhat.com)
56 * @author Aaron M. Renn (arenn@urbanophile.com)
58 public class GridLayout implements LayoutManager, Serializable
60 static final long serialVersionUID = -7411804673224730901L;
62 /** Add a new component to the layout. This particular implementation
63 * does nothing.
64 * @param name The name of the component to add.
65 * @param comp The component to add.
67 public void addLayoutComponent (String name, Component comp)
69 // Nothing.
72 /** Return the number of columns in this layout. */
73 public int getColumns ()
75 return cols;
78 /** Return the horizontal gap. */
79 public int getHgap ()
81 return hgap;
84 /** Return the number of rows in this layout. */
85 public int getRows ()
87 return rows;
90 /** Return the vertical gap. */
91 public int getVgap ()
93 return vgap;
96 /** Create a new <code>GridLayout</code> with one row and any number
97 * of columns. Both gaps are set to 0.
99 public GridLayout ()
101 this (1, 0, 0, 0);
104 /** Create a new <code>GridLayout</code> with the specified number
105 * of rows and columns. Both gaps are set to 0. Note that the row
106 * and column settings cannot both be zero. If both the row and
107 * column values are non-zero, the rows value takes precedence.
108 * @param rows Number of rows
109 * @param cols Number of columns
110 * @exception IllegalArgumentException If rows and columns are both
111 * 0, or if either are negative
113 public GridLayout (int rows, int cols)
115 this (rows, cols, 0, 0);
118 /** Create a new GridLayout with the specified number of rows and
119 * columns and the specified gaps.
120 * Note that the row and column settings cannot both be
121 * zero. If both the row and column values are non-zero, the rows value
122 * takes precedence.
123 * @param rows Number of rows
124 * @param cols Number of columns
125 * @param hgap The horizontal gap
126 * @param vgap The vertical gap
127 * @exception IllegalArgumentException If rows and columns are both
128 * 0, if either are negative, or if either gap is negative
130 public GridLayout (int rows, int cols, int hgap, int vgap)
132 if (rows < 0)
133 throw new IllegalArgumentException ("number of rows cannot be negative");
134 if (cols < 0)
135 throw new IllegalArgumentException ("number of columns cannot be negative");
136 if (rows == 0 && cols == 0)
137 throw new IllegalArgumentException ("both rows and columns cannot be 0");
138 if (hgap < 0)
139 throw new IllegalArgumentException ("horizontal gap must be nonnegative");
140 if (vgap < 0)
141 throw new IllegalArgumentException ("vertical gap must be nonnegative");
142 this.rows = rows;
143 this.cols = cols;
144 this.hgap = hgap;
145 this.vgap = vgap;
148 /** Lay out the container's components based on current settings.
149 * The free space in the container is divided evenly into the specified
150 * number of rows and columns in this object.
151 * @param parent The container to lay out
153 public void layoutContainer (Container parent)
155 synchronized (parent.getTreeLock ())
157 int num = parent.ncomponents;
159 // There's no point, and handling this would mean adding special
160 // cases.
161 if (num == 0)
162 return;
164 // This is more efficient than calling getComponents().
165 Component[] comps = parent.component;
167 int real_rows = rows;
168 int real_cols = cols;
169 if (real_rows == 0)
170 real_rows = (num + real_cols - 1) / real_cols;
171 else
172 real_cols = (num + real_rows - 1) / real_rows;
174 // We might have less than a single row. In this case we expand
175 // to fill.
176 if (num < real_cols)
177 real_cols = num;
179 Dimension d = parent.getSize ();
180 Insets ins = parent.getInsets ();
182 // Compute width and height of each cell in the grid.
183 int tw = d.width - ins.left - ins.right;
184 tw = (tw - (real_cols - 1) * hgap) / real_cols;
185 int th = d.height - ins.top - ins.bottom;
186 th = (th - (real_rows - 1) * vgap) / real_rows;
188 // If the cells are too small, still try to do something.
189 if (tw < 0)
190 tw = 1;
191 if (th < 0)
192 th = 1;
194 int x = ins.left;
195 int y = ins.top;
196 int i = 0;
197 int recount = 0;
199 while (i < num)
201 comps[i].setBounds (x, y, tw, th);
203 ++i;
204 ++recount;
205 if (recount == real_cols)
207 recount = 0;
208 y += vgap + th;
209 x = ins.left;
211 else
212 x += hgap + tw;
217 /** Get the minimum layout size of the container.
218 * @param cont The parent container
220 public Dimension minimumLayoutSize (Container cont)
222 return getSize (cont, true);
225 /** Get the preferred layout size of the container.
226 * @param cont The parent container
228 public Dimension preferredLayoutSize (Container cont)
230 return getSize (cont, false);
233 /** Remove the indicated component from this layout manager.
234 * This particular implementation does nothing.
235 * @param comp The component to remove
237 public void removeLayoutComponent (Component comp)
239 // Nothing.
242 /** Set the number of columns.
243 * @param newCols
244 * @exception IllegalArgumentException If the number of columns is
245 * negative, or if the number of columns is zero and the number
246 * of rows is already 0.
248 public void setColumns (int newCols)
250 if (newCols < 0)
251 throw new IllegalArgumentException ("number of columns cannot be negative");
252 if (newCols == 0 && rows == 0)
253 throw new IllegalArgumentException ("number of rows is already 0");
254 this.cols = newCols;
257 /** Set the horizontal gap
258 * @param hgap The horizontal gap
259 * @exception IllegalArgumentException If the hgap value is less than zero.
261 public void setHgap (int hgap)
263 if (hgap < 0)
264 throw new IllegalArgumentException ("horizontal gap must be nonnegative");
265 this.hgap = hgap;
268 /** Set the number of rows
269 * @param newRows
270 * @exception IllegalArgumentException If the number of rows is
271 * negative, or if the number of rows is zero and the number
272 * of columns is already 0.
274 public void setRows (int newRows)
276 if (newRows < 0)
277 throw new IllegalArgumentException ("number of rows cannot be negative");
278 if (newRows == 0 && cols == 0)
279 throw new IllegalArgumentException ("number of columns is already 0");
280 this.rows = newRows;
283 /** Set the vertical gap.
284 * @param vgap The vertical gap
285 * @exception IllegalArgumentException If the vgap value is less than zero.
287 public void setVgap (int vgap)
289 if (vgap < 0)
290 throw new IllegalArgumentException ("vertical gap must be nonnegative");
291 this.vgap = vgap;
294 /** Return String description of this object. */
295 public String toString ()
297 return ("[" + getClass ().getName ()
298 + ",hgap=" + hgap + ",vgap=" + vgap
299 + ",rows=" + rows + ",cols=" + cols
300 + "]");
303 // This method is used to compute the various sizes.
304 private Dimension getSize (Container parent, boolean is_min)
306 synchronized (parent.getTreeLock ())
308 int w = 0, h = 0, num = parent.ncomponents;
309 // This is more efficient than calling getComponents().
310 Component[] comps = parent.component;
312 for (int i = 0; i < num; ++i)
314 Dimension d;
316 if (is_min)
317 d = comps[i].getMinimumSize ();
318 else
319 d = comps[i].getPreferredSize ();
321 w = Math.max (d.width, w);
322 h = Math.max (d.height, h);
325 int real_rows = rows;
326 int real_cols = cols;
327 if (real_rows == 0)
328 real_rows = (num + real_cols - 1) / real_cols;
329 else
330 real_cols = (num + real_rows - 1) / real_rows;
332 Insets ins = parent.getInsets ();
333 // We subtract out an extra gap here because the gaps are only
334 // between cells.
335 w = ins.left + ins.right + real_cols * (w + hgap) - hgap;
336 h = ins.top + ins.bottom + real_rows * (h + vgap) - vgap;
337 return new Dimension (w, h);
342 * @serial The number of columns in the grid.
344 private int cols;
347 * @serial The number of rows in the grid.
349 private int rows;
352 * @serial The horizontal gap between columns
354 private int hgap;
357 * @serial The vertical gap between rows
359 private int vgap;