1 package net.miginfocom.layout;
3 import java.io.Externalizable;
4 import java.io.IOException;
5 import java.io.ObjectInput;
6 import java.io.ObjectOutput;
7 import java.io.ObjectStreamException;
12 * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
13 * All rights reserved.
15 * Redistribution and use in source and binary forms, with or without modification,
16 * are permitted provided that the following conditions are met:
17 * Redistributions of source code must retain the above copyright notice, this list
18 * of conditions and the following disclaimer.
19 * Redistributions in binary form must reproduce the above copyright notice, this
20 * list of conditions and the following disclaimer in the documentation and/or other
21 * materials provided with the distribution.
22 * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
23 * used to endorse or promote products derived from this software without specific
24 * prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
32 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
38 * @author Mikael Grev, MiG InfoCom AB
42 /** A simple value holder for a constraint for one dimension.
44 public final class DimConstraint implements Externalizable
46 /** How this entity can be resized in the dimension that this constraint represents.
48 final ResizeConstraint resize = new ResizeConstraint();
50 // Look at the properties' getter/setter methods for explanation
52 private String sizeGroup = null; // A "context" compared with equals.
54 private BoundSize size = BoundSize.NULL_SIZE; // Min, pref, max. Never null, but sizes can be null.
56 private BoundSize gapBefore = null, gapAfter = null;
58 private UnitValue align = null;
61 // ************** Only applicable on components! *******************
63 private String endGroup = null; // A "context" compared with equals.
66 // ************** Only applicable on rows/columns! *******************
68 private boolean fill = false;
70 private boolean noGrid = false;
72 /** Empty constructor.
74 public DimConstraint()
78 /** Returns the grow priority. Relative priority is used for determining which entities gets the extra space first.
80 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
81 * @return The grow priority.
83 public int getGrowPriority()
85 return resize.growPrio;
88 /** Sets the grow priority. Relative priority is used for determining which entities gets the extra space first.
90 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
91 * @param p The new grow priority.
93 public void setGrowPriority(int p)
98 /** Returns the grow weight.<p>
99 * Grow weight is how flexible the entity should be, relative to other entities, when it comes to growing. <code>null</code> or
100 * zero mean it will never grow. An entity that has twice the grow weight compared to another entity will get twice
101 * as much of available space.
103 * GrowWeight are only compared within the same GrowPrio.
105 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
106 * @return The current grow weight.
108 public Float getGrow()
113 /** Sets the grow weight.<p>
114 * Grow weight is how flexible the entity should be, relative to other entities, when it comes to growing. <code>null</code> or
115 * zero mean it will never grow. An entity that has twice the grow weight compared to another entity will get twice
116 * as much of available space.
118 * GrowWeight are only compared within the same GrowPrio.
120 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
121 * @param weight The new grow weight.
123 public void setGrow(Float weight)
125 resize.grow = weight;
128 /** Returns the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarce.
130 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
131 * @return The shrink priority.
133 public int getShrinkPriority()
135 return resize.shrinkPrio;
138 /** Sets the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarce.
140 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
141 * @param p The new shrink priority.
143 public void setShrinkPriority(int p)
145 resize.shrinkPrio = p;
148 /** Returns the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarce.
149 * Shrink weight is how flexible the entity should be, relative to other entities, when it comes to shrinking. <code>null</code> or
150 * zero mean it will never shrink (default). An entity that has twice the shrink weight compared to another entity will get twice
151 * as much of available space.
153 * Shrink(Weight) are only compared within the same ShrinkPrio.
155 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
156 * @return The current shrink weight.
158 public Float getShrink()
160 return resize.shrink;
163 /** Sets the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarce.
164 * Shrink weight is how flexible the entity should be, relative to other entities, when it comes to shrinking. <code>null</code> or
165 * zero mean it will never shrink (default). An entity that has twice the shrink weight compared to another entity will get twice
166 * as much of available space.
168 * Shrink(Weight) are only compared within the same ShrinkPrio.
170 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
171 * @param weight The new shrink weight.
173 public void setShrink(Float weight)
175 resize.shrink = weight;
178 public UnitValue getAlignOrDefault(boolean isCols)
184 return UnitValue.LEADING;
186 return fill || PlatformDefaults.getDefaultRowAlignmentBaseline() == false ? UnitValue.CENTER : UnitValue.BASELINE_IDENTITY;
189 /** Returns the alignment used either as a default value for sub-entities or for this entity.
191 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
192 * @return The alignment.
194 public UnitValue getAlign()
199 /** Sets the alignment used wither as a default value for sub-entities or for this entity.
201 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
202 * @param uv The new shrink priority. E.g. {@link UnitValue#CENTER} or {@link net.miginfocom.layout.UnitValue#LEADING}.
204 public void setAlign(UnitValue uv)
209 /** Returns the gap after this entity. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and
210 * grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
212 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
213 * @return The gap after this entity
215 public BoundSize getGapAfter()
220 /** Sets the gap after this entity. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and
221 * grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
223 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
224 * @param size The new gap.
225 * @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean)
227 public void setGapAfter(BoundSize size)
229 this.gapAfter = size;
232 boolean hasGapAfter()
234 return gapAfter != null && gapAfter.isUnset() == false;
237 boolean isGapAfterPush()
239 return gapAfter != null && gapAfter.getGapPush();
242 /** Returns the gap before this entity. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and
243 * grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
245 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
246 * @return The gap before this entity
248 public BoundSize getGapBefore()
253 /** Sets the gap before this entity. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and
254 * grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
256 * See also {@link net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean)}.
257 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
258 * @param size The new gap.
260 public void setGapBefore(BoundSize size)
262 this.gapBefore = size;
265 boolean hasGapBefore()
267 return gapBefore != null && gapBefore.isUnset() == false;
270 boolean isGapBeforePush()
272 return gapBefore != null && gapBefore.getGapPush();
275 /** Returns the min/preferred/max size for the entity in the dimension that this object describes.
277 * See also {@link net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean)}.
278 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
279 * @return The current size. Never <code>null</code> since v3.5.
281 public BoundSize getSize()
286 /** Sets the min/preferred/max size for the entity in the dimension that this object describes.
288 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
289 * @param size The new size. May be <code>null</code>.
291 public void setSize(BoundSize size)
294 size.checkNotLinked();
298 /** Returns the size group that this entity should be in for the dimension that this object is describing.
299 * If this constraint is in a size group that is specified here. <code>null</code> means no size group
300 * and all other values are legal. Comparison with .equals(). Components/columns/rows in the same size group
301 * will have the same min/preferred/max size; that of the largest in the group for the first two and the
304 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
305 * @return The current size group. May be <code>null</code>.
307 public String getSizeGroup()
312 /** Sets the size group that this entity should be in for the dimension that this object is describing.
313 * If this constraint is in a size group that is specified here. <code>null</code> means no size group
314 * and all other values are legal. Comparison with .equals(). Components/columns/rows in the same size group
315 * will have the same min/preferred/max size; that of the largest in the group for the first two and the
318 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
319 * @param s The new size group. <code>null</code> disables size grouping.
321 public void setSizeGroup(String s)
326 // ************** Only applicable on components ! *******************
328 /** Returns the end group that this entity should be in for the dimension that this object is describing.
329 * If this constraint is in an end group that is specified here. <code>null</code> means no end group
330 * and all other values are legal. Comparison with .equals(). Components in the same end group
331 * will have the same end coordinate.
333 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
334 * @return The current end group. <code>null</code> may be returned.
336 public String getEndGroup()
341 /** Sets the end group that this entity should be in for the dimension that this object is describing.
342 * If this constraint is in an end group that is specified here. <code>null</code> means no end group
343 * and all other values are legal. Comparison with .equals(). Components in the same end group
344 * will have the same end coordinate.
346 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
347 * @param s The new end group. <code>null</code> disables end grouping.
349 public void setEndGroup(String s)
354 // ************** Not applicable on components below ! *******************
356 /** Returns if the component in the row/column that this constraint should default be grown in the same dimension that
357 * this constraint represents (width for column and height for a row).
359 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
360 * @return <code>true</code> means that components should grow.
362 public boolean isFill()
367 /** Sets if the component in the row/column that this constraint should default be grown in the same dimension that
368 * this constraint represents (width for column and height for a row).
370 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
371 * @param b <code>true</code> means that components should grow.
373 public void setFill(boolean b)
378 /** Returns if the row/column should default to flow and not to grid behaviour. This means that the whole row/column
379 * will be one cell and all components will end up in that cell.
381 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
382 * @return <code>true</code> means that the whole row/column should be one cell.
384 public boolean isNoGrid()
389 /** Sets if the row/column should default to flow and not to grid behaviour. This means that the whole row/column
390 * will be one cell and all components will end up in that cell.
392 * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
393 * @param b <code>true</code> means that the whole row/column should be one cell.
395 public void setNoGrid(boolean b)
400 /** Returns the gaps as pixel values.
401 * @param parent The parent. Used to get the pixel values.
402 * @param defGap The default gap to use if there is no gap set on this object (i.e. it is null).
403 * @param refSize The reference size used to get the pixel sizes.
404 * @param before IF it is the gap before rather than the gap after to return.
405 * @return The [min,preferred,max] sizes for the specified gap. Uses {@link net.miginfocom.layout.LayoutUtil#NOT_SET}
406 * for gap sizes that are <code>null</code>. Returns <code>null</code> if there was no gap specified. A new and free to use array.
408 int[] getRowGaps(ContainerWrapper parent, BoundSize defGap, int refSize, boolean before)
410 BoundSize gap = before ? gapBefore : gapAfter;
411 if (gap == null || gap.isUnset())
414 if (gap == null || gap.isUnset())
417 int[] ret = new int[3];
418 for (int i = LayoutUtil.MIN; i <= LayoutUtil.MAX; i++) {
419 UnitValue uv = gap.getSize(i);
420 ret[i] = uv != null ? uv.getPixels(refSize, parent, null) : LayoutUtil.NOT_SET;
425 /** Returns the gaps as pixel values.
426 * @param parent The parent. Used to get the pixel values.
427 * @param comp The component that the gap is for. If not for a component it is <code>null</code>.
428 * @param adjGap The gap that the adjacent component, if any, has towards <code>comp</code>.
429 * @param adjacentComp The adjacent component if any. May be <code>null</code>.
430 * @param refSize The reference size used to get the pixel sizes.
431 * @param adjacentSide What side the <code>adjacentComp</code> is on. 0 = top, 1 = left, 2 = bottom, 3 = right.
432 * @param tag The tag string that the component might be tagged with in the component constraints. May be <code>null</code>.
433 * @param isLTR If it is left-to-right.
434 * @return The [min,preferred,max] sizes for the specified gap. Uses {@link net.miginfocom.layout.LayoutUtil#NOT_SET}
435 * for gap sizes that are <code>null</code>. Returns <code>null</code> if there was no gap specified. A new and free to use array.
437 int[] getComponentGaps(ContainerWrapper parent, ComponentWrapper comp, BoundSize adjGap, ComponentWrapper adjacentComp, String tag, int refSize, int adjacentSide, boolean isLTR)
439 BoundSize gap = adjacentSide < 2 ? gapBefore : gapAfter;
441 boolean hasGap = gap != null && gap.getGapPush();
442 if ((gap == null || gap.isUnset()) && (adjGap == null || adjGap.isUnset()) && comp != null)
443 gap = PlatformDefaults.getDefaultComponentGap(comp, adjacentComp, adjacentSide + 1, tag, isLTR);
446 return hasGap ? new int[] {0, 0, LayoutUtil.NOT_SET} : null;
448 int[] ret = new int[3];
449 for (int i = LayoutUtil.MIN; i <= LayoutUtil.MAX; i++) {
450 UnitValue uv = gap.getSize(i);
451 ret[i] = uv != null ? uv.getPixels(refSize, parent, null) : LayoutUtil.NOT_SET;
456 // ************************************************
457 // Persistence Delegate and Serializable combined.
458 // ************************************************
460 private Object readResolve() throws ObjectStreamException
462 return LayoutUtil.getSerializedObject(this);
466 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
468 LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
472 public void writeExternal(ObjectOutput out) throws IOException
474 if (getClass() == DimConstraint.class)
475 LayoutUtil.writeAsXML(out, this);