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