1 /*
2 * Copyright 2006-2016 The JGUIraffe Team.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License")
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package net.sf.jguiraffe.gui.layout;
17
18 import java.util.HashMap;
19 import java.util.Map;
20
21 /**
22 * <p>
23 * An enumeration class for defining units.
24 * </p>
25 * <p>
26 * Some of the layout classes can deal with different units, e.g. with
27 * centimeters, pixels or dialog units. This class is an enumeration class which
28 * defines constants for the supported units. It also provides functionality for
29 * converting a number in their represented unit into the default unit pixel.
30 * </p>
31 * <p>
32 * Usually this class will not be used directly. Instead convenience classes
33 * will be used which combine numeric values with a unit.
34 * </p>
35 *
36 * @author Oliver Heger
37 * @version $Id: Unit.java 205 2012-01-29 18:29:57Z oheger $
38 */
39 public enum Unit
40 {
41 /**
42 * The unit <em>pixel</em>. Pixels are the default unit. They do not require
43 * any special conversion logic.
44 */
45 PIXEL("px")
46 {
47 /**
48 * {@inheritDoc} This implementation just rounds the floating point
49 * number to obtain the integer pixel value.
50 */
51 @Override
52 public int toPixel(double value, UnitSizeHandler handler, Object comp,
53 boolean y)
54 {
55 return (int) Math.round(value);
56 }
57 },
58
59 /**
60 * The unit <em>inch</em>. Inches can be converted to pixels based on the
61 * current screen resolution, which is defined in pixels per inch.
62 */
63 INCH("in")
64 {
65 /**
66 * {@inheritDoc} This implementation applies the screen resolution to
67 * the inch value.
68 */
69 @Override
70 public int toPixel(double value, UnitSizeHandler handler, Object comp,
71 boolean y)
72 {
73 return (int) Math.round(value * handler.getScreenResolution());
74 }
75 },
76
77 /**
78 * The unit <em>cm</em>. Centimeters work similar to inches. The conversion
79 * to pixels is also based on the current screen resolution. However, a
80 * different conversion factor is used.
81 */
82 CM("cm")
83 {
84 /**
85 * {@inheritDoc} This implementation transforms the centimeter value to
86 * inches and applies the screen resolution.
87 */
88 @Override
89 public int toPixel(double value, UnitSizeHandler handler, Object comp,
90 boolean y)
91 {
92 return (int) Math.round(value * CM_FACTOR
93 * handler.getScreenResolution());
94 }
95 },
96
97 /**
98 * The unit <em>dlu</em>. A "dialog unit" is a unit whose exact
99 * size depends on the font of the container it is used in. A horizontal
100 * dialog unit equals the fourth part of the container's font's average
101 * character width; a vertical dialog unit equals the eighth part of the
102 * character height. So to transform a value in this unit to pixels always
103 * the corresponding container component must be known.
104 */
105 DLU("dlu")
106 {
107 /**
108 * {@inheritDoc} This implementation performs the transformation
109 * depending on the direction and the font size of the container object.
110 */
111 @Override
112 public int toPixel(double value, UnitSizeHandler handler, Object comp,
113 boolean y)
114 {
115 int factor = y ? DLU_Y_FACTOR : DLU_X_FACTOR;
116 return (int) Math.round((value * handler.getFontSize(comp, y))
117 / factor);
118 }
119 };
120
121 /** Constant for the DLU width factor. */
122 private static final int DLU_X_FACTOR = 4;
123
124 /** Constant for the DLU height factor. */
125 private static final int DLU_Y_FACTOR = 8;
126
127 /** Constant for the inch factor. */
128 private static final double INCH_FACTOR = 2.54;
129
130 /** Constant for transforming a centimeter value to an inch. */
131 private static final double CM_FACTOR = 1 / INCH_FACTOR;
132
133 /** The mapping between short unit names and enumeration constants. */
134 private static final Map<String, Unit> UNIT_NAMES;
135
136 /** Stores the short name of the unit. */
137 private final String unitName;
138
139 /**
140 * Creates a new instance of {@code Unit} and sets the short name of the
141 * unit.
142 *
143 * @param n the unit short name
144 */
145 private Unit(String n)
146 {
147 unitName = n;
148 }
149
150 /**
151 * Returns the short unit name. This is something like "cm" or "in". This
152 * name can be passed to the {@link #fromString(String)} method for
153 * obtaining the corresponding enumeration literal.
154 *
155 * @return the short unit name
156 */
157 public String getUnitName()
158 {
159 return unitName;
160 }
161
162 /**
163 * Converts the specified value from this unit into pixels. This can be used
164 * for calculating values in the default unit pixels.
165 *
166 * @param value the value to be converted
167 * @param handler the size handler implementation; this is needed by complex
168 * unit classes
169 * @param comp the affected component; can be used by derived classes to
170 * obtain needed information
171 * @param y a flag whether the value is to be converted for the X or the Y
172 * direction; some units may make a distinction
173 * @return the value in pixels
174 */
175 public abstract int toPixel(double value, UnitSizeHandler handler,
176 Object comp, boolean y);
177
178 /**
179 * Returns the {@code Unit} constant for the unit with the given short name.
180 * This method works like the default {@code valueOf()} method available for
181 * each enumeration class. However, it operates on the short unit names as
182 * returned by {@link #getUnitName()}. It is case insensitive and throws an
183 * exception if the name cannot be resolved.
184 *
185 * @param name the short name of the unit
186 * @return the {@code Unit} constant with this short name
187 * @throws IllegalArgumentException if the name cannot be resolved
188 */
189 public static Unit fromString(String name)
190 {
191 Unit result = null;
192 if (name != null)
193 {
194 result = UNIT_NAMES.get(name.toLowerCase());
195 }
196
197 if (result == null)
198 {
199 throw new IllegalArgumentException("Unknown unit: " + name);
200 }
201 return result;
202 }
203
204 // static initializer
205 static
206 {
207 UNIT_NAMES = new HashMap<String, Unit>();
208 for (Unit u : values())
209 {
210 UNIT_NAMES.put(u.getUnitName(), u);
211 }
212 }
213 }