001/* 002 * Copyright (c) 2002-2007 JGoodies Karsten Lentzsch. All Rights Reserved. 003 * 004 * Redistribution and use in source and binary forms, with or without 005 * modification, are permitted provided that the following conditions are met: 006 * 007 * o Redistributions of source code must retain the above copyright notice, 008 * this list of conditions and the following disclaimer. 009 * 010 * o Redistributions in binary form must reproduce the above copyright notice, 011 * this list of conditions and the following disclaimer in the documentation 012 * and/or other materials provided with the distribution. 013 * 014 * o Neither the name of JGoodies Karsten Lentzsch nor the names of 015 * its contributors may be used to endorse or promote products derived 016 * from this software without specific prior written permission. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 020 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 021 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 022 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 023 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 024 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 025 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 026 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 027 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030 031package com.jgoodies.forms.layout; 032 033import java.awt.Component; 034import java.awt.Container; 035import java.io.Serializable; 036import java.util.Iterator; 037import java.util.List; 038 039import com.jgoodies.forms.util.DefaultUnitConverter; 040import com.jgoodies.forms.util.UnitConverter; 041 042/** 043 * Consists only of static methods that create and convert sizes 044 * as required by the FormLayout. The conversion of sizes 045 * that are not based on pixel is delegated to an implementation 046 * of {@link UnitConverter}. The conversion methods require the 047 * layout container as parameter to read its current font and resolution. 048 * 049 * @author Karsten Lentzsch 050 * @version $Revision$ 051 * 052 * @see Size 053 * @see UnitConverter 054 * @see DefaultUnitConverter 055 */ 056public final class Sizes { 057 058 // Common Constant Sizes ************************************************ 059 060 public static final ConstantSize ZERO = pixel(0); 061 062 public static final ConstantSize DLUX1 = dluX(1); 063 public static final ConstantSize DLUX2 = dluX(2); 064 public static final ConstantSize DLUX3 = dluX(3); 065 public static final ConstantSize DLUX4 = dluX(4); 066 public static final ConstantSize DLUX5 = dluX(5); 067 public static final ConstantSize DLUX6 = dluX(6); 068 public static final ConstantSize DLUX7 = dluX(7); 069 public static final ConstantSize DLUX8 = dluX(8); 070 public static final ConstantSize DLUX9 = dluX(9); 071 public static final ConstantSize DLUX11 = dluX(11); 072 public static final ConstantSize DLUX14 = dluX(14); 073 074 public static final ConstantSize DLUY1 = dluY(1); 075 public static final ConstantSize DLUY2 = dluY(2); 076 public static final ConstantSize DLUY3 = dluY(3); 077 public static final ConstantSize DLUY4 = dluY(4); 078 public static final ConstantSize DLUY5 = dluY(5); 079 public static final ConstantSize DLUY6 = dluY(6); 080 public static final ConstantSize DLUY7 = dluY(7); 081 public static final ConstantSize DLUY8 = dluY(8); 082 public static final ConstantSize DLUY9 = dluY(9); 083 public static final ConstantSize DLUY11 = dluY(11); 084 public static final ConstantSize DLUY14 = dluY(14); 085 086 // Static Component Sizes *********************************************** 087 088 /** 089 * Use the maximum of all component minimum sizes as column or row size. 090 */ 091 public static final ComponentSize MINIMUM = new ComponentSize("minimum"); 092 093 /** 094 * Use the maximum of all component preferred sizes as column or row size. 095 */ 096 public static final ComponentSize PREFERRED = new ComponentSize( 097 "preferred"); 098 099 /** 100 * Use the maximum of all component sizes as column or row size; 101 * measures preferred sizes when asked for the preferred size 102 * and minimum sizes when asked for the minimum size. 103 */ 104 public static final ComponentSize DEFAULT = new ComponentSize("default"); 105 106 /** 107 * An array of all enumeration values used to canonicalize 108 * deserialized component sizes. 109 */ 110 private static final ComponentSize[] VALUES = { MINIMUM, PREFERRED, 111 DEFAULT }; 112 113 // Singleton State ******************************************************* 114 115 /** 116 * Holds the current converter that maps non-pixel sizes to pixels. 117 */ 118 private static UnitConverter unitConverter; 119 120 // Instance Creation ****************************************************** 121 122 private Sizes() { 123 // Suppresses default constructor, ensuring non-instantiability. 124 } 125 126 // Creation of Size Instances ********************************************* 127 128 /** 129 * Creates and returns an instance of <code>ConstantSize</code> from the 130 * given encoded size and unit description. 131 * 132 * @param encodedValueAndUnit value and unit in string representation 133 * @param horizontal true for horizontal, false for vertical 134 * @return a <code>ConstantSize</code> for the given value and unit 135 */ 136 public static ConstantSize constant(String encodedValueAndUnit, 137 boolean horizontal) { 138 return ConstantSize.valueOf(encodedValueAndUnit, horizontal); 139 } 140 141 /** 142 * Creates and returns a ConstantSize for the specified value 143 * in horizontal dialog units. 144 * 145 * @param value size value in horizontal dialog units 146 * @return the associated <code>ConstantSize</code> 147 */ 148 public static ConstantSize dluX(int value) { 149 return ConstantSize.dluX(value); 150 } 151 152 /** 153 * Creates and returns a ConstantSize for the specified value 154 * in vertical dialog units. 155 * 156 * @param value size value in vertical dialog units 157 * @return the associated <code>ConstantSize</code> 158 */ 159 public static ConstantSize dluY(int value) { 160 return ConstantSize.dluY(value); 161 } 162 163 /** 164 * Creates and returns a ConstantSize 165 * for the specified pixel value. 166 * 167 * @param value value in pixel 168 * @return the associated <code>ConstantSize</code> 169 */ 170 public static ConstantSize pixel(int value) { 171 return new ConstantSize(value, ConstantSize.PIXEL); 172 } 173 174 /** 175 * Creates and returns a BoundedSize for the given basis 176 * using the specified lower and upper bounds. 177 * 178 * @param basis the base size 179 * @param lowerBound the lower bound size 180 * @param upperBound the upper bound size 181 * @return a <code>BoundedSize</code> for the given basis and bounds 182 * @exception NullPointerException if basis is null 183 */ 184 public static Size bounded(Size basis, Size lowerBound, Size upperBound) { 185 return new BoundedSize(basis, lowerBound, upperBound); 186 } 187 188 // Unit Conversion ****************************************************** 189 190 /** 191 * Converts Inches and returns pixels using the specified resolution. 192 * 193 * @param in the Inches 194 * @param component the component that provides the graphics object 195 * @return the given Inches as pixels 196 */ 197 public static int inchAsPixel(double in, Component component) { 198 return in == 0d ? 0 : getUnitConverter().inchAsPixel(in, component); 199 } 200 201 /** 202 * Converts Millimeters and returns pixels using the resolution of the 203 * given component's graphics object. 204 * 205 * @param mm Millimeters 206 * @param component the component that provides the graphics object 207 * @return the given Millimeters as pixels 208 */ 209 public static int millimeterAsPixel(double mm, Component component) { 210 return mm == 0d ? 0 211 : getUnitConverter().millimeterAsPixel(mm, component); 212 } 213 214 /** 215 * Converts Centimeters and returns pixels using the resolution of the 216 * given component's graphics object. 217 * 218 * @param cm Centimeters 219 * @param component the component that provides the graphics object 220 * @return the given Centimeters as pixels 221 */ 222 public static int centimeterAsPixel(double cm, Component component) { 223 return cm == 0d ? 0 224 : getUnitConverter().centimeterAsPixel(cm, component); 225 } 226 227 /** 228 * Converts DTP Points and returns pixels using the resolution of the 229 * given component's graphics object. 230 * 231 * @param pt DTP Points 232 * @param component the component that provides the graphics object 233 * @return the given Points as pixels 234 */ 235 public static int pointAsPixel(int pt, Component component) { 236 return pt == 0 ? 0 : getUnitConverter().pointAsPixel(pt, component); 237 } 238 239 /** 240 * Converts horizontal dialog units and returns pixels. 241 * Honors the resolution, dialog font size, platform, and l&f. 242 * 243 * @param dluX the horizontal dialog units 244 * @param component the component that provides the graphics object 245 * @return the given horizontal dialog units as pixels 246 */ 247 public static int dialogUnitXAsPixel(int dluX, Component component) { 248 return dluX == 0 ? 0 249 : getUnitConverter().dialogUnitXAsPixel(dluX, component); 250 } 251 252 /** 253 * Converts vertical dialog units and returns pixels. 254 * Honors the resolution, dialog font size, platform, and l&f. 255 * 256 * @param dluY the vertical dialog units 257 * @param component the component that provides the graphics object 258 * @return the given vertical dialog units as pixels 259 */ 260 public static int dialogUnitYAsPixel(int dluY, Component component) { 261 return dluY == 0 ? 0 262 : getUnitConverter().dialogUnitYAsPixel(dluY, component); 263 } 264 265 // Accessing the Unit Converter ******************************************* 266 267 /** 268 * Returns the current {@link UnitConverter}. If it has not been initialized 269 * before it will get an instance of {@link DefaultUnitConverter}. 270 * 271 * @return the current <code>UnitConverter</code> 272 */ 273 public static UnitConverter getUnitConverter() { 274 if (unitConverter == null) { 275 unitConverter = DefaultUnitConverter.getInstance(); 276 } 277 return unitConverter; 278 } 279 280 /** 281 * Sets a new UnitConverter that will be used to convert 282 * font-dependent sizes to pixel sizes. 283 * 284 * @param newUnitConverter the unit converter to be set 285 */ 286 public static void setUnitConverter(UnitConverter newUnitConverter) { 287 unitConverter = newUnitConverter; 288 } 289 290 // Helper Class ********************************************************* 291 292 /** 293 * An ordinal-based serializable typesafe enumeration that implements 294 * the {@link Size} interface for the component sizes: 295 * <em>min, pref, default</em>. 296 */ 297 @SuppressWarnings("serial") 298 static final class ComponentSize implements Size, Serializable { 299 300 private final transient String name; 301 302 private ComponentSize(String name) { 303 this.name = name; 304 } 305 306 /** 307 * Returns an instance of <code>ComponentSize</code> that corresponds 308 * to the specified string. 309 * @param str the encoded component size 310 * @return the corresponding ComponentSize or null if none matches 311 */ 312 static ComponentSize valueOf(String str) { 313 if (str.equals("m") || str.equals("min")) { 314 return MINIMUM; 315 } 316 if (str.equals("p") || str.equals("pref")) { 317 return PREFERRED; 318 } 319 if (str.equals("d") || str.equals("default")) { 320 return DEFAULT; 321 } 322 return null; 323 } 324 325 /** 326 * Computes the maximum size for the given list of components, using 327 * this form spec and the specified measure. 328 * <p> 329 * Invoked by FormLayout to determine the size of one of my elements 330 * 331 * @param container the layout container 332 * @param components the list of components to measure 333 * @param minMeasure the measure used to determine the minimum size 334 * @param prefMeasure the measure used to determine the preferred size 335 * @param defaultMeasure the measure used to determine the default size 336 * @return the maximum size in pixels for the given list of components 337 */ 338 @Override 339 public int maximumSize(Container container, List components, 340 FormLayout.Measure minMeasure, FormLayout.Measure prefMeasure, 341 FormLayout.Measure defaultMeasure) { 342 343 FormLayout.Measure measure = this == MINIMUM ? minMeasure 344 : this == PREFERRED ? prefMeasure : defaultMeasure; 345 int maximum = 0; 346 for (Iterator i = components.iterator(); i.hasNext();) { 347 Component c = (Component) i.next(); 348 maximum = Math.max(maximum, measure.sizeOf(c)); 349 } 350 return maximum; 351 } 352 353 @Override 354 public String toString() { 355 return name.substring(0, 1); 356 } 357 358 // Serialization ***************************************************** 359 360 private static int nextOrdinal = 0; 361 362 private final int ordinal = nextOrdinal++; 363 364 private Object readResolve() { 365 return VALUES[ordinal]; // Canonicalize 366 } 367 368 } 369 370}