1 package net.miginfocom.layout;
4 import java.util.ArrayList;
10 * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
11 * All rights reserved.
13 * Redistribution and use in source and binary forms, with or without modification,
14 * are permitted provided that the following conditions are met:
15 * Redistributions of source code must retain the above copyright notice, this list
16 * of conditions and the following disclaimer.
17 * Redistributions in binary form must reproduce the above copyright notice, this
18 * list of conditions and the following disclaimer in the documentation and/or other
19 * materials provided with the distribution.
20 * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
21 * used to endorse or promote products derived from this software without specific
22 * prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
30 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
36 * @author Mikael Grev, MiG InfoCom AB
40 /** A constraint that holds the column <b>or</b> row constraints for the grid. It also holds the gaps between the rows and columns.
42 * This class is a holder and builder for a number of {@link net.miginfocom.layout.DimConstraint}s.
44 * For a more thorough explanation of what these constraints do, and how to build the constraints, see the White Paper or Cheat Sheet at www.migcomponents.com.
46 * Note that there are two way to build this constraint. Through String (e.g. <code>"[100]3[200,fill]"</code> or through API (E.g.
47 * <code>new AC().size("100").gap("3").size("200").fill()</code>.
49 public final class AC implements Externalizable
51 private final ArrayList<DimConstraint> cList = new ArrayList<DimConstraint>(1);
53 private transient int curIx = 0;
55 /** Constructor. Creates an instance that can be configured manually. Will be initialized with a default
56 * {@link net.miginfocom.layout.DimConstraint}.
60 cList.add(new DimConstraint());
63 /** Property. The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of.
64 * These <code>DimConstraints</code> contains all information in this class.
66 * Yes, we are embarrassingly aware that the method is misspelled.
67 * @return The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of. A new list and
68 * never <code>null</code>.
70 public final DimConstraint[] getConstaints()
72 return cList.toArray(new DimConstraint[cList.size()]);
75 /** Sets the different {@link net.miginfocom.layout.DimConstraint}s that this object should consists of.
77 * Yes, we are embarrassingly aware that the method is misspelled.
78 * @param constr The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of. The list
79 * will be copied for storage. <code>null</code> or and empty array will reset the constraints to one <code>DimConstraint</code>
80 * with default values.
82 public final void setConstaints(DimConstraint[] constr)
84 if (constr == null || constr.length < 1 )
85 constr = new DimConstraint[] {new DimConstraint()};
88 cList.ensureCapacity(constr.length);
89 for (DimConstraint c : constr)
93 /** Returns the number of rows/columns that this constraints currently have.
94 * @return The number of rows/columns that this constraints currently have. At least 1.
101 /** Sets the total number of rows/columns to <code>size</code>. If the number of rows/columns is already more
102 * than <code>size</code> nothing will happen.
103 * @param size The total number of rows/columns
104 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
106 public final AC count(int size)
112 /** Specifies that the current row/column should not be grid-like. The while row/column will have its components layed out
113 * in one single cell. It is the same as to say that the cells in this column/row will all be merged (a.k.a spanned).
115 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
116 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
118 public final AC noGrid()
120 return noGrid(curIx);
123 /** Specifies that the indicated rows/columns should not be grid-like. The while row/column will have its components layed out
124 * in one single cell. It is the same as to say that the cells in this column/row will all be merged (a.k.a spanned).
126 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
127 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
128 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
130 public final AC noGrid(int... indexes)
132 for (int i = indexes.length - 1; i >= 0; i--) {
135 cList.get(ix).setNoGrid(true);
140 /** Sets the current row/column to <code>i</code>. If the current number of rows/columns is less than <code>i</code> a call
141 * to {@link #count(int)} will set the size accordingly.
143 * The next call to any of the constraint methods (e.g. {@link net.miginfocom.layout.AC#noGrid}) will be carried
144 * out on this new row/column.
146 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
147 * @param i The new current row/column.
148 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
150 public final AC index(int i)
157 /** Specifies that the current row/column's component should grow by default. It does not affect the size of the row/column.
159 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
160 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
162 public final AC fill()
167 /** Specifies that the indicated rows'/columns' component should grow by default. It does not affect the size of the row/column.
169 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
170 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
171 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
173 public final AC fill(int... indexes)
175 for (int i = indexes.length - 1; i >= 0; i--) {
178 cList.get(ix).setFill(true);
183 // /** Specifies that the current row/column should be put in the end group <code>s</code> and will thus share the same ending
184 // * coordinate within the group.
186 // * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
187 // * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
188 // * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
190 // public final AxisConstraint endGroup(String s)
192 // return endGroup(s, curIx);
195 // /** Specifies that the indicated rows/columns should be put in the end group <code>s</code> and will thus share the same ending
196 // * coordinate within the group.
198 // * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
199 // * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
200 // * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
201 // * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
203 // public final AxisConstraint endGroup(String s, int... indexes)
205 // for (int i = indexes.length - 1; i >= 0; i--) {
206 // int ix = indexes[i];
208 // cList.get(ix).setEndGroup(s);
213 /** Specifies that the current row/column should be put in the size group <code>s</code> and will thus share the same size
214 * constraints as the other components in the group.
216 * Same as <code>sizeGroup("")</code>
218 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
219 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
222 public final AC sizeGroup()
224 return sizeGroup("", curIx);
227 /** Specifies that the current row/column should be put in the size group <code>s</code> and will thus share the same size
228 * constraints as the other components in the group.
230 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
231 * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
232 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
234 public final AC sizeGroup(String s)
236 return sizeGroup(s, curIx);
239 /** Specifies that the indicated rows/columns should be put in the size group <code>s</code> and will thus share the same size
240 * constraints as the other components in the group.
242 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
243 * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
244 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
245 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
247 public final AC sizeGroup(String s, int... indexes)
249 for (int i = indexes.length - 1; i >= 0; i--) {
252 cList.get(ix).setSizeGroup(s);
257 /** Specifies the current row/column's min and/or preferred and/or max size. E.g. <code>"10px"</code> or <code>"50:100:200"</code>.
259 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
260 * @param s The minimum and/or preferred and/or maximum size of this row. The string will be interpreted
261 * as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation.
262 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
264 public final AC size(String s)
266 return size(s, curIx);
269 /** Specifies the indicated rows'/columns' min and/or preferred and/or max size. E.g. <code>"10px"</code> or <code>"50:100:200"</code>.
271 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
272 * @param size The minimum and/or preferred and/or maximum size of this row. The string will be interpreted
273 * as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation.
274 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
275 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
277 public final AC size(String size, int... indexes)
279 BoundSize bs = ConstraintParser.parseBoundSize(size, false, true);
280 for (int i = indexes.length - 1; i >= 0; i--) {
283 cList.get(ix).setSize(bs);
288 /** Specifies the gap size to be the default one <b>AND</b> moves to the next column/row. The method is called <code>.gap()</code>
289 * rather the more natural <code>.next()</code> to indicate that it is very much related to the other <code>.gap(..)</code> methods.
291 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
292 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
294 public final AC gap()
301 /** Specifies the gap size to <code>size</code> <b>AND</b> moves to the next column/row.
303 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
304 * @param size minimum and/or preferred and/or maximum size of the gap between this and the next row/column.
305 * The string will be interpreted as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation.
306 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
308 public final AC gap(String size)
310 return gap(size, curIx++);
313 /** Specifies the indicated rows'/columns' gap size to <code>size</code>.
315 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
316 * @param size minimum and/or preferred and/or maximum size of the gap between this and the next row/column.
317 * The string will be interpreted as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation.
318 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
319 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
321 public final AC gap(String size, int... indexes)
323 BoundSize bsa = size != null ? ConstraintParser.parseBoundSize(size, true, true) : null;
325 for (int i = indexes.length - 1; i >= 0; i--) {
329 cList.get(ix).setGapAfter(bsa);
334 /** Specifies the current row/column's columns default alignment <b>for its components</b>. It does not affect the positioning
335 * or size of the columns/row itself. For columns it is the horizontal alignment (e.g. "left") and for rows it is the vertical
336 * alignment (e.g. "top").
338 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
339 * @param side The default side to align the components. E.g. "top" or "left", or "leading" or "trailing" or "bottom" or "right".
340 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
342 public final AC align(String side)
344 return align(side, curIx);
347 /** Specifies the indicated rows'/columns' columns default alignment <b>for its components</b>. It does not affect the positioning
348 * or size of the columns/row itself. For columns it is the horizontal alignment (e.g. "left") and for rows it is the vertical
349 * alignment (e.g. "top").
351 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
352 * @param side The default side to align the components. E.g. "top" or "left", or "before" or "after" or "bottom" or "right".
353 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
354 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
356 public final AC align(String side, int... indexes)
358 UnitValue al = ConstraintParser.parseAlignKeywords(side, true);
360 al = ConstraintParser.parseAlignKeywords(side, false);
362 for (int i = indexes.length - 1; i >= 0; i--) {
365 cList.get(ix).setAlign(al);
370 /** Specifies the current row/column's grow priority.
372 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
373 * @param p The new grow priority.
374 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
376 public final AC growPrio(int p)
378 return growPrio(p, curIx);
381 /** Specifies the indicated rows'/columns' grow priority.
383 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
384 * @param p The new grow priority.
385 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
386 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
388 public final AC growPrio(int p, int... indexes)
390 for (int i = indexes.length - 1; i >= 0; i--) {
393 cList.get(ix).setGrowPriority(p);
398 /** Specifies the current row/column's grow weight within columns/rows with the <code>grow priority</code> 100f.
400 * Same as <code>grow(100f)</code>
402 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
403 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
406 public final AC grow()
408 return grow(100f, curIx);
411 /** Specifies the current row/column's grow weight within columns/rows with the same <code>grow priority</code>.
413 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
414 * @param w The new grow weight.
415 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
417 public final AC grow(float w)
419 return grow(w, curIx);
422 /** Specifies the indicated rows'/columns' grow weight within columns/rows with the same <code>grow priority</code>.
424 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
425 * @param w The new grow weight.
426 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
427 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
429 public final AC grow(float w, int... indexes)
431 Float gw = new Float(w);
432 for (int i = indexes.length - 1; i >= 0; i--) {
435 cList.get(ix).setGrow(gw);
440 /** Specifies the current row/column's shrink priority.
442 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
443 * @param p The new shrink priority.
444 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
446 public final AC shrinkPrio(int p)
448 return shrinkPrio(p, curIx);
451 /** Specifies the indicated rows'/columns' shrink priority.
453 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
454 * @param p The new shrink priority.
455 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
456 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
458 public final AC shrinkPrio(int p, int... indexes)
460 for (int i = indexes.length - 1; i >= 0; i--) {
463 cList.get(ix).setShrinkPriority(p);
468 /** Specifies that the current row/column's shrink weight within the columns/rows with the <code>shrink priority</code> 100f.
470 * Same as <code>shrink(100f)</code>.
472 * For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
473 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
476 public final AC shrink()
478 return shrink(100f, curIx);
481 /** Specifies that the current row/column's shrink weight within the columns/rows with the same <code>shrink priority</code>.
483 * For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
484 * @param w The shrink weight.
485 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
488 public final AC shrink(float w)
490 return shrink(w, curIx);
493 /** Specifies the indicated rows'/columns' shrink weight within the columns/rows with the same <code>shrink priority</code>.
495 * For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
496 * @param w The shrink weight.
497 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
498 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
501 public final AC shrink(float w, int... indexes)
503 Float sw = new Float(w);
504 for (int i = indexes.length - 1; i >= 0; i--) {
507 cList.get(ix).setShrink(sw);
512 /** Specifies that the current row/column's shrink weight within the columns/rows with the same <code>shrink priority</code>.
514 * For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
515 * @param w The shrink weight.
516 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
517 * @deprecated in 3.7.2. Use {@link #shrink(float)} instead.
519 public final AC shrinkWeight(float w)
524 /** Specifies the indicated rows'/columns' shrink weight within the columns/rows with the same <code>shrink priority</code>.
526 * For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
527 * @param w The shrink weight.
528 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
529 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
530 * @deprecated in 3.7.2. Use {@link #shrink(float, int...)} instead.
532 public final AC shrinkWeight(float w, int... indexes)
534 return shrink(w, indexes);
537 private void makeSize(int sz)
539 if (cList.size() <= sz) {
540 cList.ensureCapacity(sz);
541 for (int i = cList.size(); i <= sz; i++)
542 cList.add(new DimConstraint());
546 // ************************************************
547 // Persistence Delegate and Serializable combined.
548 // ************************************************
550 private Object readResolve() throws ObjectStreamException
552 return LayoutUtil.getSerializedObject(this);
556 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
558 LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
562 public void writeExternal(ObjectOutput out) throws IOException
564 if (getClass() == AC.class)
565 LayoutUtil.writeAsXML(out, this);