JAL-3032 adds Java 8 functionality (2/2)
[jalview.git] / src2 / net / miginfocom / layout / CC.java
1 package net.miginfocom.layout;
2
3 import java.io.*;
4 import java.util.ArrayList;
5 /*
6  * License (BSD):
7  * ==============
8  *
9  * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without modification,
13  * are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice, this list
15  * of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice, this
17  * list of conditions and the following disclaimer in the documentation and/or other
18  * materials provided with the distribution.
19  * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
20  * used to endorse or promote products derived from this software without specific
21  * prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
29  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32  * OF SUCH DAMAGE.
33  *
34  * @version 1.0
35  * @author Mikael Grev, MiG InfoCom AB
36  *         Date: 2006-sep-08
37  */
38
39 /** A simple value holder for one component's constraint.
40  */
41 public final class CC implements Externalizable
42 {
43         private static final BoundSize DEF_GAP = BoundSize.NULL_SIZE;    // Only used to denote default wrap/newline gap.
44
45         static final String[] DOCK_SIDES = {"north", "west", "south", "east"};
46
47         // See the getters and setters for information about the properties below.
48
49         private int dock = -1;
50
51         private UnitValue[] pos = null; // [x1, y1, x2, y2]
52
53         private UnitValue[] padding = null;   // top, left, bottom, right
54
55         private UnitValue[] visualPadding = null;   // top, left, bottom, right
56
57         private Boolean flowX = null;
58
59         private int skip = 0;
60
61         private int split = 1;
62
63         private int spanX = 1, spanY = 1;
64
65         private int cellX = -1, cellY = 0; // If cellX is -1 then cellY is also considered -1. cellY is never negative.
66
67         private String tag = null;
68
69         private String id = null;
70
71         private int hideMode = -1;
72
73         private DimConstraint hor = new DimConstraint();
74
75         private DimConstraint ver = new DimConstraint();
76
77         private BoundSize newline = null;
78
79         private BoundSize wrap = null;
80
81         private boolean boundsInGrid = true;
82
83         private boolean external = false;
84
85         private Float pushX = null, pushY = null;
86
87         private AnimSpec animSpec = AnimSpec.DEF;
88
89
90         // ***** Tmp cache field
91
92         private static final String[] EMPTY_ARR = new String[0];
93
94         private transient String[] linkTargets = null;
95
96         /** Empty constructor.
97          */
98         public CC()
99         {
100         }
101
102         String[] getLinkTargets()
103         {
104                 if (linkTargets == null) {
105                         final ArrayList<String> targets = new ArrayList<String>(2);
106
107                         if (pos != null) {
108                                 for (int i = 0; i < pos.length ; i++)
109                                         addLinkTargetIDs(targets, pos[i]);
110                         }
111
112                         linkTargets = targets.size() == 0 ? EMPTY_ARR : targets.toArray(new String[targets.size()]);
113                 }
114                 return linkTargets;
115         }
116
117         private void addLinkTargetIDs(ArrayList<String> targets, UnitValue uv)
118         {
119                 if (uv != null) {
120                         String linkId = uv.getLinkTargetId();
121                         if (linkId != null) {
122                                 targets.add(linkId);
123                         } else {
124                                 for (int i = uv.getSubUnitCount() - 1; i >= 0; i--) {
125                                         UnitValue subUv = uv.getSubUnitValue(i);
126                                         if (subUv.isLinkedDeep())
127                                                 addLinkTargetIDs(targets, subUv);
128                                 }
129                         }
130                 }
131         }
132
133         // **********************************************************
134         // Chaining constraint setters
135         // **********************************************************
136
137         /** Specifies that the component should be put in the end group <code>s</code> and will thus share the same ending
138          * coordinate as them within the group.
139          * <p>
140          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
141          * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
142          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
143          */
144         public final CC endGroupX(String s)
145         {
146                 hor.setEndGroup(s);
147                 return this;
148         }
149
150         /** Specifies that the component should be put in the size group <code>s</code> and will thus share the same size
151          * as them within the group.
152          * <p>
153          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
154          * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
155          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
156          */
157         public final CC sizeGroupX(String s)
158         {
159                 hor.setSizeGroup(s);
160                 return this;
161         }
162
163         /** The minimum size for the component. The value will override any value that is set on the component itself.
164          * <p>
165          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
166          * @param size The size expressed as a <code>UnitValue</code>. E.g. "100px" or "200mm".
167          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
168          */
169         public final CC minWidth(String size)
170         {
171                 hor.setSize(LayoutUtil.derive(hor.getSize(), ConstraintParser.parseUnitValue(size, true), null, null));
172                 return this;
173         }
174
175         /** The size for the component as a min and/or preferred and/or maximum size. The value will override any value that is set on
176          * the component itself.
177          * <p>
178          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
179          * @param size The size expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px".
180          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
181          */
182         public final CC width(String size)
183         {
184                 hor.setSize(ConstraintParser.parseBoundSize(size, false, true));
185                 return this;
186         }
187
188         /** The maximum size for the component. The value will override any value that is set on the component itself.
189          * <p>
190          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
191          * @param size The size expressed as a <code>UnitValue</code>. E.g. "100px" or "200mm".
192          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
193          */
194         public final CC maxWidth(String size)
195         {
196                 hor.setSize(LayoutUtil.derive(hor.getSize(), null, null, ConstraintParser.parseUnitValue(size, true)));
197                 return this;
198         }
199
200
201         /** The horizontal gap before and/or after the component. The gap is towards cell bounds and/or other component bounds.
202          * <p>
203          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
204          * @param before The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!".
205          * @param after The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!".
206          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
207          */
208         public final CC gapX(String before, String after)
209         {
210                 if (before != null)
211                         hor.setGapBefore(ConstraintParser.parseBoundSize(before, true, true));
212
213                 if (after != null)
214                         hor.setGapAfter(ConstraintParser.parseBoundSize(after, true, true));
215
216                 return this;
217         }
218
219         /** Same functionality as <code>getHorizontal().setAlign(ConstraintParser.parseUnitValue(unitValue, true))</code> only this method
220          * returns <code>this</code> for chaining multiple calls.
221          * <p>
222          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
223          * @param align The align keyword or for instance "100px". E.g "left", "right", "leading" or "trailing".
224          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
225          */
226         public final CC alignX(String align)
227         {
228                 hor.setAlign(ConstraintParser.parseUnitValueOrAlign(align, true, null));
229                 return this;
230         }
231
232         /** The grow priority compared to other components in the same cell.
233          * <p>
234          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
235          * @param p The grow priority.
236          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
237          */
238         public final CC growPrioX(int p)
239         {
240                 hor.setGrowPriority(p);
241                 return this;
242         }
243
244         /** Grow priority for the component horizontally and optionally vertically.
245          * <p>
246          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
247          * @param widthHeight The new shrink weight and height. 1-2 arguments, never null.
248          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
249          * @since 3.7.2
250          */
251         public final CC growPrio(int ... widthHeight)
252         {
253                 switch (widthHeight.length) {
254                         default:
255                                 throw new IllegalArgumentException("Illegal argument count: " + widthHeight.length);
256                         case 2:
257                                 growPrioY(widthHeight[1]);
258                         case 1:
259                                 growPrioX(widthHeight[0]);
260                 }
261                 return this;
262         }
263
264         /** Grow weight for the component horizontally. It default to weight <code>100</code>.
265          * <p>
266          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
267          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
268          * @see #growX(float)
269          */
270         public final CC growX()
271         {
272                 hor.setGrow(ResizeConstraint.WEIGHT_100);
273                 return this;
274         }
275
276         /** Grow weight for the component horizontally.
277          * <p>
278          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
279          * @param w The new grow weight.
280          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
281          */
282         public final CC growX(float w)
283         {
284                 hor.setGrow(new Float(w));
285                 return this;
286         }
287
288         /** grow weight for the component horizontally and optionally vertically.
289          * <p>
290          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
291          * @param widthHeight The new shrink weight and height. 1-2 arguments, never null.
292          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
293          * @since 3.7.2
294          */
295         public final CC grow(float ... widthHeight)
296         {
297                 switch (widthHeight.length) {
298                         default:
299                                 throw new IllegalArgumentException("Illegal argument count: " + widthHeight.length);
300                         case 2:
301                                 growY(widthHeight[1]);
302                         case 1:
303                                 growX(widthHeight[0]);
304                 }
305                 return this;
306         }
307
308         /** The shrink priority compared to other components in the same cell.
309          * <p>
310          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
311          * @param p The shrink priority.
312          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
313          */
314         public final CC shrinkPrioX(int p)
315         {
316                 hor.setShrinkPriority(p);
317                 return this;
318         }
319
320         /** Shrink priority for the component horizontally and optionally vertically.
321          * <p>
322          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
323          * @param widthHeight The new shrink weight and height. 1-2 arguments, never null.
324          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
325          * @since 3.7.2
326          */
327         public final CC shrinkPrio(int ... widthHeight)
328         {
329                 switch (widthHeight.length) {
330                         default:
331                                 throw new IllegalArgumentException("Illegal argument count: " + widthHeight.length);
332                         case 2:
333                                 shrinkPrioY(widthHeight[1]);
334                         case 1:
335                                 shrinkPrioX(widthHeight[0]);
336                 }
337                 return this;
338         }
339
340         /** Shrink weight for the component horizontally.
341          * <p>
342          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
343          * @param w The new shrink weight.
344          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
345          */
346         public final CC shrinkX(float w)
347         {
348                 hor.setShrink(new Float(w));
349                 return this;
350         }
351
352         /** Shrink weight for the component horizontally and optionally vertically.
353          * <p>
354          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
355          * @param widthHeight The new shrink weight and height. 1-2 arguments, never null.
356          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
357          * @since 3.7.2
358          */
359         public final CC shrink(float ... widthHeight)
360         {
361                 switch (widthHeight.length) {
362                         default:
363                                 throw new IllegalArgumentException("Illegal argument count: " + widthHeight.length);
364                         case 2:
365                                 shrinkY(widthHeight[1]);
366                         case 1:
367                                 shrinkX(widthHeight[0]);
368                 }
369                 return this;
370         }
371
372         /** The end group that this component should be placed in.
373          * <p>
374          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
375          * @param s The name of the group. If <code>null</code> that means no group (default)
376          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
377          */
378         public final CC endGroupY(String s)
379         {
380                 ver.setEndGroup(s);
381                 return this;
382         }
383
384         /** The end group(s) that this component should be placed in.
385          * <p>
386          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
387          * @param xy The end group for x and y respectively. 1-2 arguments, not null.
388          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
389          * @since 3.7.2
390          */
391         public final CC endGroup(String ... xy)
392         {
393                 switch (xy.length) {
394                         default:
395                                 throw new IllegalArgumentException("Illegal argument count: " + xy.length);
396                         case 2:
397                                 endGroupY(xy[1]);
398                         case 1:
399                                 endGroupX(xy[0]);
400                 }
401                 return this;
402         }
403
404         /** The size group that this component should be placed in.
405          * <p>
406          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
407          * @param s The name of the group. If <code>null</code> that means no group (default)
408          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
409          */
410         public final CC sizeGroupY(String s)
411         {
412                 ver.setSizeGroup(s);
413                 return this;
414         }
415
416         /** The size group(s) that this component should be placed in.
417          * <p>
418          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
419          * @param xy The size group for x and y respectively. 1-2 arguments, not null.
420          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
421          * @since 3.7.2
422          */
423         public final CC sizeGroup(String ... xy)
424         {
425                 switch (xy.length) {
426                         default:
427                                 throw new IllegalArgumentException("Illegal argument count: " + xy.length);
428                         case 2:
429                                 sizeGroupY(xy[1]);
430                         case 1:
431                                 sizeGroupX(xy[0]);
432                 }
433                 return this;
434         }
435
436         /** The minimum size for the component. The value will override any value that is set on the component itself.
437          * <p>
438          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
439          * @param size The size expressed as a <code>UnitValue</code>. E.g. "100px" or "200mm".
440          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
441          */
442         public final CC minHeight(String size)
443         {
444                 ver.setSize(LayoutUtil.derive(ver.getSize(), ConstraintParser.parseUnitValue(size, false), null, null));
445                 return this;
446         }
447
448         /** The size for the component as a min and/or preferred and/or maximum size. The value will override any value that is set on
449          * the component itself.
450          * <p>
451          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
452          * @param size The size expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px".
453          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
454          */
455         public final CC height(String size)
456         {
457                 ver.setSize(ConstraintParser.parseBoundSize(size, false, false));
458                 return this;
459         }
460
461         /** The maximum size for the component. The value will override any value that is set on the component itself.
462          * <p>
463          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
464          * @param size The size expressed as a <code>UnitValue</code>. E.g. "100px" or "200mm".
465          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
466          */
467         public final CC maxHeight(String size)
468         {
469                 ver.setSize(LayoutUtil.derive(ver.getSize(), null, null, ConstraintParser.parseUnitValue(size, false)));
470                 return this;
471         }
472
473         /** The vertical gap before (normally above) and/or after (normally below) the component. The gap is towards cell bounds and/or other component bounds.
474          * <p>
475          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
476          * @param before The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!".
477          * @param after The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!".
478          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
479          */
480         public final CC gapY(String before, String after)
481         {
482                 if (before != null)
483                         ver.setGapBefore(ConstraintParser.parseBoundSize(before, true, false));
484
485                 if (after != null)
486                         ver.setGapAfter(ConstraintParser.parseBoundSize(after, true, false));
487
488                 return this;
489         }
490
491         /** Same functionality as <code>getVertical().setAlign(ConstraintParser.parseUnitValue(unitValue, true))</code> only this method
492          * returns <code>this</code> for chaining multiple calls.
493          * <p>
494          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
495          * @param align The align keyword or for instance "100px". E.g "top" or "bottom".
496          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
497          */
498         public final CC alignY(String align)
499         {
500                 ver.setAlign(ConstraintParser.parseUnitValueOrAlign(align, false, null));
501                 return this;
502         }
503
504         /** The grow priority compared to other components in the same cell.
505          * <p>
506          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
507          * @param p The grow priority.
508          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
509          */
510         public final CC growPrioY(int p)
511         {
512                 ver.setGrowPriority(p);
513                 return this;
514         }
515
516         /** Grow weight for the component vertically. Defaults to <code>100</code>.
517          * <p>
518          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
519          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
520          * @see #growY(Float)
521          */
522         public final CC growY()
523         {
524                 ver.setGrow(ResizeConstraint.WEIGHT_100);
525                 return this;
526         }
527
528         /** Grow weight for the component vertically.
529          * <p>
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 new grow weight.
532          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
533          */
534         public final CC growY(float w)
535         {
536                 ver.setGrow(w);
537                 return this;
538         }
539
540         /** Grow weight for the component vertically.
541          * <p>
542          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
543          * @param w The new grow weight.
544          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
545          */
546         @Deprecated
547         public final CC growY(Float w)
548         {
549                 ver.setGrow(w);
550                 return this;
551         }
552
553         /** The shrink priority compared to other components in the same cell.
554          * <p>
555          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
556          * @param p The shrink priority.
557          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
558          */
559         public final CC shrinkPrioY(int p)
560         {
561                 ver.setShrinkPriority(p);
562                 return this;
563         }
564
565         /** Shrink weight for the component horizontally.
566          * <p>
567          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
568          * @param w The new shrink weight.
569          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
570          */
571         public final CC shrinkY(float w)
572         {
573                 ver.setShrink(new Float(w));
574                 return this;
575         }
576
577         /** How this component, if hidden (not visible), should be treated.
578          * <p>
579          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
580          * @param mode The mode. Default to the mode in the {@link net.miginfocom.layout.LC}.
581          * 0 == Normal. Bounds will be calculated as if the component was visible.<br>
582          * 1 == If hidden the size will be 0, 0 but the gaps remain.<br>
583          * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br>
584          * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
585          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
586          */
587         public final CC hideMode(int mode)
588         {
589                 setHideMode(mode);
590                 return this;
591         }
592
593         /** The id used to reference this component in some constraints.
594          * <p>
595          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
596          * @param s The id or <code>null</code>. May consist of a groupID and an componentID which are separated by a dot: ".". E.g. "grp1.id1".
597          * The dot should never be first or last if present.
598          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
599          */
600         public final CC id(String s)
601         {
602                 setId(s);
603                 return this;
604         }
605
606         /** Same functionality as {@link #setTag(String tag)} only this method returns <code>this</code> for chaining multiple calls.
607          * <p>
608          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
609          * @param tag The new tag. May be <code>null</code>.
610          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
611          * @see #setTag(String)
612          */
613         public final CC tag(String tag)
614         {
615                 setTag(tag);
616                 return this;
617         }
618
619         /** Set the cell(s) that the component should occupy in the grid. Same functionality as {@link #setCellX(int col)} and
620          * {@link #setCellY(int row)} together with {@link #setSpanX(int width)} and {@link #setSpanY(int height)}. This method
621          * returns <code>this</code> for chaining multiple calls.
622          * <p>
623          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
624          * @param colRowWidthHeight cellX, cellY, spanX, spanY respectively. 1-4 arguments, not null.
625          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
626          * @see #setCellX(int)
627          * @see #setCellY(int)
628          * @see #setSpanX(int)
629          * @see #setSpanY(int)
630          * @since 3.7.2. Replacing cell(int, int) and cell(int, int, int, int)
631          */
632         public final CC cell(int ... colRowWidthHeight)
633         {
634                 switch (colRowWidthHeight.length) {
635                         default:
636                                 throw new IllegalArgumentException("Illegal argument count: " + colRowWidthHeight.length);
637                         case 4:
638                                 setSpanY(colRowWidthHeight[3]);
639                         case 3:
640                                 setSpanX(colRowWidthHeight[2]);
641                         case 2:
642                                 setCellY(colRowWidthHeight[1]);
643                         case 1:
644                                 setCellX(colRowWidthHeight[0]);
645                 }
646                 return this;
647         }
648
649         /** Same functionality as <code>spanX(cellsX).spanY(cellsY)</code> which means this cell will span cells in both x and y.
650          * This method returns <code>this</code> for chaining multiple calls.
651          * <p>
652          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
653          * Since 3.7.2 this takes an array/vararg whereas it previously only took two specific values, xSpan and ySpan.
654          * @param cells spanX and spanY, when present, and in that order.
655          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
656          * @see #setSpanY(int)
657          * @see #setSpanX(int)
658          * @see #spanY()
659          * @see #spanX()
660          * @since 3.7.2 Replaces span(int, int).
661          */
662         public final CC span(int ... cells)
663         {
664                 if (cells == null || cells.length == 0) {
665                         setSpanX(LayoutUtil.INF);
666                         setSpanY(1);
667                 } else if (cells.length == 1) {
668                         setSpanX(cells[0]);
669                         setSpanY(1);
670                 } else {
671                         setSpanX(cells[0]);
672                         setSpanY(cells[1]);
673                 }
674                 return this;
675         }
676
677         /** Corresponds exactly to the "gap left right top bottom" keyword.
678          * @param args Same as for the "gap" keyword. Length 1-4, never null buf elements can be null.
679          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
680          * @since 3.7.2
681          */
682         public final CC gap(String ... args)
683         {
684                 switch (args.length) {
685                         default:
686                                 throw new IllegalArgumentException("Illegal argument count: " + args.length);
687                         case 4:
688                                 gapBottom(args[3]);
689                         case 3:
690                                 gapTop(args[2]);
691                         case 2:
692                                 gapRight(args[1]);
693                         case 1:
694                                 gapLeft(args[0]);
695                 }
696                 return this;
697         }
698
699         /** Sets the horizontal gap before the component.
700          * <p>
701          * Note! This is currently same as gapLeft(). This might change in 4.x.
702          * @param boundsSize The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!".
703          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
704          * @since 3.7.2
705          */
706         public final CC gapBefore(String boundsSize)
707         {
708                 hor.setGapBefore(ConstraintParser.parseBoundSize(boundsSize, true, true));
709                 return this;
710         }
711
712         /** Sets the horizontal gap after the component.
713          * <p>
714          * Note! This is currently same as gapRight(). This might change in 4.x.
715          * @param boundsSize The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!".
716          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
717          * @since 3.7.2
718          */
719         public final CC gapAfter(String boundsSize)
720         {
721                 hor.setGapAfter(ConstraintParser.parseBoundSize(boundsSize, true, true));
722                 return this;
723         }
724
725         /** Sets the gap above the component.
726          * @param boundsSize The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!".
727          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
728          * @since 3.7.2
729          */
730         public final CC gapTop(String boundsSize)
731         {
732                 ver.setGapBefore(ConstraintParser.parseBoundSize(boundsSize, true, false));
733                 return this;
734         }
735
736         /** Sets the gap to the left the component.
737          * @param boundsSize The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!".
738          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
739          * @since 3.7.2
740          */
741         public final CC gapLeft(String boundsSize)
742         {
743                 hor.setGapBefore(ConstraintParser.parseBoundSize(boundsSize, true, true));
744                 return this;
745         }
746
747         /** Sets the gap below the component.
748          * @param boundsSize The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!".
749          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
750          * @since 3.7.2
751          */
752         public final CC gapBottom(String boundsSize)
753         {
754                 ver.setGapAfter(ConstraintParser.parseBoundSize(boundsSize, true, false));
755                 return this;
756         }
757
758         /** Sets the gap to the right of the component.
759          * @param boundsSize The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!".
760          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
761          * @since 3.7.2
762          */
763         public final CC gapRight(String boundsSize)
764         {
765                 hor.setGapAfter(ConstraintParser.parseBoundSize(boundsSize, true, true));
766                 return this;
767         }
768
769         /** Same functionality as calling {@link #setSpanY(int)} with <code>LayoutUtil.INF</code> which means this cell will span the rest of the column.
770          * This method returns <code>this</code> for chaining multiple calls.
771          * <p>
772          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
773          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
774          * @see #setSpanY(int)
775          * @see #spanY()
776          */
777         public final CC spanY()
778         {
779                 return spanY(LayoutUtil.INF);
780         }
781
782         /** Same functionality as {@link #setSpanY(int)} only this method returns <code>this</code> for chaining multiple calls.
783          * <p>
784          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
785          * @param cells The number of cells to span (i.e. merge).
786          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
787          * @see #setSpanY(int)
788          */
789         public final CC spanY(int cells)
790         {
791                 setSpanY(cells);
792                 return this;
793         }
794
795         /** Same functionality as {@link #setSpanX(int)} which means this cell will span the rest of the row.
796          * This method returns <code>this</code> for chaining multiple calls.
797          * <p>
798          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
799          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
800          * @see #setSpanX(int)
801          * @see #spanX()
802          */
803         public final CC spanX()
804         {
805                 return spanX(LayoutUtil.INF);
806         }
807
808         /** Same functionality as {@link #setSpanX(int)} only this method returns <code>this</code> for chaining multiple calls.
809          * <p>
810          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
811          * @param cells The number of cells to span (i.e. merge).
812          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
813          * @see #setSpanY(int)
814          */
815         public final CC spanX(int cells)
816         {
817                 setSpanX(cells);
818                 return this;
819         }
820
821         /** Same functionality as <code>pushX().pushY()</code> which means this cell will push in both x and y dimensions.
822          * This method returns <code>this</code> for chaining multiple calls.
823          * <p>
824          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
825          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
826          * @see #setPushX(Float)
827          * @see #setPushX(Float)
828          * @see #pushY()
829          * @see #pushX()
830          */
831         public final CC push()
832         {
833                 return pushX().pushY();
834         }
835
836         /** Same functionality as <code>pushX(weightX).pushY(weightY)</code> which means this cell will push in both x and y dimensions.
837          * This method returns <code>this</code> for chaining multiple calls.
838          * <p>
839          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
840          * @param weightX The weight used in the push.
841          * @param weightY The weight used in the push.
842          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
843          * @see #setPushY(Float)
844          * @see #setPushX(Float)
845          * @see #pushY()
846          * @see #pushX()
847          */
848         public final CC push(Float weightX, Float weightY)
849         {
850                 return pushX(weightX).pushY(weightY);
851         }
852
853         /** Same functionality as {@link #setPushY(Float)} which means this cell will push the rest of the column.
854          * This method returns <code>this</code> for chaining multiple calls.
855          * <p>
856          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
857          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
858          * @see #setPushY(Float)
859          */
860         public final CC pushY()
861         {
862                 return pushY(ResizeConstraint.WEIGHT_100);
863         }
864
865         /** Same functionality as {@link #setPushY(Float weight)} only this method returns <code>this</code> for chaining multiple calls.
866          * <p>
867          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
868          * @param weight The weight used in the push.
869          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
870          * @see #setPushY(Float)
871          */
872         public final CC pushY(Float weight)
873         {
874                 setPushY(weight);
875                 return this;
876         }
877
878         /** Same functionality as {@link #setPushX(Float)} which means this cell will push the rest of the row.
879          * This method returns <code>this</code> for chaining multiple calls.
880          * <p>
881          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
882          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
883          * @see #setPushX(Float)
884          */
885         public final CC pushX()
886         {
887                 return pushX(ResizeConstraint.WEIGHT_100);
888         }
889
890         /** Same functionality as {@link #setPushX(Float weight)} only this method returns <code>this</code> for chaining multiple calls.
891          * <p>
892          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
893          * @param weight The weight used in the push.
894          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
895          * @see #setPushY(Float)
896          */
897         public final CC pushX(Float weight)
898         {
899                 setPushX(weight);
900                 return this;
901         }
902
903         /** Same functionality as {@link #setSplit(int parts)} only this method returns <code>this</code> for chaining multiple calls.
904          * <p>
905          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
906          * @param parts The number of parts (i.e. component slots) the cell should be divided into.
907          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
908          * @see #setSplit(int)
909          */
910         public final CC split(int parts)
911         {
912                 setSplit(parts);
913                 return this;
914         }
915
916         /** Same functionality as split(LayoutUtil.INF), which means split until one of the keywords that breaks the split is found for
917          * a component after this one (e.g. wrap, newline and skip).
918          * <p>
919          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
920          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
921          * @see #setSplit(int)
922          * @since 3.7.2
923          */
924         public final CC split()
925         {
926                 setSplit(LayoutUtil.INF);
927                 return this;
928         }
929
930         /** Same functionality as {@link #setSkip(int)} only this method returns <code>this</code> for chaining multiple calls.
931          * <p>
932          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
933          * @param cells How many cells in the grid that should be skipped <b>before</b> the component that this constraint belongs to
934          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
935          * @see #setSkip(int)
936          */
937         public final CC skip(int cells)
938         {
939                 setSkip(cells);
940                 return this;
941         }
942
943         /** Same functionality as skip(1).
944          * <p>
945          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
946          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
947          * @see #setSkip(int)
948          * @since 3.7.2
949          */
950         public final CC skip()
951         {
952                 setSkip(1);
953                 return this;
954         }
955
956         /** Same functionality as calling {@link #setExternal(boolean)} with <code>true</code> only this method returns <code>this</code> for chaining multiple calls.
957          * <p>
958          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
959          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
960          * @see #setExternal(boolean)
961          */
962         public final CC external()
963         {
964                 setExternal(true);
965                 return this;
966         }
967
968         /** Same functionality as calling {@link #setFlowX(Boolean)} with <code>Boolean.TRUE</code> only this method returns <code>this</code> for chaining multiple calls.
969          * <p>
970          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
971          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
972          * @see #setFlowX(Boolean)
973          */
974         public final CC flowX()
975         {
976                 setFlowX(Boolean.TRUE);
977                 return this;
978         }
979
980         /** Same functionality as calling {@link #setFlowX(Boolean)} with <code>Boolean.FALSE</code> only this method returns <code>this</code> for chaining multiple calls.
981          * <p>
982          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
983          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
984          * @see #setFlowX(Boolean)
985          */
986         public final CC flowY()
987         {
988                 setFlowX(Boolean.FALSE);
989                 return this;
990         }
991
992
993         /** Same functionality as {@link #growX()} and {@link #growY()}.
994          * <p>
995          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
996          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
997          * @see #growX()
998          * @see #growY()
999          */
1000         public final CC grow()
1001         {
1002                 growX();
1003                 growY();
1004                 return this;
1005         }
1006
1007         /** Same functionality as calling {@link #setNewline(boolean)} with <code>true</code> only this method returns <code>this</code> for chaining multiple calls.
1008          * <p>
1009          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1010          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1011          * @see #setNewline(boolean)
1012          */
1013         public final CC newline()
1014         {
1015                 setNewline(true);
1016                 return this;
1017         }
1018
1019         /** Same functionality as {@link #setNewlineGapSize(BoundSize)} only this method returns <code>this</code> for chaining multiple calls.
1020          * <p>
1021          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1022          * @param gapSize The gap size that will override the gap size in the row/column constraints if <code>!= null</code>. E.g. "5px" or "unrel".
1023          * If <code>null</code> or <code>""</code> the newline size will be set to the default size and turned on. This is different compared to
1024          * {@link #setNewlineGapSize(BoundSize)}.
1025          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1026          * @see #setNewlineGapSize(BoundSize)
1027          */
1028         public final CC newline(String gapSize)
1029         {
1030                 BoundSize bs = ConstraintParser.parseBoundSize(gapSize, true, (flowX != null && flowX == false));
1031                 if (bs != null) {
1032                         setNewlineGapSize(bs);
1033                 } else {
1034                         setNewline(true);
1035                 }
1036                 return this;
1037         }
1038
1039         /** Same functionality as calling {@link #setWrap(boolean)} with <code>true</code> only this method returns <code>this</code> for chaining multiple calls.
1040          * <p>
1041          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1042          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1043          * @see #setWrap(boolean)
1044          */
1045         public final CC wrap()
1046         {
1047                 setWrap(true);
1048                 return this;
1049         }
1050
1051         /** Same functionality as {@link #setWrapGapSize(BoundSize)} only this method returns <code>this</code> for chaining multiple calls.
1052          * <p>
1053          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1054          * @param gapSize The gap size that will override the gap size in the row/column constraints if <code>!= null</code>. E.g. "5px" or "unrel".
1055          * If <code>null</code> or <code>""</code> the wrap size will be set to the default size and turned on. This is different compared to
1056          * {@link #setWrapGapSize(BoundSize)}.
1057          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1058          * @see #setWrapGapSize(BoundSize)
1059          */
1060         public final CC wrap(String gapSize)
1061         {
1062                 BoundSize bs = ConstraintParser.parseBoundSize(gapSize, true, (flowX != null && flowX == false));
1063                 if (bs != null) {
1064                         setWrapGapSize(bs);
1065                 } else {
1066                         setWrap(true);
1067                 }
1068                 return this;
1069         }
1070
1071         /** Same functionality as calling {@link #setDockSide(int)} with <code>0</code> only this method returns <code>this</code> for chaining multiple calls.
1072          * <p>
1073          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1074          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1075          * @see #setDockSide(int)
1076          */
1077         public final CC dockNorth()
1078         {
1079                 setDockSide(0);
1080                 return this;
1081         }
1082
1083         /** Same functionality as calling {@link #setDockSide(int)} with <code>1</code> only this method returns <code>this</code> for chaining multiple calls.
1084          * <p>
1085          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1086          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1087          * @see #setDockSide(int)
1088          */
1089         public final CC dockWest()
1090         {
1091                 setDockSide(1);
1092                 return this;
1093         }
1094
1095         /** Same functionality as calling {@link #setDockSide(int)} with <code>2</code> only this method returns <code>this</code> for chaining multiple calls.
1096          * <p>
1097          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1098          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1099          * @see #setDockSide(int)
1100          */
1101         public final CC dockSouth()
1102         {
1103                 setDockSide(2);
1104                 return this;
1105         }
1106
1107         /** Same functionality as calling {@link #setDockSide(int)} with <code>3</code> only this method returns <code>this</code> for chaining multiple calls.
1108          * <p>
1109          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1110          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1111          * @see #setDockSide(int)
1112          */
1113         public final CC dockEast()
1114         {
1115                 setDockSide(3);
1116                 return this;
1117         }
1118
1119         /** Sets the x-coordinate for the component. This is used to set the x coordinate position to a specific value. The component
1120          * bounds is still precalculated to the grid cell and this method should be seen as a way to correct the x position.
1121          * <p>
1122          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1123          * @param x The x position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
1124          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1125          * @see #setPos(UnitValue[])
1126          * @see #setBoundsInGrid(boolean)
1127          */
1128         public final CC x(String x)
1129         {
1130                 return corrPos(x, 0);
1131         }
1132
1133         /** Sets the y-coordinate for the component. This is used to set the y coordinate position to a specific value. The component
1134          * bounds is still precalculated to the grid cell and this method should be seen as a way to correct the y position.
1135          * <p>
1136          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1137          * @param y The y position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
1138          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1139          * @see #setPos(UnitValue[])
1140          * @see #setBoundsInGrid(boolean)
1141          */
1142         public final CC y(String y)
1143         {
1144                 return corrPos(y, 1);
1145         }
1146
1147         /** Sets the x2-coordinate for the component (right side). This is used to set the x2 coordinate position to a specific value. The component
1148          * bounds is still precalculated to the grid cell and this method should be seen as a way to correct the x position.
1149          * <p>
1150          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1151          * @param x2 The x2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10".
1152          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1153          * @see #setPos(UnitValue[])
1154          * @see #setBoundsInGrid(boolean)
1155          */
1156         public final CC x2(String x2)
1157         {
1158                 return corrPos(x2, 2);
1159         }
1160
1161         /** Sets the y2-coordinate for the component (bottom side). This is used to set the y2 coordinate position to a specific value. The component
1162          * bounds is still precalculated to the grid cell and this method should be seen as a way to correct the y position.
1163          * <p>
1164          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1165          * @param y2 The y2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10".
1166          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1167          * @see #setPos(UnitValue[])
1168          * @see #setBoundsInGrid(boolean)
1169          */
1170         public final CC y2(String y2)
1171         {
1172                 return corrPos(y2, 3);
1173         }
1174
1175         private final CC corrPos(String uv, int ix)
1176         {
1177                 UnitValue[] b = getPos();
1178                 if (b == null)
1179                         b = new UnitValue[4];
1180
1181                 b[ix] = ConstraintParser.parseUnitValue(uv, (ix % 2 == 0));
1182                 setPos(b);
1183
1184                 setBoundsInGrid(true);
1185                 return this;
1186         }
1187
1188         /** Same functionality as {@link #x(String x)} and {@link #y(String y)} together.
1189          * <p>
1190          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1191          * @param x The x position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
1192          * @param y The y position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
1193          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1194          * @see #setPos(UnitValue[])
1195          */
1196         public final CC pos(String x, String y)
1197         {
1198                 UnitValue[] b = getPos();
1199                 if (b == null)
1200                         b = new UnitValue[4];
1201
1202                 b[0] = ConstraintParser.parseUnitValue(x, true);
1203                 b[1] = ConstraintParser.parseUnitValue(y, false);
1204                 setPos(b);
1205
1206                 setBoundsInGrid(false);
1207                 return this;
1208         }
1209
1210         /** Same functionality as {@link #x(String x)}, {@link #y(String y)}, {@link #y2(String y)} and {@link #y2(String y)} together.
1211          * <p>
1212          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1213          * @param x The x position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
1214          * @param y The y position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
1215          * @param x2 The x2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10".
1216          * @param y2 The y2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10".
1217          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1218          * @see #setPos(UnitValue[])
1219          */
1220         public final CC pos(String x, String y, String x2, String y2)
1221         {
1222                 setPos(new UnitValue[] {
1223                                 ConstraintParser.parseUnitValue(x, true),
1224                                 ConstraintParser.parseUnitValue(y, false),
1225                                 ConstraintParser.parseUnitValue(x2, true),
1226                                 ConstraintParser.parseUnitValue(y2, false),
1227                 });
1228                 setBoundsInGrid(false);
1229                 return this;
1230         }
1231
1232         /** Same functionality as {@link #setPadding(UnitValue[])} but the unit values as absolute pixels. This method returns <code>this</code> for chaining multiple calls.
1233          * <p>
1234          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1235          * @param top The top padding that will be added to the y coordinate at the last stage in the layout.
1236          * @param left The top padding that will be added to the x coordinate at the last stage in the layout.
1237          * @param bottom The top padding that will be added to the y2 coordinate at the last stage in the layout.
1238          * @param right The top padding that will be added to the x2 coordinate at the last stage in the layout.
1239          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1240          * @see #setTag(String)
1241          */
1242         public final CC pad(int top, int left, int bottom, int right)
1243         {
1244                 setPadding(new UnitValue[] {
1245                                 new UnitValue(top),     new UnitValue(left), new UnitValue(bottom), new UnitValue(right)
1246                 });
1247                 return this;
1248         }
1249
1250         /** Same functionality as <code>setPadding(ConstraintParser.parseInsets(pad, false))}</code> only this method returns <code>this</code> for chaining multiple calls.
1251          * <p>
1252          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1253          * @param pad The string to parse. E.g. "10 10 10 10" or "20". If less than 4 groups the last will be used for the missing.
1254          * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
1255          * @see #setTag(String)
1256          */
1257         public final CC pad(String pad)
1258         {
1259                 setPadding(pad != null ? ConstraintParser.parseInsets(pad, false) : null);
1260                 return this;
1261         }
1262
1263         // **********************************************************
1264         // Bean properties
1265         // **********************************************************
1266
1267         /** Returns the horizontal dimension constraint for this component constraint. It has constraints for the horizontal size
1268          * and grow/shrink priorities and weights.
1269          * <p>
1270          * Note! If any changes is to be made it must be made direct when the object is returned. It is not allowed to save the
1271          * constraint for later use.
1272          * @return The current dimension constraint. Never <code>null</code>.
1273          */
1274         public DimConstraint getHorizontal()
1275         {
1276                 return hor;
1277         }
1278
1279         /** Sets the horizontal dimension constraint for this component constraint. It has constraints for the horizontal size
1280          * and grow/shrink priorities and weights.
1281          * @param h The new dimension constraint. If <code>null</code> it will be reset to <code>new DimConstraint();</code>
1282          */
1283         public void setHorizontal(DimConstraint h)
1284         {
1285                 hor = h != null ? h : new DimConstraint();
1286         }
1287
1288         /** Returns the vertical dimension constraint for this component constraint. It has constraints for the vertical size
1289          * and grow/shrink priorities and weights.
1290          * <p>
1291          * Note! If any changes is to be made it must be made direct when the object is returned. It is not allowed to save the
1292          * constraint for later use.
1293          * @return The current dimension constraint. Never <code>null</code>.
1294          */
1295         public DimConstraint getVertical()
1296         {
1297                 return ver;
1298         }
1299
1300         /** Sets the vertical dimension constraint for this component constraint. It has constraints for the vertical size
1301          * and grow/shrink priorities and weights.
1302          * @param v The new dimension constraint. If <code>null</code> it will be reset to <code>new DimConstraint();</code>
1303          */
1304         public void setVertical(DimConstraint v)
1305         {
1306                 ver = v != null ? v : new DimConstraint();
1307         }
1308
1309         /** Returns the vertical or horizontal dim constraint.
1310          * <p>
1311          * Note! If any changes is to be made it must be made direct when the object is returned. It is not allowed to save the
1312          * constraint for later use.
1313          * @param isHor If the horizontal constraint should be returned.
1314          * @return The dim constraint. Never <code>null</code>.
1315          */
1316         public DimConstraint getDimConstraint(boolean isHor)
1317         {
1318                 return isHor ? hor : ver;
1319         }
1320
1321         /** Returns the absolute positioning of one or more of the edges. This will be applied last in the layout cycle and will not
1322          * affect the flow or grid positions. The positioning is relative to the parent and can not (as padding) be used
1323          * to adjust the edges relative to the old value. May be <code>null</code> and elements may be <code>null</code>.
1324          * <code>null</code> value(s) for the x2 and y2 will be interpreted as to keep the preferred size and thus the x1
1325          * and x2 will just absolutely positions the component.
1326          * <p>
1327          * Note that {@link #setBoundsInGrid(boolean)} changes the interpretation of this property slightly.
1328          * <p>
1329          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1330          * @return The current value as a new array, free to modify.
1331          */
1332         public UnitValue[] getPos()
1333         {
1334                 return pos != null ? new UnitValue[] {pos[0], pos[1], pos[2], pos[3]} : null;
1335         }
1336
1337         /** Sets absolute positioning of one or more of the edges. This will be applied last in the layout cycle and will not
1338          * affect the flow or grid positions. The positioning is relative to the parent and can not (as padding) be used
1339          * to adjust the edges relative to the old value. May be <code>null</code> and elements may be <code>null</code>.
1340          * <code>null</code> value(s) for the x2 and y2 will be interpreted as to keep the preferred size and thus the x1
1341          * and x2 will just absolutely positions the component.
1342          * <p>
1343          * Note that {@link #setBoundsInGrid(boolean)} changes the interpretation of this property slightly.
1344          * <p>
1345          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1346          * @param pos <code>UnitValue[] {x, y, x2, y2}</code>. Must be <code>null</code> or of length 4. Elements can be <code>null</code>.
1347          */
1348         public void setPos(UnitValue[] pos)
1349         {
1350                 this.pos = pos != null ? new UnitValue[] {pos[0], pos[1], pos[2], pos[3]} : null;
1351                 linkTargets = null;
1352         }
1353
1354         /** Returns if the absolute <code>pos</code> value should be corrections to the component that is in a normal cell. If <code>false</code>
1355          * the value of <code>pos</code> is truly absolute in that it will not affect the grid or have a default bounds in the grid.
1356          * <p>
1357          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1358          * @return The current value.
1359          * @see #getPos()
1360          */
1361         public boolean isBoundsInGrid()
1362         {
1363                 return boundsInGrid;
1364         }
1365
1366         /** Sets if the absolute <code>pos</code> value should be corrections to the component that is in a normal cell. If <code>false</code>
1367          * the value of <code>pos</code> is truly absolute in that it will not affect the grid or have a default bounds in the grid.
1368          * <p>
1369          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1370          * @param b <code>true</code> for bounds taken from the grid position. <code>false</code> is default.
1371          * @see #setPos(UnitValue[])
1372          */
1373         void setBoundsInGrid(boolean b)
1374         {
1375                 this.boundsInGrid = b;
1376         }
1377
1378         /** Returns the absolute cell position in the grid or <code>-1</code> if cell positioning is not used.
1379          * <p>
1380          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1381          * @return The current value.
1382          */
1383         public int getCellX()
1384         {
1385                 return cellX;
1386         }
1387
1388         /** Set an absolute cell x-position in the grid. If &gt;= 0 this point points to the absolute cell that this constaint's component should occupy.
1389          * If there's already a component in that cell they will split the cell. The flow will then continue after this cell.
1390          * <p>
1391          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1392          * @param x The x-position or <code>-1</code> to disable cell positioning.
1393          */
1394         public void setCellX(int x)
1395         {
1396                 cellX = x;
1397         }
1398
1399         /** Returns the absolute cell position in the grid or <code>-1</code> if cell positioning is not used.
1400          * <p>
1401          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1402          * @return The current value.
1403          */
1404         public int getCellY()
1405         {
1406                 return cellX < 0 ? -1 : cellY;
1407         }
1408
1409         /** Set an absolute cell x-position in the grid. If &gt;= 0 this point points to the absolute cell that this constaint's component should occupy.
1410          * If there's already a component in that cell they will split the cell. The flow will then continue after this cell.
1411          * <p>
1412          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1413          * @param y The y-position or <code>-1</code> to disable cell positioning.
1414          */
1415         public void setCellY(int y)
1416         {
1417                 if (y < 0)
1418                         cellX = -1;
1419                 cellY = y < 0 ? 0 : y;
1420         }
1421
1422         /** Sets the docking side. -1 means no docking.<br>
1423          * Valid sides are: <code> north = 0, west = 1, south = 2, east = 3</code>.
1424          * <p>
1425          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1426          * @return The current side.
1427          */
1428         public int getDockSide()
1429         {
1430                 return dock;
1431         }
1432
1433         /** Sets the docking side. -1 means no docking.<br>
1434          * Valid sides are: <code> north = 0, west = 1, south = 2, east = 3</code>.
1435          * <p>
1436          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1437          * @param side -1 or 0-3.
1438          */
1439         public void setDockSide(int side)
1440         {
1441                 if (side < -1 || side > 3)
1442                         throw new IllegalArgumentException("Illegal dock side: " + side);
1443                 dock = side;
1444         }
1445
1446         /** Returns if this component should have its bounds handled by an external source and not this layout manager.
1447          * <p>
1448          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1449          * @return The current value.
1450          */
1451         public boolean isExternal()
1452         {
1453                 return external;
1454         }
1455
1456         /** If this boolean is true this component is not handled in any way by the layout manager and the component can have its bounds set by an external
1457          * handler which is normally by the use of some <code>component.setBounds(x, y, width, height)</code> directly (for Swing).
1458          * <p>
1459          * The bounds <b>will not</b> affect the minimum and preferred size of the container.
1460          * <p>
1461          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1462          * @param b <code>true</code> means that the bounds are not changed.
1463          */
1464         public void setExternal(boolean b)
1465         {
1466                 this.external = b;
1467         }
1468
1469         /** Returns if the flow in the <b>cell</b> is in the horizontal dimension. Vertical if <code>false</code>. Only the first
1470          * component is a cell can set the flow.
1471          * <p>
1472          * If <code>null</code> the flow direction is inherited by from the {@link net.miginfocom.layout.LC}.
1473          * <p>
1474          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1475          * @return The current value.
1476          */
1477         public Boolean getFlowX()
1478         {
1479                 return flowX;
1480         }
1481
1482         /** Sets if the flow in the <b>cell</b> is in the horizontal dimension. Vertical if <code>false</code>. Only the first
1483          * component is a cell can set the flow.
1484          * <p>
1485          * If <code>null</code> the flow direction is inherited by from the {@link net.miginfocom.layout.LC}.
1486          * <p>
1487          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1488          * @param b <code>Boolean.TRUE</code> means horizontal flow in the cell.
1489          */
1490         public void setFlowX(Boolean b)
1491         {
1492                 this.flowX = b;
1493         }
1494
1495         /** Sets how a component that is hidden (not visible) should be treated by default.
1496          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1497          * @return The mode:<br>
1498          * 0 == Normal. Bounds will be calculated as if the component was visible.<br>
1499          * 1 == If hidden the size will be 0, 0 but the gaps remain.<br>
1500          * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br>
1501          * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
1502          */
1503         public int getHideMode()
1504         {
1505                 return hideMode;
1506         }
1507
1508         /** Sets how a component that is hidden (not visible) should be treated by default.
1509          * @param mode The mode:<br>
1510          * 0 == Normal. Bounds will be calculated as if the component was visible.<br>
1511          * 1 == If hidden the size will be 0, 0 but the gaps remain.<br>
1512          * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br>
1513          * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
1514          */
1515         public void setHideMode(int mode)
1516         {
1517                 if (mode < -1 || mode > 3)
1518                         throw new IllegalArgumentException("Wrong hideMode: " + mode);
1519
1520                 hideMode = mode;
1521         }
1522
1523         /** Returns the id used to reference this component in some constraints.
1524          * <p>
1525          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1526          * @return The id or <code>null</code>. May consist of a groupID and an componentID which are separated by a dot: ".". E.g. "grp1.id1".
1527          * The dot should never be first or last if present.
1528          */
1529         public String getId()
1530         {
1531                 return id;
1532         }
1533
1534         /** Sets the id used to reference this component in some constraints.
1535          * <p>
1536          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1537          * @param id The id or <code>null</code>. May consist of a groupID and an componentID which are separated by a dot: ".". E.g. "grp1.id1".
1538          * The dot should never be first or last if present.
1539          */
1540         public void setId(String id)
1541         {
1542                 this.id = id;
1543         }
1544
1545         /** Returns the absolute resizing in the last stage of the layout cycle. May be <code>null</code> and elements may be <code>null</code>.
1546          * <p>
1547          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1548          * @return The current value. <code>null</code> or of length 4.
1549          */
1550         public UnitValue[] getPadding()
1551         {
1552                 return padding != null ? new UnitValue[] {padding[0], padding[1], padding[2], padding[3]} : null;
1553         }
1554
1555         /** Sets the absolute resizing in the last stage of the layout cycle. These values are added to the edges and can thus for
1556          * instance be used to grow or reduce the size or move the component an absolute number of pixels. May be <code>null</code>
1557          * and elements may be <code>null</code>.
1558          * <p>
1559          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1560          * @param sides top, left, bottom right. Must be <code>null</code> or of length 4.
1561          */
1562         public void setPadding(UnitValue[] sides)
1563         {
1564                 this.padding = sides != null ? new UnitValue[] {sides[0], sides[1], sides[2], sides[3]} : null;
1565         }
1566
1567         /** Returns the visual padding used when laying out this Component. May be <code>null</code> and elements may be <code>null</code>.
1568          * <p>
1569          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1570          * @return The current value. <code>null</code> or of length 4.
1571          */
1572         public UnitValue[] getVisualPadding()
1573         {
1574                 return visualPadding != null ? new UnitValue[] {visualPadding[0], visualPadding[1], visualPadding[2], visualPadding[3]} : null;
1575         }
1576
1577         /** Sets the visual padding used when laying out this Component.
1578          * <p>
1579          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1580          * @param sides top, left, bottom right. Must be <code>null</code> or of length 4.
1581          */
1582         public void setVisualPadding(UnitValue[] sides)
1583         {
1584                 this.visualPadding = sides != null ? new UnitValue[] {sides[0], sides[1], sides[2], sides[3]} : null;
1585         }
1586
1587         /** Returns how many cells in the grid that should be skipped <b>before</b> the component that this constraint belongs to.
1588          * <p>
1589          * Note that only the first component will be checked for this property.
1590          * <p>
1591          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1592          * @return The current value. 0 if no skip.
1593          */
1594         public int getSkip()
1595         {
1596                 return skip;
1597         }
1598
1599         /** Sets how many cells in the grid that should be skipped <b>before</b> the component that this constraint belongs to.
1600          * <p>
1601          * Note that only the first component will be checked for this property.
1602          * <p>
1603          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1604          * @param cells How many cells in the grid that should be skipped <b>before</b> the component that this constraint belongs to
1605          */
1606         public void setSkip(int cells)
1607         {
1608                 this.skip = cells;
1609         }
1610
1611         /** Returns the number of cells the cell that this constraint's component will span in the indicated dimension. <code>1</code> is default and
1612          * means that it only spans the current cell. <code>LayoutUtil.INF</code> is used to indicate a span to the end of the column/row.
1613          * <p>
1614          * Note that only the first component will be checked for this property.
1615          * <p>
1616          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1617          * @return The current value.
1618          */
1619         public int getSpanX()
1620         {
1621                 return spanX;
1622         }
1623
1624         /** Sets the number of cells the cell that this constraint's component will span in the indicated dimension. <code>1</code> is default and
1625          * means that it only spans the current cell. <code>LayoutUtil.INF</code> is used to indicate a span to the end of the column/row.
1626          * <p>
1627          * Note that only the first component will be checked for this property.
1628          * <p>
1629          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1630          * @param cells The number of cells to span (i.e. merge).
1631          */
1632         public void setSpanX(int cells)
1633         {
1634                 this.spanX = cells;
1635         }
1636
1637         /** Returns the number of cells the cell that this constraint's component will span in the indicated dimension. <code>1</code> is default and
1638          * means that it only spans the current cell. <code>LayoutUtil.INF</code> is used to indicate a span to the end of the column/row.
1639          * <p>
1640          * Note that only the first component will be checked for this property.
1641          * <p>
1642          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1643          * @return The current value.
1644          */
1645         public int getSpanY()
1646         {
1647                 return spanY;
1648         }
1649
1650         /** Sets the number of cells the cell that this constraint's component will span in the indicated dimension. <code>1</code> is default and
1651          * means that it only spans the current cell. <code>LayoutUtil.INF</code> is used to indicate a span to the end of the column/row.
1652          * <p>
1653          * Note that only the first component will be checked for this property.
1654          * <p>
1655          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1656          * @param cells The number of cells to span (i.e. merge).
1657          */
1658         public void setSpanY(int cells)
1659         {
1660                 this.spanY = cells;
1661         }
1662
1663         /** "pushx" indicates that the column that this component is in (this first if the component spans) should default to growing.
1664          * If any other column has been set to grow this push value on the component does nothing as the column's explicit grow weight
1665          * will take precedence. Push is normally used when the grid has not been defined in the layout.
1666          * <p>
1667          * If multiple components in a column has push weights set the largest one will be used for the column.
1668          * @return The current push value. Default is <code>null</code>.
1669          */
1670         public Float getPushX()
1671         {
1672                 return pushX;
1673         }
1674
1675         /** "pushx" indicates that the column that this component is in (this first if the component spans) should default to growing.
1676          * If any other column has been set to grow this push value on the component does nothing as the column's explicit grow weight
1677          * will take precedence. Push is normally used when the grid has not been defined in the layout.
1678          * <p>
1679          * If multiple components in a column has push weights set the largest one will be used for the column.
1680          * @param weight The new push value. Default is <code>null</code>.
1681          */
1682         public void setPushX(Float weight)
1683         {
1684                 this.pushX = weight;
1685         }
1686
1687         /** "pushx" indicates that the row that this component is in (this first if the component spans) should default to growing.
1688          * If any other row has been set to grow this push value on the component does nothing as the row's explicit grow weight
1689          * will take precedence. Push is normally used when the grid has not been defined in the layout.
1690          * <p>
1691          * If multiple components in a row has push weights set the largest one will be used for the row.
1692          * @return The current push value. Default is <code>null</code>.
1693          */
1694         public Float getPushY()
1695         {
1696                 return pushY;
1697         }
1698
1699         /** "pushx" indicates that the row that this component is in (this first if the component spans) should default to growing.
1700          * If any other row has been set to grow this push value on the component does nothing as the row's explicit grow weight
1701          * will take precedence. Push is normally used when the grid has not been defined in the layout.
1702          * <p>
1703          * If multiple components in a row has push weights set the largest one will be used for the row.
1704          * @param weight The new push value. Default is <code>null</code>.
1705          */
1706         public void setPushY(Float weight)
1707         {
1708                 this.pushY = weight;
1709         }
1710
1711         /** Returns in how many parts the current cell (that this constraint's component will be in) should be split in. If for instance
1712          * it is split in two, the next component will also share the same cell. Note that the cell can also span a number of
1713          * cells, which means that you can for instance span three cells and split that big cell for two components. Split can be
1714          * set to a very high value to make all components in the same row/column share the same cell (e.g. <code>LayoutUtil.INF</code>).
1715          * <p>
1716          * Note that only the first component will be checked for this property.
1717          * <p>
1718          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1719          * @return The current value.
1720          */
1721         public int getSplit()
1722         {
1723                 return split;
1724         }
1725
1726         /** Sets in how many parts the current cell (that this constraint's component will be in) should be split in. If for instance
1727          * it is split in two, the next component will also share the same cell. Note that the cell can also span a number of
1728          * cells, which means that you can for instance span three cells and split that big cell for two components. Split can be
1729          * set to a very high value to make all components in the same row/column share the same cell (e.g. <code>LayoutUtil.INF</code>).
1730          * <p>
1731          * Note that only the first component will be checked for this property.
1732          * <p>
1733          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1734          * @param parts The number of parts (i.e. component slots) the cell should be divided into.
1735          */
1736         public void setSplit(int parts)
1737         {
1738                 this.split = parts;
1739         }
1740
1741         /** Tags the component with metadata. Currently only used to tag buttons with for instance "cancel" or "ok" to make them
1742          * show up in the correct order depending on platform. See {@link PlatformDefaults#setButtonOrder(String)} for information.
1743          * <p>
1744          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1745          * @return The current value. May be <code>null</code>.
1746          */
1747         public String getTag()
1748         {
1749                 return tag;
1750         }
1751
1752         /** Optional tag that gives more context to this constraint's component. It is for instance used to tag buttons in a
1753          * button bar with the button type such as "ok", "help" or "cancel".
1754          * <p>
1755          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1756          * @param tag The new tag. May be <code>null</code>.
1757          */
1758         public void setTag(String tag)
1759         {
1760                 this.tag = tag;
1761         }
1762
1763         /** Returns if the flow should wrap to the next line/column <b>after</b> the component that this constraint belongs to.
1764          * <p>
1765          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1766          * @return The current value.
1767          */
1768         public boolean isWrap()
1769         {
1770                 return wrap != null;
1771         }
1772
1773         /** Sets if the flow should wrap to the next line/column <b>after</b> the component that this constraint belongs to.
1774          * <p>
1775          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1776          * @param b <code>true</code> means wrap after.
1777          */
1778         public void setWrap(boolean b)
1779         {
1780                 wrap = b ? (wrap == null ? DEF_GAP : wrap) : null;
1781         }
1782
1783         /** Returns the wrap size if it is a custom size. If wrap was set to true with {@link #setWrap(boolean)} then this method will
1784          * return <code>null</code> since that means that the gap size should be the default one as defined in the rows spec.
1785          * @return The custom gap size. NOTE! Will return <code>null</code> for both no wrap <b>and</b> default wrap.
1786          * @see #isWrap()
1787          * @see #setWrap(boolean)
1788          * @since 2.4.2
1789          */
1790         public BoundSize getWrapGapSize()
1791         {
1792                 return wrap == DEF_GAP ? null : wrap;
1793         }
1794
1795         /** Set the wrap size and turns wrap on if <code>!= null</code>.
1796          * @param s The custom gap size. NOTE! <code>null</code> will not turn on or off wrap, it will only set the wrap gap size to "default".
1797          * A non-null value will turn on wrap though.
1798          * @see #isWrap()
1799          * @see #setWrap(boolean)
1800          * @since 2.4.2
1801          */
1802         public void setWrapGapSize(BoundSize s)
1803         {
1804                 wrap = s == null ? (wrap != null ? DEF_GAP : null) : s;
1805         }
1806
1807         /** Returns if the flow should wrap to the next line/column <b>before</b> the component that this constraint belongs to.
1808          * <p>
1809          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1810          * @return The current value.
1811          */
1812         public boolean isNewline()
1813         {
1814                 return newline != null;
1815         }
1816
1817         /** Sets if the flow should wrap to the next line/column <b>before</b> the component that this constraint belongs to.
1818          * <p>
1819          * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
1820          * @param b <code>true</code> means wrap before.
1821          */
1822         public void setNewline(boolean b)
1823         {
1824                 newline = b ? (newline == null ? DEF_GAP : newline) : null;
1825         }
1826
1827         /** Returns the newline size if it is a custom size. If newline was set to true with {@link #setNewline(boolean)} then this method will
1828          * return <code>null</code> since that means that the gap size should be the default one as defined in the rows spec.
1829          * @return The custom gap size. NOTE! Will return <code>null</code> for both no newline <b>and</b> default newline.
1830          * @see #isNewline()
1831          * @see #setNewline(boolean)
1832          * @since 2.4.2
1833          */
1834         public BoundSize getNewlineGapSize()
1835         {
1836                 return newline == DEF_GAP ? null : newline;
1837         }
1838
1839         /** Set the newline size and turns newline on if <code>!= null</code>.
1840          * @param s The custom gap size. NOTE! <code>null</code> will not turn on or off newline, it will only set the newline gap size to "default".
1841          * A non-null value will turn on newline though.
1842          * @see #isNewline()
1843          * @see #setNewline(boolean)
1844          * @since 2.4.2
1845          */
1846         public void setNewlineGapSize(BoundSize s)
1847         {
1848                 newline = s == null ? (newline != null ? DEF_GAP : null) : s;
1849         }
1850
1851         /** Returns the animation spec. Default is a spec where animation is off (prio 0).
1852          * @return Never null.
1853          */
1854         public AnimSpec getAnimSpec()
1855         {
1856                 return animSpec;
1857         }
1858
1859
1860         // ************************************************
1861         // Persistence Delegate and Serializable combined.
1862         // ************************************************
1863
1864         private Object readResolve() throws ObjectStreamException
1865         {
1866                 return LayoutUtil.getSerializedObject(this);
1867         }
1868
1869         @Override
1870         public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
1871         {
1872                 LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
1873         }
1874
1875         @Override
1876         public void writeExternal(ObjectOutput out) throws IOException
1877         {
1878                 if (getClass() == CC.class)
1879                         LayoutUtil.writeAsXML(out, this);
1880         }
1881 }