JAL-3032 adds Java 8 functionality (2/2)
[jalview.git] / src2 / net / miginfocom / layout / BoundSize.java
1 package net.miginfocom.layout;
2
3 import java.beans.Encoder;
4 import java.beans.Expression;
5 import java.beans.PersistenceDelegate;
6 /*
7  * License (BSD):
8  * ==============
9  *
10  * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
11  * All rights reserved.
12  *
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.
23  *
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
33  * OF SUCH DAMAGE.
34  *
35  * @version 1.0
36  * @author Mikael Grev, MiG InfoCom AB
37  *         Date: 2006-sep-08
38  */
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;
44
45 /** A size that contains minimum, preferred and maximum size of type {@link UnitValue}.
46  * <p>
47  * This class is a simple value container and it is immutable.
48  * <p>
49  * If a size is missing (i.e., <code>null</code>) that boundary should be considered "not in use".
50  * <p>
51  * You can create a BoundSize from a String with the use of {@link ConstraintParser#parseBoundSize(String, boolean, boolean)}
52  */
53 public class BoundSize implements Serializable
54 {
55         public static final BoundSize NULL_SIZE = new BoundSize(null, null);
56         public static final BoundSize ZERO_PIXEL = new BoundSize(UnitValue.ZERO, "0px");
57
58         private final transient UnitValue min;
59         private final transient UnitValue pref;
60         private final transient UnitValue max;
61         private final transient boolean gapPush;
62
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.
66          */
67         public BoundSize(UnitValue minMaxPref, String createString)
68         {
69                 this(minMaxPref, minMaxPref, minMaxPref, createString);
70         }
71
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.
78          */
79         public BoundSize(UnitValue min, UnitValue preferred, UnitValue max, String createString)    // Bound to old delegate!!!!!
80         {
81                 this(min, preferred, max, false, createString);
82         }
83
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.
91          */
92         public BoundSize(UnitValue min, UnitValue preferred, UnitValue max, boolean gapPush, String createString)
93         {
94                 this.min = min;
95                 this.pref = preferred;
96                 this.max = max;
97                 this.gapPush = gapPush;
98
99                 LayoutUtil.putCCString(this, createString);    // this escapes!!
100         }
101
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>.
104          */
105         public final UnitValue getMin()
106         {
107                 return min;
108         }
109
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>.
112          */
113         public final UnitValue getPreferred()
114         {
115                 return pref;
116         }
117
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>.
120          */
121         public final UnitValue getMax()
122         {
123                 return max;
124         }
125
126         /** If the size should be hinted as "pushing" and thus want to occupy free space if no one else is claiming it.
127          * @return The value.
128          */
129         public boolean getGapPush()
130         {
131                 return gapPush;
132         }
133
134         /** Returns if this bound size has no min, preferred and maximum size set (they are all <code>null</code>)
135          * @return If unset.
136          */
137         public boolean isUnset()
138         {
139                 // Most common case by far is this == ZERO_PIXEL...
140                 return this == ZERO_PIXEL || (pref == null && min == null && max == null && gapPush == false);
141         }
142
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.
148          */
149         public int constrain(int size, float refValue, ContainerWrapper parent)
150         {
151                 if (max != null)
152                         size = Math.min(size, max.getPixels(refValue, parent, parent));
153                 if (min != null)
154                         size = Math.max(size, min.getPixels(refValue, parent, parent));
155                 return size;
156         }
157
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>.
160          * @return
161          */
162         final UnitValue getSize(int sizeType)
163         {
164                 switch(sizeType) {
165                         case LayoutUtil.MIN:
166                                 return min;
167                         case LayoutUtil.PREF:
168                                 return pref;
169                         case LayoutUtil.MAX:
170                                 return max;
171                         default:
172                                 throw new IllegalArgumentException("Unknown size: " + sizeType);
173                 }
174         }
175
176         /** Convert the bound sizes to pixels.
177          * <p>
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).
183          */
184         final int[] getPixelSizes(float refSize, ContainerWrapper parent, ComponentWrapper comp)
185         {
186                 return new int[] {
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
190                 };
191         }
192
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>.
195          */
196         String getConstraintString()
197         {
198                 String cs = LayoutUtil.getCCString(this);
199                 if (cs != null)
200                         return cs;
201
202                 if (min == pref && pref == max)
203                         return min != null ? (min.getConstraintString() + "!") : "null";
204
205                 StringBuilder sb = new StringBuilder(16);
206
207                 if (min != null)
208                         sb.append(min.getConstraintString()).append(':');
209
210                 if (pref != null) {
211                         if (min == null && max != null)
212                                 sb.append(":");
213                         sb.append(pref.getConstraintString());
214                 } else if (min != null) {
215                         sb.append('n');
216                 }
217
218                 if (max != null)
219                         sb.append(sb.length() == 0 ? "::" : ":").append(max.getConstraintString());
220
221                 if (gapPush) {
222                         if (sb.length() > 0)
223                                 sb.append(':');
224                         sb.append("push");
225                 }
226
227                 return sb.toString();
228         }
229
230         void checkNotLinked()
231         {
232                 if (isLinked())
233                         throw new IllegalArgumentException("Size may not contain links");
234         }
235
236         boolean isLinked()
237         {
238                 return min != null && min.isLinkedDeep() || pref != null && pref.isLinkedDeep() || max != null && max.isLinkedDeep();
239         }
240
241         boolean isAbsolute()
242         {
243                 return (min == null || min.isAbsoluteDeep()) && (pref == null || pref.isAbsoluteDeep()) && (max == null || max.isAbsoluteDeep());
244         }
245
246         public String toString()
247         {
248                 return "BoundSize{" + "min=" + min + ", pref=" + pref + ", max=" + max + ", gapPush=" + gapPush +'}';
249         }
250
251 //      static {
252 //        if(LayoutUtil.HAS_BEANS){
253 //            LayoutUtil.setDelegate(BoundSize.class, new PersistenceDelegate() {
254 //                @Override
255 //                protected Expression instantiate(Object oldInstance, Encoder out)
256 //                {
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()
261 //                        });
262 //                    } else {
263 //                        return new Expression(oldInstance, BoundSize.class, "new", new Object[] {
264 //                                bs.getMin(), bs.getPreferred(), bs.getMax(), bs.getConstraintString()
265 //                        });
266 //                    }
267 //                }
268 //            });
269 //        }
270 //      }
271
272         // ************************************************
273         // Persistence Delegate and Serializable combined.
274         // ************************************************
275
276         private static final long serialVersionUID = 1L;
277
278         protected Object readResolve() throws ObjectStreamException
279         {
280                 return LayoutUtil.getSerializedObject(this);
281         }
282
283         private void writeObject(ObjectOutputStream out) throws IOException
284         {
285 //              if (getClass() == BoundSize.class)
286 //                      LayoutUtil.writeAsXML(out, this);
287         }
288
289         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
290         {
291 //              LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
292         }
293 }