1 package net.miginfocom.layout;
3 import java.beans.Encoder;
4 import java.beans.Expression;
5 import java.beans.PersistenceDelegate;
11 * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
12 * All rights reserved.
14 * Redistribution and use in source and binary forms, with or without modification,
15 * are permitted provided that the following conditions are met:
16 * Redistributions of source code must retain the above copyright notice, this list
17 * of conditions and the following disclaimer.
18 * Redistributions in binary form must reproduce the above copyright notice, this
19 * list of conditions and the following disclaimer in the documentation and/or other
20 * materials provided with the distribution.
21 * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
22 * used to endorse or promote products derived from this software without specific
23 * prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
31 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
37 * @author Mikael Grev, MiG InfoCom AB
41 /** A size that contains minimum, preferred and maximum size of type {@link UnitValue}.
43 * This class is a simple value container and it is immutable.
45 * If a size is missing (i.e., <code>null</code>) that boundary should be considered "not in use".
47 * You can create a BoundSize from a String with the use of {@link ConstraintParser#parseBoundSize(String, boolean, boolean)}
49 public class BoundSize implements Serializable
51 public static final BoundSize NULL_SIZE = new BoundSize(null, null);
52 public static final BoundSize ZERO_PIXEL = new BoundSize(UnitValue.ZERO, "0px");
54 private final transient UnitValue min;
55 private final transient UnitValue pref;
56 private final transient UnitValue max;
57 private final transient boolean gapPush;
59 /** Constructor that use the same value for min/preferred/max size.
60 * @param minMaxPref The value to use for min/preferred/max size.
61 * @param createString The string used to create the BoundsSize.
63 public BoundSize(UnitValue minMaxPref, String createString)
65 this(minMaxPref, minMaxPref, minMaxPref, createString);
68 /** Constructor. <b>This method is here for serialization only and should normally not be used.</b> Use
69 * {@link ConstraintParser#parseBoundSize(String, boolean, boolean)} instead.
70 * @param min The minimum size. May be <code>null</code>.
71 * @param preferred The preferred size. May be <code>null</code>.
72 * @param max The maximum size. May be <code>null</code>.
73 * @param createString The string used to create the BoundsSize.
75 public BoundSize(UnitValue min, UnitValue preferred, UnitValue max, String createString) // Bound to old delegate!!!!!
77 this(min, preferred, max, false, createString);
80 /** Constructor. <b>This method is here for serialization only and should normally not be used.</b> Use
81 * {@link ConstraintParser#parseBoundSize(String, boolean, boolean)} instead.
82 * @param min The minimum size. May be <code>null</code>.
83 * @param preferred The preferred size. May be <code>null</code>.
84 * @param max The maximum size. May be <code>null</code>.
85 * @param gapPush If the size should be hinted as "pushing" and thus want to occupy free space if no one else is claiming it.
86 * @param createString The string used to create the BoundsSize.
88 public BoundSize(UnitValue min, UnitValue preferred, UnitValue max, boolean gapPush, String createString)
91 this.pref = preferred;
93 this.gapPush = gapPush;
95 LayoutUtil.putCCString(this, createString); // this escapes!!
98 /** Returns the minimum size as sent into the constructor.
99 * @return The minimum size as sent into the constructor. May be <code>null</code>.
101 public final UnitValue getMin()
106 /** Returns the preferred size as sent into the constructor.
107 * @return The preferred size as sent into the constructor. May be <code>null</code>.
109 public final UnitValue getPreferred()
114 /** Returns the maximum size as sent into the constructor.
115 * @return The maximum size as sent into the constructor. May be <code>null</code>.
117 public final UnitValue getMax()
122 /** If the size should be hinted as "pushing" and thus want to occupy free space if no one else is claiming it.
125 public boolean getGapPush()
130 /** Returns if this bound size has no min, preferred and maximum size set (they are all <code>null</code>)
133 public boolean isUnset()
135 // Most common case by far is this == ZERO_PIXEL...
136 return this == ZERO_PIXEL || (pref == null && min == null && max == null && gapPush == false);
139 /** Makes sure that <code>size</code> is within min and max of this size.
140 * @param size The size to constrain.
141 * @param refValue The reference to use for relative sizes.
142 * @param parent The parent container.
143 * @return The size, constrained within min and max.
145 public int constrain(int size, float refValue, ContainerWrapper parent)
148 size = Math.min(size, max.getPixels(refValue, parent, parent));
150 size = Math.max(size, min.getPixels(refValue, parent, parent));
154 /** Returns the minimum, preferred or maximum size for this bounded size.
155 * @param sizeType The type. <code>LayoutUtil.MIN</code>, <code>LayoutUtil.PREF</code> or <code>LayoutUtil.MAX</code>.
158 final UnitValue getSize(int sizeType)
163 case LayoutUtil.PREF:
168 throw new IllegalArgumentException("Unknown size: " + sizeType);
172 /** Convert the bound sizes to pixels.
174 * <code>null</code> bound sizes will be 0 for min and preferred and {@link net.miginfocom.layout.LayoutUtil#INF} for max.
175 * @param refSize The reference size.
176 * @param parent The parent. Not <code>null</code>.
177 * @param comp The component, if applicable, can be <code>null</code>.
178 * @return An array of length three (min,pref,max).
180 final int[] getPixelSizes(float refSize, ContainerWrapper parent, ComponentWrapper comp)
183 min != null ? min.getPixels(refSize, parent, comp) : 0,
184 pref != null ? pref.getPixels(refSize, parent, comp) : 0,
185 max != null ? max.getPixels(refSize, parent, comp) : LayoutUtil.INF
189 /** Returns the a constraint string that can be re-parsed to be the exact same UnitValue.
190 * @return A String. Never <code>null</code>.
192 String getConstraintString()
194 String cs = LayoutUtil.getCCString(this);
198 if (min == pref && pref == max)
199 return min != null ? (min.getConstraintString() + "!") : "null";
201 StringBuilder sb = new StringBuilder(16);
204 sb.append(min.getConstraintString()).append(':');
207 if (min == null && max != null)
209 sb.append(pref.getConstraintString());
210 } else if (min != null) {
215 sb.append(sb.length() == 0 ? "::" : ":").append(max.getConstraintString());
223 return sb.toString();
226 void checkNotLinked()
229 throw new IllegalArgumentException("Size may not contain links");
234 return min != null && min.isLinkedDeep() || pref != null && pref.isLinkedDeep() || max != null && max.isLinkedDeep();
239 return (min == null || min.isAbsoluteDeep()) && (pref == null || pref.isAbsoluteDeep()) && (max == null || max.isAbsoluteDeep());
242 public String toString()
244 return "BoundSize{" + "min=" + min + ", pref=" + pref + ", max=" + max + ", gapPush=" + gapPush +'}';
248 // if(LayoutUtil.HAS_BEANS){
249 // LayoutUtil.setDelegate(BoundSize.class, new PersistenceDelegate() {
251 // protected Expression instantiate(Object oldInstance, Encoder out)
253 // BoundSize bs = (BoundSize) oldInstance;
254 // if (Grid.TEST_GAPS) {
255 // return new Expression(oldInstance, BoundSize.class, "new", new Object[] {
256 // bs.getMin(), bs.getPreferred(), bs.getMax(), bs.getGapPush(), bs.getConstraintString()
259 // return new Expression(oldInstance, BoundSize.class, "new", new Object[] {
260 // bs.getMin(), bs.getPreferred(), bs.getMax(), bs.getConstraintString()
268 // ************************************************
269 // Persistence Delegate and Serializable combined.
270 // ************************************************
272 private static final long serialVersionUID = 1L;
274 protected Object readResolve() throws ObjectStreamException
276 return LayoutUtil.getSerializedObject(this);
279 private void writeObject(ObjectOutputStream out) throws IOException
281 if (getClass() == BoundSize.class)
282 LayoutUtil.writeAsXML(out, this);
285 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
287 LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));