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:
031: package com.jgoodies.forms.util;
032:
033: import java.awt.Component;
034: import java.awt.FontMetrics;
035: import java.awt.Toolkit;
036:
037: /**
038: * An abstract implementation of the {@link UnitConverter} interface that
039: * minimizes the effort required to convert font-dependent sizes to pixels.
040: *
041: * @author Karsten Lentzsch
042: * @version $Revision: 1.2 $
043: *
044: * @see DefaultUnitConverter
045: * @see com.jgoodies.forms.layout.Size
046: * @see com.jgoodies.forms.layout.Sizes
047: */
048: public abstract class AbstractUnitConverter implements UnitConverter {
049:
050: private static final int DTP_RESOLUTION = 72;
051:
052: // Unit Converter Implementation *********************************************
053:
054: /**
055: * Converts Inches and returns pixels using the specified resolution.
056: *
057: * @param in the Inches
058: * @param component the component that provides the graphics object
059: * @return the given Inches as pixels
060: */
061: public int inchAsPixel(double in, Component component) {
062: return inchAsPixel(in, getScreenResolution(component));
063: }
064:
065: /**
066: * Converts Millimeters and returns pixels using the resolution of the
067: * given component's graphics object.
068: *
069: * @param mm Millimeters
070: * @param component the component that provides the graphics object
071: * @return the given Millimeters as pixels
072: */
073: public int millimeterAsPixel(double mm, Component component) {
074: return millimeterAsPixel(mm, getScreenResolution(component));
075: }
076:
077: /**
078: * Converts Centimeters and returns pixels using the resolution of the
079: * given component's graphics object.
080: *
081: * @param cm Centimeters
082: * @param component the component that provides the graphics object
083: * @return the given Centimeters as pixels
084: */
085: public int centimeterAsPixel(double cm, Component component) {
086: return centimeterAsPixel(cm, getScreenResolution(component));
087: }
088:
089: /**
090: * Converts DTP Points and returns pixels using the resolution of the
091: * given component's graphics object.
092: *
093: * @param pt DTP Points
094: * @param component the component that provides the graphics object
095: * @return the given Points as pixels
096: */
097: public int pointAsPixel(int pt, Component component) {
098: return pointAsPixel(pt, getScreenResolution(component));
099: }
100:
101: /**
102: * Converts horizontal dialog units and returns pixels.
103: * Honors the resolution, dialog font size, platform, and l&f.
104: *
105: * @param dluX the horizontal dialog units
106: * @param c a Component that provides the font and graphics
107: * @return the given horizontal dialog units as pixels
108: */
109: public int dialogUnitXAsPixel(int dluX, Component c) {
110: return dialogUnitXAsPixel(dluX, getDialogBaseUnitsX(c));
111: }
112:
113: /**
114: * Converts vertical dialog units and returns pixels.
115: * Honors the resolution, dialog font size, platform, and l&f.
116: *
117: * @param dluY the vertical dialog units
118: * @param c a Component that provides the font and graphics
119: * @return the given vertical dialog units as pixels
120: */
121: public int dialogUnitYAsPixel(int dluY, Component c) {
122: return dialogUnitYAsPixel(dluY, getDialogBaseUnitsY(c));
123: }
124:
125: // Abstract Behavior *****************************************************
126:
127: /**
128: * Gets and returns the horizontal dialog base units.
129: * Implementations are encouraged to cache previously computed
130: * dialog base units.
131: *
132: * @param component a Component that provides the font and graphics
133: * @return the horizontal dialog base units
134: */
135: protected abstract double getDialogBaseUnitsX(Component component);
136:
137: /**
138: * Gets and returns the vertical dialog base units.
139: * Implementations are encouraged to cache previously computed
140: * dialog base units.
141: *
142: * @param component a Component that provides the font and graphics
143: * @return the vertical dialog base units
144: */
145: protected abstract double getDialogBaseUnitsY(Component component);
146:
147: // Convenience Methods ***************************************************
148:
149: /**
150: * Converts Inches and returns pixels using the specified resolution.
151: *
152: * @param in the Inches
153: * @param dpi the resolution
154: * @return the given Inches as pixels
155: */
156: protected final int inchAsPixel(double in, int dpi) {
157: return (int) Math.round(dpi * in);
158: }
159:
160: /**
161: * Converts Millimeters and returns pixels using the specified resolution.
162: *
163: * @param mm Millimeters
164: * @param dpi the resolution
165: * @return the given Millimeters as pixels
166: */
167: protected final int millimeterAsPixel(double mm, int dpi) {
168: return (int) Math.round(dpi * mm * 10 / 254);
169: }
170:
171: /**
172: * Converts Centimeters and returns pixels using the specified resolution.
173: *
174: * @param cm Centimeters
175: * @param dpi the resolution
176: * @return the given Centimeters as pixels
177: */
178: protected final int centimeterAsPixel(double cm, int dpi) {
179: return (int) Math.round(dpi * cm * 100 / 254);
180: }
181:
182: /**
183: * Converts DTP Points and returns pixels using the specified resolution.
184: *
185: * @param pt DTP Points
186: * @param dpi the resolution in dpi
187: * @return the given Points as pixels
188: */
189: protected final int pointAsPixel(int pt, int dpi) {
190: return Math.round(dpi * pt / DTP_RESOLUTION);
191: }
192:
193: /**
194: * Converts horizontal dialog units and returns pixels.
195: *
196: * @param dluX the horizontal dialog units
197: * @param dialogBaseUnitsX the horizontal dialog base units
198: * @return the given dialog base units as pixels
199: */
200: protected int dialogUnitXAsPixel(int dluX, double dialogBaseUnitsX) {
201: return (int) Math.round(dluX * dialogBaseUnitsX / 4);
202: }
203:
204: /**
205: * Converts vertical dialog units and returns pixels.
206: *
207: * @param dluY the vertical dialog units
208: * @param dialogBaseUnitsY the vertical dialog base units
209: * @return the given dialog base units as pixels
210: */
211: protected int dialogUnitYAsPixel(int dluY, double dialogBaseUnitsY) {
212: return (int) Math.round(dluY * dialogBaseUnitsY / 8);
213: }
214:
215: // Helper Code ************************************************************
216:
217: /**
218: * Computes and returns the average character width
219: * of the specified test string using the given FontMetrics.
220: * The test string shall represent an "average" text.
221: *
222: * @param metrics used to compute the test string's width
223: * @param testString the string that shall represent an "average" text
224: * @return the test string's average character width.
225: */
226: protected double computeAverageCharWidth(FontMetrics metrics,
227: String testString) {
228: int width = metrics.stringWidth(testString);
229: double average = (double) width / testString.length();
230: //System.out.println("Average width of '" + testString + "'=" + average);
231: return average;
232: }
233:
234: /**
235: * Returns the components screen resolution or the default screen
236: * resolution if the component is null or has no toolkit assigned yet.
237: *
238: * @param c the component to ask for a toolkit
239: * @return the component's screen resolution
240: */
241: protected int getScreenResolution(Component c) {
242: if (c == null)
243: return getDefaultScreenResolution();
244:
245: Toolkit toolkit = c.getToolkit();
246: return toolkit != null ? toolkit.getScreenResolution()
247: : getDefaultScreenResolution();
248: }
249:
250: private static int defaultScreenResolution = -1;
251:
252: /**
253: * Computes and returns the default resolution.
254: *
255: * @return the default screen resolution
256: */
257: protected int getDefaultScreenResolution() {
258: if (defaultScreenResolution == -1) {
259: defaultScreenResolution = Toolkit.getDefaultToolkit()
260: .getScreenResolution();
261: }
262: return defaultScreenResolution;
263: }
264:
265: }
|