1 package net.miginfocom.layout;
3 import java.io.Externalizable;
4 import java.io.IOException;
5 import java.io.ObjectInput;
6 import java.io.ObjectOutput;
7 import java.io.ObjectStreamException;
8 import java.util.ArrayList;
14 * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
15 * All rights reserved.
17 * Redistribution and use in source and binary forms, with or without modification,
18 * are permitted provided that the following conditions are met:
19 * Redistributions of source code must retain the above copyright notice, this list
20 * of conditions and the following disclaimer.
21 * Redistributions in binary form must reproduce the above copyright notice, this
22 * list of conditions and the following disclaimer in the documentation and/or other
23 * materials provided with the distribution.
24 * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
25 * used to endorse or promote products derived from this software without specific
26 * prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
31 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
32 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
34 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
35 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
40 * @author Mikael Grev, MiG InfoCom AB
44 /** A constraint that holds the column <b>or</b> row constraints for the grid. It also holds the gaps between the rows and columns.
46 * This class is a holder and builder for a number of {@link net.miginfocom.layout.DimConstraint}s.
48 * 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.
50 * 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.
51 * <code>new AC().size("100").gap("3").size("200").fill()</code>.
53 public final class AC //implements Externalizable
55 private final ArrayList<DimConstraint> cList = new ArrayList<DimConstraint>(1);
57 private transient int curIx = 0;
59 /** Constructor. Creates an instance that can be configured manually. Will be initialized with a default
60 * {@link net.miginfocom.layout.DimConstraint}.
64 cList.add(new DimConstraint());
67 /** Property. The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of.
68 * These <code>DimConstraints</code> contains all information in this class.
70 * Yes, we are embarrassingly aware that the method is misspelled.
71 * @return The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of. A new list and
72 * never <code>null</code>.
74 public final DimConstraint[] getConstaints()
76 return cList.toArray(new DimConstraint[cList.size()]);
79 /** Sets the different {@link net.miginfocom.layout.DimConstraint}s that this object should consists of.
81 * Yes, we are embarrassingly aware that the method is misspelled.
82 * @param constr The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of. The list
83 * will be copied for storage. <code>null</code> or and empty array will reset the constraints to one <code>DimConstraint</code>
84 * with default values.
86 public final void setConstaints(DimConstraint[] constr)
88 if (constr == null || constr.length < 1 )
89 constr = new DimConstraint[] {new DimConstraint()};
92 cList.ensureCapacity(constr.length);
93 for (DimConstraint c : constr)
97 /** Returns the number of rows/columns that this constraints currently have.
98 * @return The number of rows/columns that this constraints currently have. At least 1.
100 public int getCount()
105 /** Sets the total number of rows/columns to <code>size</code>. If the number of rows/columns is already more
106 * than <code>size</code> nothing will happen.
107 * @param size The total number of rows/columns
108 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
110 public final AC count(int size)
116 /** Specifies that the current row/column should not be grid-like. The while row/column will have its components layed out
117 * 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).
119 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
120 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
122 public final AC noGrid()
124 return noGrid(curIx);
127 /** Specifies that the indicated rows/columns should not be grid-like. The while row/column will have its components layed out
128 * 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).
130 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
131 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
132 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
134 public final AC noGrid(int... indexes)
136 for (int i = indexes.length - 1; i >= 0; i--) {
139 cList.get(ix).setNoGrid(true);
144 /** Sets the current row/column to <code>i</code>. If the current number of rows/columns is less than <code>i</code> a call
145 * to {@link #count(int)} will set the size accordingly.
147 * The next call to any of the constraint methods (e.g. {@link net.miginfocom.layout.AC#noGrid}) will be carried
148 * out on this new row/column.
150 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
151 * @param i The new current row/column.
152 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
154 public final AC index(int i)
161 /** Specifies that the current row/column's component should grow by default. It does not affect the size of the row/column.
163 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
164 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
166 public final AC fill()
171 /** Specifies that the indicated rows'/columns' component should grow by default. It does not affect the size of the row/column.
173 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
174 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
175 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
177 public final AC fill(int... indexes)
179 for (int i = indexes.length - 1; i >= 0; i--) {
182 cList.get(ix).setFill(true);
187 // /** Specifies that the current row/column should be put in the end group <code>s</code> and will thus share the same ending
188 // * coordinate within the group.
190 // * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
191 // * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
192 // * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
194 // public final AxisConstraint endGroup(String s)
196 // return endGroup(s, curIx);
199 // /** Specifies that the indicated rows/columns should be put in the end group <code>s</code> and will thus share the same ending
200 // * coordinate within the group.
202 // * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
203 // * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
204 // * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
205 // * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
207 // public final AxisConstraint endGroup(String s, int... indexes)
209 // for (int i = indexes.length - 1; i >= 0; i--) {
210 // int ix = indexes[i];
212 // cList.get(ix).setEndGroup(s);
217 /** Specifies that the current row/column should be put in the size group <code>s</code> and will thus share the same size
218 * constraints as the other components in the group.
220 * Same as <code>sizeGroup("")</code>
222 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
223 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
226 public final AC sizeGroup()
228 return sizeGroup("", curIx);
231 /** Specifies that the current row/column should be put in the size group <code>s</code> and will thus share the same size
232 * constraints as the other components in the group.
234 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
235 * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
236 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
238 public final AC sizeGroup(String s)
240 return sizeGroup(s, curIx);
243 /** Specifies that the indicated rows/columns should be put in the size group <code>s</code> and will thus share the same size
244 * constraints as the other components in the group.
246 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
247 * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
248 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
249 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
251 public final AC sizeGroup(String s, int... indexes)
253 for (int i = indexes.length - 1; i >= 0; i--) {
256 cList.get(ix).setSizeGroup(s);
261 /** 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>.
263 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
264 * @param s The minimum and/or preferred and/or maximum size of this row. The string will be interpreted
265 * as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation.
266 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
268 public final AC size(String s)
270 return size(s, curIx);
273 /** Specifies the indicated rows'/columns' min and/or preferred and/or max size. E.g. <code>"10px"</code> or <code>"50:100:200"</code>.
275 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
276 * @param size The minimum and/or preferred and/or maximum size of this row. The string will be interpreted
277 * as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation.
278 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
279 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
281 public final AC size(String size, int... indexes)
283 BoundSize bs = ConstraintParser.parseBoundSize(size, false, true);
284 for (int i = indexes.length - 1; i >= 0; i--) {
287 cList.get(ix).setSize(bs);
292 /** 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>
293 * rather the more natural <code>.next()</code> to indicate that it is very much related to the other <code>.gap(..)</code> methods.
295 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
296 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
298 public final AC gap()
305 /** Specifies the gap size to <code>size</code> <b>AND</b> moves to the next column/row.
307 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
308 * @param size minimum and/or preferred and/or maximum size of the gap between this and the next row/column.
309 * The string will be interpreted as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation.
310 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
312 public final AC gap(String size)
314 return gap(size, curIx++);
317 /** Specifies the indicated rows'/columns' gap size to <code>size</code>.
319 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
320 * @param size minimum and/or preferred and/or maximum size of the gap between this and the next row/column.
321 * The string will be interpreted as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation.
322 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
323 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
325 public final AC gap(String size, int... indexes)
327 BoundSize bsa = size != null ? ConstraintParser.parseBoundSize(size, true, true) : null;
329 for (int i = indexes.length - 1; i >= 0; i--) {
333 cList.get(ix).setGapAfter(bsa);
338 /** Specifies the current row/column's columns default alignment <b>for its components</b>. It does not affect the positioning
339 * or size of the columns/row itself. For columns it is the horizontal alignment (e.g. "left") and for rows it is the vertical
340 * alignment (e.g. "top").
342 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
343 * @param side The default side to align the components. E.g. "top" or "left", or "leading" or "trailing" or "bottom" or "right".
344 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
346 public final AC align(String side)
348 return align(side, curIx);
351 /** Specifies the indicated rows'/columns' columns default alignment <b>for its components</b>. It does not affect the positioning
352 * or size of the columns/row itself. For columns it is the horizontal alignment (e.g. "left") and for rows it is the vertical
353 * alignment (e.g. "top").
355 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
356 * @param side The default side to align the components. E.g. "top" or "left", or "before" or "after" or "bottom" or "right".
357 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
358 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
360 public final AC align(String side, int... indexes)
362 UnitValue al = ConstraintParser.parseAlignKeywords(side, true);
364 al = ConstraintParser.parseAlignKeywords(side, false);
366 for (int i = indexes.length - 1; i >= 0; i--) {
369 cList.get(ix).setAlign(al);
374 /** Specifies the current row/column's grow priority.
376 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
377 * @param p The new grow priority.
378 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
380 public final AC growPrio(int p)
382 return growPrio(p, curIx);
385 /** Specifies the indicated rows'/columns' grow priority.
387 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
388 * @param p The new grow priority.
389 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
390 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
392 public final AC growPrio(int p, int... indexes)
394 for (int i = indexes.length - 1; i >= 0; i--) {
397 cList.get(ix).setGrowPriority(p);
402 /** Specifies the current row/column's grow weight within columns/rows with the <code>grow priority</code> 100f.
404 * Same as <code>grow(100f)</code>
406 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
407 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
410 public final AC grow()
412 return grow(100f, curIx);
415 /** Specifies the current row/column's grow weight within columns/rows with the same <code>grow priority</code>.
417 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
418 * @param w The new grow weight.
419 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
421 public final AC grow(float w)
423 return grow(w, curIx);
426 /** Specifies the indicated rows'/columns' grow weight within columns/rows with the same <code>grow priority</code>.
428 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
429 * @param w The new grow weight.
430 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
431 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
433 public final AC grow(float w, int... indexes)
435 Float gw = new Float(w);
436 for (int i = indexes.length - 1; i >= 0; i--) {
439 cList.get(ix).setGrow(gw);
444 /** Specifies the current row/column's shrink priority.
446 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
447 * @param p The new shrink priority.
448 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
450 public final AC shrinkPrio(int p)
452 return shrinkPrio(p, curIx);
455 /** Specifies the indicated rows'/columns' shrink priority.
457 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
458 * @param p The new shrink priority.
459 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
460 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
462 public final AC shrinkPrio(int p, int... indexes)
464 for (int i = indexes.length - 1; i >= 0; i--) {
467 cList.get(ix).setShrinkPriority(p);
472 /** Specifies that the current row/column's shrink weight within the columns/rows with the <code>shrink priority</code> 100f.
474 * Same as <code>shrink(100f)</code>.
476 * For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
477 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
480 public final AC shrink()
482 return shrink(100f, curIx);
485 /** Specifies that the current row/column's shrink weight within the columns/rows with the same <code>shrink priority</code>.
487 * For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
488 * @param w The shrink weight.
489 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
492 public final AC shrink(float w)
494 return shrink(w, curIx);
497 /** Specifies the indicated rows'/columns' shrink weight within the columns/rows with the same <code>shrink priority</code>.
499 * For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
500 * @param w The shrink weight.
501 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
502 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
505 public final AC shrink(float w, int... indexes)
507 Float sw = new Float(w);
508 for (int i = indexes.length - 1; i >= 0; i--) {
511 cList.get(ix).setShrink(sw);
516 /** Specifies that the current row/column's shrink weight within the columns/rows with the same <code>shrink priority</code>.
518 * For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
519 * @param w The shrink weight.
520 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
521 * @deprecated in 3.7.2. Use {@link #shrink(float)} instead.
523 public final AC shrinkWeight(float w)
528 /** Specifies the indicated rows'/columns' shrink weight within the columns/rows with the same <code>shrink priority</code>.
530 * For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
531 * @param w The shrink weight.
532 * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
533 * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
534 * @deprecated in 3.7.2. Use {@link #shrink(float, int...)} instead.
536 public final AC shrinkWeight(float w, int... indexes)
538 return shrink(w, indexes);
541 private void makeSize(int sz)
543 if (cList.size() <= sz) {
544 cList.ensureCapacity(sz);
545 for (int i = cList.size(); i <= sz; i++)
546 cList.add(new DimConstraint());
550 // // ************************************************
551 // // Persistence Delegate and Serializable combined.
552 // // ************************************************
554 // private Object readResolve() throws ObjectStreamException
556 // return LayoutUtil.getSerializedObject(this);
560 // public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
562 // LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
566 // public void writeExternal(ObjectOutput out) throws IOException
568 // if (getClass() == AC.class)
569 // LayoutUtil.writeAsXML(out, this);