/*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com),
* modifications by Nikolaus Moll
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
* Neither the name of the MiG InfoCom AB nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
*/
package org.jowidgets.impl.layout.miglayout;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.ObjectStreamException;
/**
* A simple value holder for a constraint for one dimension.
*/
final class DimConstraintCommon implements Externalizable {
/**
* How this entity can be resized in the dimension that this constraint represents.
*/
//CHECKSTYLE:OFF
final ResizeConstraintCommon resize = new ResizeConstraintCommon();
//CHECKSTYLE:ON
// Look at the properties' getter/setter methods for explanation
private String sizeGroup = null; // A "context" compared with equals.
private BoundSizeCommon size = BoundSizeCommon.NULL_SIZE; // Min, pref, max. Never null, but sizes can be null.
private BoundSizeCommon gapBefore = null;
private BoundSizeCommon gapAfter = null;
private UnitValueCommon align = null;
// ************** Only applicable on components! *******************
private String endGroup = null; // A "context" compared with equals.
// ************** Only applicable on rows/columns! *******************
private boolean fill = false;
private boolean noGrid = false;
/**
* Empty constructor.
*/
DimConstraintCommon() {}
/**
* Returns the grow priority. Relative priority is used for determining which entities gets the extra space first.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @return The grow priority.
*/
public int getGrowPriority() {
return resize.growPrio;
}
/**
* Sets the grow priority. Relative priority is used for determining which entities gets the extra space first.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @param p The new grow priority.
*/
public void setGrowPriority(final int p) {
resize.growPrio = p;
}
/**
* Returns the grow weight.
* <p>
* Grow weight is how flexible the entity should be, relative to other entities, when it comes to growing. <code>null</code>
* or zero mean it will never grow. An entity that has twice the grow weight compared to another entity will get twice as much
* of available space.
* <p>
* GrowWeight are only compared within the same GrowPrio.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @return The current grow weight.
*/
public Float getGrow() {
return resize.grow;
}
/**
* Sets the grow weight.
* <p>
* Grow weight is how flexible the entity should be, relative to other entities, when it comes to growing. <code>null</code>
* or zero mean it will never grow. An entity that has twice the grow weight compared to another entity will get twice as much
* of available space.
* <p>
* GrowWeight are only compared within the same GrowPrio.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @param weight The new grow weight.
*/
public void setGrow(final Float weight) {
resize.grow = weight;
}
/**
* Returns the shrink priority. Relative priority is used for determining which entities gets smaller first when space is
* scarce.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @return The shrink priority.
*/
public int getShrinkPriority() {
return resize.shrinkPrio;
}
/**
* Sets the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarce.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @param p The new shrink priority.
*/
public void setShrinkPriority(final int p) {
resize.shrinkPrio = p;
}
/**
* Returns the shrink priority. Relative priority is used for determining which entities gets smaller first when space is
* scarce.
* Shrink weight is how flexible the entity should be, relative to other entities, when it comes to shrinking.
* <code>null</code> or
* zero mean it will never shrink (default). An entity that has twice the shrink weight compared to another entity will get
* twice
* as much of available space.
* <p>
* Shrink(Weight) are only compared within the same ShrinkPrio.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @return The current shrink weight.
*/
public Float getShrink() {
return resize.shrink;
}
/**
* Sets the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarce.
* Shrink weight is how flexible the entity should be, relative to other entities, when it comes to shrinking.
* <code>null</code> or
* zero mean it will never shrink (default). An entity that has twice the shrink weight compared to another entity will get
* twice
* as much of available space.
* <p>
* Shrink(Weight) are only compared within the same ShrinkPrio.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @param weight The new shrink weight.
*/
public void setShrink(final Float weight) {
resize.shrink = weight;
}
public UnitValueCommon getAlignOrDefault(final boolean isCols) {
if (align != null) {
return align;
}
if (isCols) {
return MigLayoutToolkitImpl.getMigUnitValueToolkit().LEADING;
}
return fill || MigLayoutToolkitImpl.getMigPlatformDefaults().getDefaultRowAlignmentBaseline() == false
? MigLayoutToolkitImpl.getMigUnitValueToolkit().CENTER
: MigLayoutToolkitImpl.getMigUnitValueToolkit().BASELINE_IDENTITY;
}
/**
* Returns the alignment used either as a default value for sub-entities or for this entity.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @return The alignment.
*/
public UnitValueCommon getAlign() {
return align;
}
/**
* Sets the alignment used wither as a default value for sub-entities or for this entity.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @param uv The new shrink priority. E.g. {@link UnitValueCommon#CENTER} or
* {@link net.miginfocom.layout.UnitValueCommon#LEADING}.
*/
public void setAlign(final UnitValueCommon uv) {
this.align = uv;
}
/**
* 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
* grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @return The gap after this entity
*/
public BoundSizeCommon getGapAfter() {
return gapAfter;
}
/**
* 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
* grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @param size The new gap.
* @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean).
*/
public void setGapAfter(final BoundSizeCommon size) {
this.gapAfter = size;
}
boolean hasGapAfter() {
return gapAfter != null && gapAfter.isUnset() == false;
}
boolean isGapAfterPush() {
return gapAfter != null && gapAfter.getGapPush();
}
/**
* 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
* grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @return The gap before this entity
*/
public BoundSizeCommon getGapBefore() {
return gapBefore;
}
/**
* 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
* grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @param size The new gap.
* @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean).
*/
public void setGapBefore(final BoundSizeCommon size) {
this.gapBefore = size;
}
boolean hasGapBefore() {
return gapBefore != null && gapBefore.isUnset() == false;
}
boolean isGapBeforePush() {
return gapBefore != null && gapBefore.getGapPush();
}
/**
* Returns the min/preferred/max size for the entity in the dimension that this object describes.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @return The current size. Never <code>null</code> since v3.5.
* @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean).
*/
public BoundSizeCommon getSize() {
return size;
}
/**
* Sets the min/preferred/max size for the entity in the dimension that this object describes.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @param size The new size. May be <code>null</code>.
*/
public void setSize(final BoundSizeCommon size) {
if (size != null) {
size.checkNotLinked();
}
this.size = size;
}
/**
* Returns the size group that this entity should be in for the dimension that this object is describing.
* If this constraint is in a size group that is specified here. <code>null</code> means no size group
* and all other values are legal. Comparison with .equals(). Components/columnss/rows in the same size group
* will have the same min/preferred/max size; that of the largest in the group for the first two and the
* smallest for max.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @return The current size group. May be <code>null</code>.
*/
public String getSizeGroup() {
return sizeGroup;
}
/**
* Sets the size group that this entity should be in for the dimension that this object is describing.
* If this constraint is in a size group that is specified here. <code>null</code> means no size group
* and all other values are legal. Comparison with .equals(). Components/columnss/rows in the same size group
* will have the same min/preferred/max size; that of the largest in the group for the first two and the
* smallest for max.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @param s The new size group. <code>null</code> disables size grouping.
*/
public void setSizeGroup(final String s) {
sizeGroup = s;
}
// ************** Only applicable on components ! *******************
/**
* Returns the end group that this entity should be in for the demension that this object is describing.
* If this constraint is in an end group that is specified here. <code>null</code> means no end group
* and all other values are legal. Comparison with .equals(). Components in the same end group
* will have the same end coordinate.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @return The current end group. <code>null</code> may be returned.
*/
public String getEndGroup() {
return endGroup;
}
/**
* Sets the end group that this entity should be in for the demension that this object is describing.
* If this constraint is in an end group that is specified here. <code>null</code> means no end group
* and all other values are legal. Comparison with .equals(). Components in the same end group
* will have the same end coordinate.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @param s The new end group. <code>null</code> disables end grouping.
*/
public void setEndGroup(final String s) {
endGroup = s;
}
// ************** Not applicable on components below ! *******************
/**
* Returns if the component in the row/column that this constraint should default be grown in the same dimension that
* this constraint represents (width for column and height for a row).
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @return code>true</code> means that components should grow.
*/
public boolean isFill() {
return fill;
}
/**
* Sets if the component in the row/column that this constraint should default be grown in the same dimension that
* this constraint represents (width for column and height for a row).
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @param b <code>true</code> means that components should grow.
*/
public void setFill(final boolean b) {
fill = b;
}
/**
* Returns if the row/column should default to flow and not to grid behaviour. This means that the whole row/column
* will be one cell and all components will end up in that cell.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @return <code>true</code> means that the whole row/column should be one cell.
*/
public boolean isNoGrid() {
return noGrid;
}
/**
* Sets if the row/column should default to flow and not to grid behaviour. This means that the whole row/column
* will be one cell and all components will end up in that cell.
* <p>
* For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
*
* @param b <code>true</code> means that the whole row/column should be one cell.
*/
public void setNoGrid(final boolean b) {
this.noGrid = b;
}
/**
* Returns the gaps as pixel values.
*
* @param parent The parent. Used to get the pixel values.
* @param defGap The default gap to use if there is no gap set on this object (i.e. it is null).
* @param refSize The reference size used to get the pixel sizes.
* @param before IF it is the gap before rather than the gap after to return.
* @return The [min,preferred,max] sizes for the specified gap. Uses {@link net.miginfocom.layout.LayoutUtilCommon#NOT_SET}
* 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.
*/
int[] getRowGaps(final IContainerWrapperCommon parent, final BoundSizeCommon defGap, final int refSize, final boolean before) {
BoundSizeCommon gap = before ? gapBefore : gapAfter;
if (gap == null || gap.isUnset()) {
gap = defGap;
}
if (gap == null || gap.isUnset()) {
return null;
}
final int[] ret = new int[3];
for (int i = LayoutUtilCommon.MIN; i <= LayoutUtilCommon.MAX; i++) {
final UnitValueCommon uv = gap.getSize(i);
ret[i] = uv != null ? uv.getPixels(refSize, parent, null) : LayoutUtilCommon.NOT_SET;
}
return ret;
}
/**
* Returns the gaps as pixel values.
*
* @param parent The parent. Used to get the pixel values.
* @param comp The component that the gap is for. If not for a component it is <code>null</code>.
* @param adjGap The gap that the adjacent component, if any, has towards <code>comp</code>.
* @param adjacentComp The adjacent component if any. May be <code>null</code>.
* @param refSize The reference size used to get the pixel sizes.
* @param adjacentSide What side the <code>adjacentComp</code> is on. 0 = top, 1 = left, 2 = bottom, 3 = right.
* @param tag The tag string that the component might be tagged with in the component constraints. May be <code>null</code>.
* @param isLTR If it is left-to-right.
* @return The [min,preferred,max] sizes for the specified gap. Uses {@link net.miginfocom.layout.LayoutUtilCommon#NOT_SET}
* 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.
*/
int[] getComponentGaps(
final IContainerWrapperCommon parent,
final IComponentWrapperCommon comp,
final BoundSizeCommon adjGap,
final IComponentWrapperCommon adjacentComp,
final String tag,
final int refSize,
final int adjacentSide,
final boolean isLTR) {
BoundSizeCommon gap = adjacentSide < 2 ? gapBefore : gapAfter;
final boolean hasGap = gap != null && gap.getGapPush();
if ((gap == null || gap.isUnset()) && (adjGap == null || adjGap.isUnset()) && comp != null) {
gap = MigLayoutToolkitImpl.getMigPlatformDefaults().getDefaultComponentGap(
comp,
adjacentComp,
adjacentSide + 1,
tag,
isLTR);
}
if (gap == null) {
return hasGap ? new int[] {0, 0, LayoutUtilCommon.NOT_SET} : null;
}
final int[] ret = new int[3];
for (int i = LayoutUtilCommon.MIN; i <= LayoutUtilCommon.MAX; i++) {
final UnitValueCommon uv = gap.getSize(i);
ret[i] = uv != null ? uv.getPixels(refSize, parent, null) : LayoutUtilCommon.NOT_SET;
}
return ret;
}
// ************************************************
// Persistence Delegate and Serializable combined.
// ************************************************
private Object readResolve() throws ObjectStreamException {
return MigLayoutToolkitImpl.getMigLayoutUtil().getSerializedObject(this);
}
@Override
public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
final LayoutUtilCommon layoutUtil = MigLayoutToolkitImpl.getMigLayoutUtil();
layoutUtil.setSerializedObject(this, layoutUtil.readAsXML(in));
}
@Override
public void writeExternal(final ObjectOutput out) throws IOException {
if (getClass() == DimConstraintCommon.class) {
MigLayoutToolkitImpl.getMigLayoutUtil().writeAsXML(out, this);
}
}
}