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.platform.swing.layout;
17  
18  import java.awt.Component;
19  import java.awt.Font;
20  import java.awt.FontMetrics;
21  import java.awt.Toolkit;
22  import java.io.Serializable;
23  import java.util.HashMap;
24  import java.util.Map;
25  
26  import net.sf.jguiraffe.gui.layout.UnitSizeHandler;
27  
28  /**
29   * <p>
30   * Swing specific implementation of the <code>SizeHandler</code> interface.
31   * </p>
32   * <p>
33   * Note: This implementation performs some caching to optimize performance, but
34   * it is not synchronized. So it must be ensured that an instance is accessed by
35   * a single thread only or that manual synchronization is performed.
36   * </p>
37   *
38   * @author Oliver Heger
39   * @version $Id: SwingSizeHandler.java 205 2012-01-29 18:29:57Z oheger $
40   */
41  public class SwingSizeHandler implements UnitSizeHandler, Serializable
42  {
43      /**
44       * The serial version UID.
45       */
46      private static final long serialVersionUID = 20090731L;
47  
48      /**
49       * Constant for the string used for determining the average character width.
50       */
51      private static final String WIDTH_STRING =
52              "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
53  
54      /** Constant for the length of the width string. */
55      private static final int WIDTH_STRING_LEN = WIDTH_STRING.length();
56  
57      /** Constant for the array index with the X font size. */
58      private static final int IDX_FONTX = 0;
59  
60      /** Constant for the array index with the Y font size. */
61      private static final int IDX_FONTY = 1;
62  
63      /**
64       * A cache for storing the character sizes that have already been
65       * determined.
66       */
67      private final Map<Font, double[]> sizeCache;
68  
69      /**
70       * Creates a new instance of <code>SwingSizeHandler</code>.
71       */
72      public SwingSizeHandler()
73      {
74          sizeCache = new HashMap<Font, double[]>();
75      }
76  
77      /**
78       * Calculates the desired font size for the given component. The passed in
79       * object is expected to be a <code>Component</code> instance.
80       *
81       * @param component the component (must not be <b>null</b>)
82       * @param y the orientation flag
83       * @return the font size
84       * @throws IllegalArgumentException if the component is <b>null</b>
85       */
86      public double getFontSize(Object component, boolean y)
87      {
88          if (!(component instanceof Component))
89          {
90              throw new IllegalArgumentException(
91                      "getFontSize() can only work with Component objects: "
92                              + component);
93          }
94  
95          Component comp = (Component) component;
96          Font font = comp.getFont();
97  
98          double[] sizes = (double[]) sizeCache.get(font);
99          if (sizes == null)
100         {
101             sizes = calculateFontSizes(font, comp);
102             sizeCache.put(font, sizes);
103         }
104 
105         return y ? sizes[IDX_FONTY] : sizes[IDX_FONTX];
106     }
107 
108     /**
109      * Returns the current screen resolution.
110      *
111      * @return the screen resolution
112      */
113     public int getScreenResolution()
114     {
115         return Toolkit.getDefaultToolkit().getScreenResolution();
116     }
117 
118     /**
119      * Helper method for calculating the relevant sizes for the given font.
120      *
121      * @param font the font
122      * @param comp the associated component
123      * @return an array with the relevant font sizes
124      */
125     double[] calculateFontSizes(Font font, Component comp)
126     {
127         double[] result = new double[2];
128         FontMetrics fm = comp.getFontMetrics(font);
129         result[IDX_FONTX] =
130                 (double) fm.stringWidth(WIDTH_STRING) / WIDTH_STRING_LEN;
131         result[IDX_FONTY] = fm.getHeight();
132         return result;
133     }
134 }