~ubuntu-branches/ubuntu/trusty/libjgoodies-forms-java/trusty

« back to all changes in this revision

Viewing changes to src/core/com/jgoodies/forms/layout/Sizes.java

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath
  • Date: 2008-02-25 10:57:07 UTC
  • mfrom: (1.2.1 upstream) (2.1.2 hardy)
  • Revision ID: james.westby@ubuntu.com-20080225105707-pe51fdbcq1dt3vi6
Tags: 1.2.0-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2002-2008 JGoodies Karsten Lentzsch. All Rights Reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions are met:
 
6
 *
 
7
 *  o Redistributions of source code must retain the above copyright notice,
 
8
 *    this list of conditions and the following disclaimer.
 
9
 *
 
10
 *  o Redistributions in binary form must reproduce the above copyright notice,
 
11
 *    this list of conditions and the following disclaimer in the documentation
 
12
 *    and/or other materials provided with the distribution.
 
13
 *
 
14
 *  o Neither the name of JGoodies Karsten Lentzsch nor the names of
 
15
 *    its contributors may be used to endorse or promote products derived
 
16
 *    from this software without specific prior written permission.
 
17
 *
 
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
19
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 
20
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
21
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 
22
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
23
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
24
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 
25
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 
26
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 
27
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 
28
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
29
 */
 
30
 
 
31
package com.jgoodies.forms.layout;
 
32
 
 
33
import java.awt.Component;
 
34
import java.awt.Container;
 
35
import java.io.Serializable;
 
36
import java.util.Iterator;
 
37
import java.util.List;
 
38
import java.util.Locale;
 
39
 
 
40
import com.jgoodies.forms.layout.ConstantSize.Unit;
 
41
import com.jgoodies.forms.util.DefaultUnitConverter;
 
42
import com.jgoodies.forms.util.UnitConverter;
 
43
 
 
44
 
 
45
/**
 
46
 * Consists only of static methods that create and convert sizes
 
47
 * as required by the FormLayout. The conversion of sizes
 
48
 * that are not based on pixel is delegated to an implementation
 
49
 * of {@link UnitConverter}. The conversion methods require the
 
50
 * layout container as parameter to read its current font and resolution.
 
51
 *
 
52
 * @author  Karsten Lentzsch
 
53
 * @version $Revision: 1.14 $
 
54
 *
 
55
 * @see     Size
 
56
 * @see     UnitConverter
 
57
 * @see     DefaultUnitConverter
 
58
 */
 
59
public final class Sizes {
 
60
 
 
61
 
 
62
    // Common Constant Sizes ************************************************
 
63
 
 
64
    public static final ConstantSize ZERO   = pixel(0);
 
65
 
 
66
    public static final ConstantSize DLUX1  = dluX( 1);
 
67
    public static final ConstantSize DLUX2  = dluX( 2);
 
68
    public static final ConstantSize DLUX3  = dluX( 3);
 
69
    public static final ConstantSize DLUX4  = dluX( 4);
 
70
    public static final ConstantSize DLUX5  = dluX( 5);
 
71
    public static final ConstantSize DLUX6  = dluX( 6);
 
72
    public static final ConstantSize DLUX7  = dluX( 7);
 
73
    public static final ConstantSize DLUX8  = dluX( 8);
 
74
    public static final ConstantSize DLUX9  = dluX( 9);
 
75
    public static final ConstantSize DLUX11 = dluX(11);
 
76
    public static final ConstantSize DLUX14 = dluX(14);
 
77
    /**
 
78
     * 21 horizontal dialog units.
 
79
     * @since 1.2
 
80
     */
 
81
    public static final ConstantSize DLUX21 = dluX(21);
 
82
 
 
83
    public static final ConstantSize DLUY1  = dluY( 1);
 
84
    public static final ConstantSize DLUY2  = dluY( 2);
 
85
    public static final ConstantSize DLUY3  = dluY( 3);
 
86
    public static final ConstantSize DLUY4  = dluY( 4);
 
87
    public static final ConstantSize DLUY5  = dluY( 5);
 
88
    public static final ConstantSize DLUY6  = dluY( 6);
 
89
    public static final ConstantSize DLUY7  = dluY( 7);
 
90
    public static final ConstantSize DLUY8  = dluY( 8);
 
91
    public static final ConstantSize DLUY9  = dluY( 9);
 
92
    public static final ConstantSize DLUY11 = dluY(11);
 
93
    public static final ConstantSize DLUY14 = dluY(14);
 
94
    /**
 
95
     * 21 vertical dialog units.
 
96
     * @since 1.2
 
97
     */
 
98
    public static final ConstantSize DLUY21 = dluY(21);
 
99
 
 
100
 
 
101
    // Static Component Sizes ***********************************************
 
102
 
 
103
    /**
 
104
     * Use the maximum of all component minimum sizes as column or row size.
 
105
     */
 
106
    public static final ComponentSize MINIMUM  = new ComponentSize("minimum");
 
107
 
 
108
    /**
 
109
     * Use the maximum of all component preferred sizes as column or row size.
 
110
     */
 
111
    public static final ComponentSize PREFERRED = new ComponentSize("preferred");
 
112
 
 
113
    /**
 
114
     * Use the maximum of all component sizes as column or row size;
 
115
     * measures preferred sizes when asked for the preferred size
 
116
     * and minimum sizes when asked for the minimum size.
 
117
     */
 
118
    public static final ComponentSize DEFAULT = new ComponentSize("default");
 
119
 
 
120
    /**
 
121
     * An array of all enumeration values used to canonicalize
 
122
     * deserialized component sizes.
 
123
     */
 
124
    private static final ComponentSize[] VALUES =
 
125
        { MINIMUM, PREFERRED, DEFAULT};
 
126
 
 
127
 
 
128
    // Singleton State *******************************************************
 
129
 
 
130
    /**
 
131
     * Holds the current converter that maps non-pixel sizes to pixels.
 
132
     *
 
133
     * @see #setUnitConverter(UnitConverter)
 
134
     */
 
135
    private static UnitConverter unitConverter;
 
136
 
 
137
 
 
138
    /**
 
139
     * Holds the Unit that is used if no Unit is provided in encoded
 
140
     * ConstantSizes.
 
141
     *
 
142
     * @see #setDefaultUnit(Unit)
 
143
     */
 
144
    private static Unit defaultUnit = ConstantSize.PIXEL;
 
145
 
 
146
 
 
147
    // Instance Creation ******************************************************
 
148
 
 
149
    private Sizes() {
 
150
        // Suppresses default constructor, prevents instantiation.
 
151
    }
 
152
 
 
153
 
 
154
    // Creation of Size Instances *********************************************
 
155
 
 
156
    /**
 
157
     * Creates and returns an instance of <code>ConstantSize</code> from the
 
158
     * given encoded size and unit description.
 
159
     *
 
160
     * @param encodedValueAndUnit  value and unit in string representation
 
161
     * @param horizontal                        true for horizontal, false for vertical
 
162
     * @return a <code>ConstantSize</code> for the given value and unit
 
163
     */
 
164
    public static ConstantSize constant(String encodedValueAndUnit,
 
165
                                         boolean horizontal) {
 
166
        String lowerCase = encodedValueAndUnit.toLowerCase(Locale.ENGLISH);
 
167
        String trimmed = lowerCase.trim();
 
168
        return ConstantSize.valueOf(trimmed, horizontal);
 
169
    }
 
170
 
 
171
    /**
 
172
     * Creates and returns a ConstantSize for the specified value
 
173
     * in horizontal dialog units.
 
174
     *
 
175
     * @param value     size value in horizontal dialog units
 
176
     * @return the associated <code>ConstantSize</code>
 
177
     */
 
178
    public static ConstantSize dluX(int value) {
 
179
        return ConstantSize.dluX(value);
 
180
    }
 
181
 
 
182
    /**
 
183
     * Creates and returns a ConstantSize for the specified value
 
184
     * in vertical dialog units.
 
185
     *
 
186
     * @param value     size value in vertical dialog units
 
187
     * @return the associated <code>ConstantSize</code>
 
188
     */
 
189
    public static ConstantSize dluY(int value) {
 
190
        return ConstantSize.dluY(value);
 
191
    }
 
192
 
 
193
    /**
 
194
     * Creates and returns a ConstantSize
 
195
     * for the specified pixel value.
 
196
     *
 
197
     * @param value  value in pixel
 
198
     * @return the associated <code>ConstantSize</code>
 
199
     */
 
200
    public static ConstantSize pixel(int value) {
 
201
        return new ConstantSize(value, ConstantSize.PIXEL);
 
202
    }
 
203
 
 
204
    /**
 
205
     * Creates and returns a BoundedSize for the given basis
 
206
     * using the specified lower and upper bounds.
 
207
     *
 
208
     * @param basis             the base size
 
209
     * @param lowerBound        the lower bound size
 
210
     * @param upperBound        the upper bound size
 
211
     * @return a <code>BoundedSize</code> for the given basis and bounds
 
212
     * @throws NullPointerException if {@code basis} is {@code null},
 
213
     *    or if both {@code lowerBound} and {@code upperBound} are {@code null}.
 
214
     */
 
215
    public static Size bounded(Size basis, Size lowerBound, Size upperBound) {
 
216
        return new BoundedSize(basis, lowerBound, upperBound);
 
217
    }
 
218
 
 
219
 
 
220
    // Unit Conversion ******************************************************
 
221
 
 
222
    /**
 
223
     * Converts Inches and returns pixels using the specified resolution.
 
224
     *
 
225
     * @param in           the Inches
 
226
     * @param component    the component that provides the graphics object
 
227
     * @return the given Inches as pixels
 
228
     */
 
229
    public static int inchAsPixel(double in, Component component) {
 
230
        return in == 0d
 
231
            ? 0
 
232
            : getUnitConverter().inchAsPixel(in, component);
 
233
    }
 
234
 
 
235
    /**
 
236
     * Converts Millimeters and returns pixels using the resolution of the
 
237
     * given component's graphics object.
 
238
     *
 
239
     * @param mm                Millimeters
 
240
     * @param component    the component that provides the graphics object
 
241
     * @return the given Millimeters as pixels
 
242
     */
 
243
    public static int millimeterAsPixel(double mm, Component component) {
 
244
        return mm == 0d
 
245
            ? 0
 
246
            : getUnitConverter().millimeterAsPixel(mm, component);
 
247
    }
 
248
 
 
249
    /**
 
250
     * Converts Centimeters and returns pixels using the resolution of the
 
251
     * given component's graphics object.
 
252
     *
 
253
     * @param cm                Centimeters
 
254
     * @param component    the component that provides the graphics object
 
255
     * @return the given Centimeters as pixels
 
256
     */
 
257
    public static int centimeterAsPixel(double cm, Component component) {
 
258
        return cm == 0d
 
259
            ? 0
 
260
            : getUnitConverter().centimeterAsPixel(cm, component);
 
261
    }
 
262
 
 
263
    /**
 
264
     * Converts DTP Points and returns pixels using the resolution of the
 
265
     * given component's graphics object.
 
266
     *
 
267
     * @param pt                DTP Points
 
268
     * @param component    the component that provides the graphics object
 
269
     * @return the given Points as pixels
 
270
     */
 
271
    public static int pointAsPixel(int pt, Component component) {
 
272
        return pt == 0
 
273
            ? 0
 
274
            : getUnitConverter().pointAsPixel(pt, component);
 
275
    }
 
276
 
 
277
    /**
 
278
     * Converts horizontal dialog units and returns pixels.
 
279
     * Honors the resolution, dialog font size, platform, and l&amp;f.
 
280
     *
 
281
     * @param dluX         the horizontal dialog units
 
282
     * @param component    the component that provides the graphics object
 
283
     * @return the given horizontal dialog units as pixels
 
284
     */
 
285
    public static int dialogUnitXAsPixel(int dluX, Component component) {
 
286
        return dluX == 0
 
287
            ? 0
 
288
            : getUnitConverter().dialogUnitXAsPixel(dluX, component);
 
289
    }
 
290
 
 
291
    /**
 
292
     * Converts vertical dialog units and returns pixels.
 
293
     * Honors the resolution, dialog font size, platform, and l&amp;f.
 
294
     *
 
295
     * @param dluY         the vertical dialog units
 
296
     * @param component    the component that provides the graphics object
 
297
     * @return the given vertical dialog units as pixels
 
298
     */
 
299
    public static int dialogUnitYAsPixel(int dluY, Component component) {
 
300
        return dluY == 0
 
301
            ? 0
 
302
            : getUnitConverter().dialogUnitYAsPixel(dluY, component);
 
303
    }
 
304
 
 
305
 
 
306
    // Accessing the Unit Converter *******************************************
 
307
 
 
308
    /**
 
309
     * Returns the current {@link UnitConverter}. If it has not been initialized
 
310
     * before it will get an instance of {@link DefaultUnitConverter}.
 
311
     *
 
312
     * @return the current <code>UnitConverter</code>
 
313
     */
 
314
    public static UnitConverter getUnitConverter() {
 
315
        if (unitConverter == null) {
 
316
            unitConverter = DefaultUnitConverter.getInstance();
 
317
        }
 
318
        return unitConverter;
 
319
    }
 
320
 
 
321
    /**
 
322
     * Sets a new UnitConverter that will be used to convert
 
323
     * font-dependent sizes to pixel sizes.
 
324
     *
 
325
     * @param newUnitConverter  the unit converter to be set
 
326
     */
 
327
    public static void setUnitConverter(UnitConverter newUnitConverter) {
 
328
        unitConverter = newUnitConverter;
 
329
    }
 
330
 
 
331
 
 
332
    // Default Unit ***********************************************************
 
333
 
 
334
    /**
 
335
     * Returns the Unit that is used if an encoded ConstantSize contains
 
336
     * no unit string.
 
337
     *
 
338
     * @return the Unit if no unit string is provided
 
339
     *
 
340
     * @since 1.2
 
341
     */
 
342
    public static Unit getDefaultUnit() {
 
343
        return defaultUnit;
 
344
    }
 
345
 
 
346
 
 
347
    /**
 
348
     * Sets the Unit that shall be used if an encoded ConstantSize
 
349
     * provides no unit string.
 
350
     *
 
351
     * @param unit    the new default Unit, {@code null} for dialog units
 
352
     *
 
353
     * @throws IllegalArgumentException if {@code unit} is
 
354
     *    {@link ConstantSize#DLUX} or {@link ConstantSize#DLUY}.
 
355
     *
 
356
     * @since 1.2
 
357
     */
 
358
    public static void setDefaultUnit(Unit unit) {
 
359
        if ((unit == ConstantSize.DLUX) || (unit == ConstantSize.DLUY)) {
 
360
            throw new IllegalArgumentException(
 
361
                    "The unit must not be DLUX or DLUY. "
 
362
                  + "To use DLU as default unit, invoke this method with null.");
 
363
        }
 
364
        defaultUnit = unit;
 
365
    }
 
366
 
 
367
 
 
368
    // Helper Class *********************************************************
 
369
 
 
370
    /**
 
371
     * An ordinal-based serializable typesafe enumeration that implements
 
372
     * the {@link Size} interface for the component sizes:
 
373
     * <em>min, pref, default</em>.
 
374
     */
 
375
    static final class ComponentSize implements Size, Serializable {
 
376
 
 
377
        private final transient String name;
 
378
 
 
379
        private ComponentSize(String name) {
 
380
            this.name = name;
 
381
        }
 
382
 
 
383
        /**
 
384
         * Returns an instance of <code>ComponentSize</code> that corresponds
 
385
         * to the specified string.
 
386
         * @param str                   the encoded component size
 
387
         * @return the corresponding ComponentSize or null if none matches
 
388
         */
 
389
        static ComponentSize valueOf(String str) {
 
390
            if (str.equals("m") || str.equals("min"))
 
391
                return MINIMUM;
 
392
            if (str.equals("p") || str.equals("pref"))
 
393
                return PREFERRED;
 
394
            if (str.equals("d") || str.equals("default"))
 
395
                return DEFAULT;
 
396
            return null;
 
397
        }
 
398
 
 
399
        /**
 
400
         * Computes the maximum size for the given list of components, using
 
401
         * this form spec and the specified measure.
 
402
         * <p>
 
403
         * Invoked by FormLayout to determine the size of one of my elements
 
404
         *
 
405
         * @param container       the layout container
 
406
         * @param components      the list of components to measure
 
407
         * @param minMeasure      the measure used to determine the minimum size
 
408
         * @param prefMeasure     the measure used to determine the preferred size
 
409
         * @param defaultMeasure  the measure used to determine the default size
 
410
         * @return the maximum size in pixels for the given list of components
 
411
         */
 
412
        public int maximumSize(
 
413
            Container container,
 
414
            List components,
 
415
            FormLayout.Measure minMeasure,
 
416
            FormLayout.Measure prefMeasure,
 
417
            FormLayout.Measure defaultMeasure) {
 
418
 
 
419
            FormLayout.Measure measure = this == MINIMUM
 
420
                    ? minMeasure
 
421
                    : (this == PREFERRED ? prefMeasure : defaultMeasure);
 
422
            int maximum = 0;
 
423
            for (Iterator i = components.iterator(); i.hasNext();) {
 
424
                Component c = (Component) i.next();
 
425
                maximum = Math.max(maximum, measure.sizeOf(c));
 
426
            }
 
427
            return maximum;
 
428
        }
 
429
 
 
430
        /**
 
431
         * Describes if this Size can be compressed, if container space gets scarce.
 
432
         * Used by the FormLayout size computations in <code>#compressedSizes</code>
 
433
         * to check whether a column or row can be compressed or not.<p>
 
434
         *
 
435
         * The DEFAULT ComponentSize is compressible, MINIMUM and PREFERRED
 
436
         * are incompressible.
 
437
         *
 
438
         * @return <code>true</code> for the DEFAULT size,
 
439
         *      <code>false</code> otherwise
 
440
         *
 
441
         * @since 1.1
 
442
         */
 
443
        public boolean compressible() {
 
444
            return this == DEFAULT;
 
445
        }
 
446
 
 
447
 
 
448
        public String toString() {
 
449
            return encode();
 
450
        }
 
451
 
 
452
 
 
453
        /**
 
454
         * Returns a parseable string representation of this ComponentSize.
 
455
         *
 
456
         * @return a String that can be parsed by the Forms parser
 
457
         *
 
458
         * @since 1.2
 
459
         */
 
460
        public String encode() {
 
461
            return name.substring(0, 1);
 
462
        }
 
463
 
 
464
 
 
465
        // Serialization *****************************************************
 
466
 
 
467
        private static int nextOrdinal = 0;
 
468
 
 
469
        private final int ordinal = nextOrdinal++;
 
470
 
 
471
        private Object readResolve() {
 
472
            return VALUES[ordinal];  // Canonicalize
 
473
        }
 
474
 
 
475
    }
 
476
 
 
477
 
 
478
}