View Javadoc

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 &quot;dialog unit&quot; 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 }