1 package net.miginfocom.layout;
3 import java.beans.Encoder;
4 import java.beans.Expression;
5 import java.beans.PersistenceDelegate;
10 * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
11 * All rights reserved.
13 * Redistribution and use in source and binary forms, with or without modification,
14 * are permitted provided that the following conditions are met:
15 * Redistributions of source code must retain the above copyright notice, this list
16 * of conditions and the following disclaimer.
17 * Redistributions in binary form must reproduce the above copyright notice, this
18 * list of conditions and the following disclaimer in the documentation and/or other
19 * materials provided with the distribution.
20 * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
21 * used to endorse or promote products derived from this software without specific
22 * prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
30 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
36 * @author Mikael Grev, MiG InfoCom AB
39 import java.io.IOException;
40 import java.io.ObjectInputStream;
41 import java.io.ObjectOutputStream;
42 import java.io.ObjectStreamException;
43 import java.io.Serializable;
45 /** A size that contains minimum, preferred and maximum size of type {@link UnitValue}.
47 * This class is a simple value container and it is immutable.
49 * If a size is missing (i.e., <code>null</code>) that boundary should be considered "not in use".
51 * You can create a BoundSize from a String with the use of {@link ConstraintParser#parseBoundSize(String, boolean, boolean)}
53 public class BoundSize implements Serializable
55 public static final BoundSize NULL_SIZE = new BoundSize(null, null);
56 public static final BoundSize ZERO_PIXEL = new BoundSize(UnitValue.ZERO, "0px");
58 private final transient UnitValue min;
59 private final transient UnitValue pref;
60 private final transient UnitValue max;
61 private final transient boolean gapPush;
63 /** Constructor that use the same value for min/preferred/max size.
64 * @param minMaxPref The value to use for min/preferred/max size.
65 * @param createString The string used to create the BoundsSize.
67 public BoundSize(UnitValue minMaxPref, String createString)
69 this(minMaxPref, minMaxPref, minMaxPref, createString);
72 /** Constructor. <b>This method is here for serialization only and should normally not be used.</b> Use
73 * {@link ConstraintParser#parseBoundSize(String, boolean, boolean)} instead.
74 * @param min The minimum size. May be <code>null</code>.
75 * @param preferred The preferred size. May be <code>null</code>.
76 * @param max The maximum size. May be <code>null</code>.
77 * @param createString The string used to create the BoundsSize.
79 public BoundSize(UnitValue min, UnitValue preferred, UnitValue max, String createString) // Bound to old delegate!!!!!
81 this(min, preferred, max, false, createString);
84 /** Constructor. <b>This method is here for serialization only and should normally not be used.</b> Use
85 * {@link ConstraintParser#parseBoundSize(String, boolean, boolean)} instead.
86 * @param min The minimum size. May be <code>null</code>.
87 * @param preferred The preferred size. May be <code>null</code>.
88 * @param max The maximum size. May be <code>null</code>.
89 * @param gapPush If the size should be hinted as "pushing" and thus want to occupy free space if no one else is claiming it.
90 * @param createString The string used to create the BoundsSize.
92 public BoundSize(UnitValue min, UnitValue preferred, UnitValue max, boolean gapPush, String createString)
95 this.pref = preferred;
97 this.gapPush = gapPush;
99 LayoutUtil.putCCString(this, createString); // this escapes!!
102 /** Returns the minimum size as sent into the constructor.
103 * @return The minimum size as sent into the constructor. May be <code>null</code>.
105 public final UnitValue getMin()
110 /** Returns the preferred size as sent into the constructor.
111 * @return The preferred size as sent into the constructor. May be <code>null</code>.
113 public final UnitValue getPreferred()
118 /** Returns the maximum size as sent into the constructor.
119 * @return The maximum size as sent into the constructor. May be <code>null</code>.
121 public final UnitValue getMax()
126 /** If the size should be hinted as "pushing" and thus want to occupy free space if no one else is claiming it.
129 public boolean getGapPush()
134 /** Returns if this bound size has no min, preferred and maximum size set (they are all <code>null</code>)
137 public boolean isUnset()
139 // Most common case by far is this == ZERO_PIXEL...
140 return this == ZERO_PIXEL || (pref == null && min == null && max == null && gapPush == false);
143 /** Makes sure that <code>size</code> is within min and max of this size.
144 * @param size The size to constrain.
145 * @param refValue The reference to use for relative sizes.
146 * @param parent The parent container.
147 * @return The size, constrained within min and max.
149 public int constrain(int size, float refValue, ContainerWrapper parent)
152 size = Math.min(size, max.getPixels(refValue, parent, parent));
154 size = Math.max(size, min.getPixels(refValue, parent, parent));
158 /** Returns the minimum, preferred or maximum size for this bounded size.
159 * @param sizeType The type. <code>LayoutUtil.MIN</code>, <code>LayoutUtil.PREF</code> or <code>LayoutUtil.MAX</code>.
162 final UnitValue getSize(int sizeType)
167 case LayoutUtil.PREF:
172 throw new IllegalArgumentException("Unknown size: " + sizeType);
176 /** Convert the bound sizes to pixels.
178 * <code>null</code> bound sizes will be 0 for min and preferred and {@link net.miginfocom.layout.LayoutUtil#INF} for max.
179 * @param refSize The reference size.
180 * @param parent The parent. Not <code>null</code>.
181 * @param comp The component, if applicable, can be <code>null</code>.
182 * @return An array of length three (min,pref,max).
184 final int[] getPixelSizes(float refSize, ContainerWrapper parent, ComponentWrapper comp)
187 min != null ? min.getPixels(refSize, parent, comp) : 0,
188 pref != null ? pref.getPixels(refSize, parent, comp) : 0,
189 max != null ? max.getPixels(refSize, parent, comp) : LayoutUtil.INF
193 /** Returns the a constraint string that can be re-parsed to be the exact same UnitValue.
194 * @return A String. Never <code>null</code>.
196 String getConstraintString()
198 String cs = LayoutUtil.getCCString(this);
202 if (min == pref && pref == max)
203 return min != null ? (min.getConstraintString() + "!") : "null";
205 StringBuilder sb = new StringBuilder(16);
208 sb.append(min.getConstraintString()).append(':');
211 if (min == null && max != null)
213 sb.append(pref.getConstraintString());
214 } else if (min != null) {
219 sb.append(sb.length() == 0 ? "::" : ":").append(max.getConstraintString());
227 return sb.toString();
230 void checkNotLinked()
233 throw new IllegalArgumentException("Size may not contain links");
238 return min != null && min.isLinkedDeep() || pref != null && pref.isLinkedDeep() || max != null && max.isLinkedDeep();
243 return (min == null || min.isAbsoluteDeep()) && (pref == null || pref.isAbsoluteDeep()) && (max == null || max.isAbsoluteDeep());
246 public String toString()
248 return "BoundSize{" + "min=" + min + ", pref=" + pref + ", max=" + max + ", gapPush=" + gapPush +'}';
252 // if(LayoutUtil.HAS_BEANS){
253 // LayoutUtil.setDelegate(BoundSize.class, new PersistenceDelegate() {
255 // protected Expression instantiate(Object oldInstance, Encoder out)
257 // BoundSize bs = (BoundSize) oldInstance;
258 // if (Grid.TEST_GAPS) {
259 // return new Expression(oldInstance, BoundSize.class, "new", new Object[] {
260 // bs.getMin(), bs.getPreferred(), bs.getMax(), bs.getGapPush(), bs.getConstraintString()
263 // return new Expression(oldInstance, BoundSize.class, "new", new Object[] {
264 // bs.getMin(), bs.getPreferred(), bs.getMax(), bs.getConstraintString()
272 // ************************************************
273 // Persistence Delegate and Serializable combined.
274 // ************************************************
276 private static final long serialVersionUID = 1L;
278 protected Object readResolve() throws ObjectStreamException
280 return LayoutUtil.getSerializedObject(this);
283 private void writeObject(ObjectOutputStream out) throws IOException
285 // if (getClass() == BoundSize.class)
286 // LayoutUtil.writeAsXML(out, this);
289 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
291 // LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));