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 }