/** * Lazily instantiates and returns the sole instance. * * @return the lazily instantiated sole instance */ public static DefaultUnitConverter getInstance() { if (instance == null) { instance = new DefaultUnitConverter(); } return instance; }
/** * Lazily computes and answer the global dialog base units. * Should be re-computed if the l&f, platform, or screen changes. * * @return a cached DialogBaseUnits object used globally if no container is available */ private DialogBaseUnits getGlobalDialogBaseUnits() { if (cachedGlobalDialogBaseUnits == null) { cachedGlobalDialogBaseUnits = computeGlobalDialogBaseUnits(); } return cachedGlobalDialogBaseUnits; }
/** * Returns the cached or computed vertical dialog base units * for the given component. * * @param component a Component that provides the font and graphics * @return the vertical dialog base units */ @Override protected double getDialogBaseUnitsY(Component component) { return getDialogBaseUnits(component).y; }
/** * Clears cached internal Forms state that is based * on the Look&Feel, for example dialog base units.<p> * * There's typically no need to call this method directly. * It'll be invoked automatically, if the L&F has been changed * via {@link UIManager#setLookAndFeel} and cached data is requested. * It's been made public to allow cache invalidation for cases * where the L&F is changed temporarily by replacing the UIDefaults, * for example in a visual editor. * * @since 1.2.1 */ public static void clearLookAndFeelBasedCaches() { cachedIsLafAqua = null; DefaultUnitConverter.getInstance().clearCache(); }
/** * Computes the global dialog base units. The current implementation assumes * a fixed 8pt font and on 96 or 120 dpi. A better implementation should ask * for the main dialog font and should honor the current screen resolution. * <p> * * Should be re-computed if the l&f, platform, or screen changes. * * @return a DialogBaseUnits object used globally if no container is * available */ private DialogBaseUnits computeGlobalDialogBaseUnits() { logInfo("Computing global dialog base units..."); Font dialogFont = getDefaultDialogFont(); FontMetrics metrics = createDefaultGlobalComponent().getFontMetrics(dialogFont); DialogBaseUnits globalDialogBaseUnits = computeDialogBaseUnits(metrics); return globalDialogBaseUnits; }
/** * Looks up and returns the dialog base units for the given component. In * case the component is <code>null</code> the global dialog base units * are answered. * <p> * * Before we compute the dialog base units we check whether they have been * computed and cached before - for the same component * <code>FontMetrics</code>. * * @param c * the component that provides the graphics object * @return the DialogBaseUnits object for the given component */ private DialogBaseUnits getDialogBaseUnits(Component c) { if (c == null) { // || (font = c.getFont()) == null) { logInfo("Missing font metrics: " + c); return getGlobalDialogBaseUnits(); } FontMetrics fm = c.getFontMetrics(getDefaultDialogFont()); DialogBaseUnits dialogBaseUnits = (DialogBaseUnits) cachedDialogBaseUnits.get(fm); if (dialogBaseUnits == null) { dialogBaseUnits = computeDialogBaseUnits(fm); cachedDialogBaseUnits.put(fm, dialogBaseUnits); } return dialogBaseUnits; }
/** * Computes the global dialog base units. The current implementation * assumes a fixed 8pt font and on 96 or 120 dpi. A better implementation * should ask for the main dialog font and should honor the current * screen resolution.<p> * * Should be re-computed if the l&f, platform, or screen changes. * * @return a DialogBaseUnits object used globally if no container is available */ private DialogBaseUnits computeGlobalDialogBaseUnits() { LOGGER.config("Computing global dialog base units..."); Font dialogFont = getDefaultDialogFont(); FontMetrics metrics = createDefaultGlobalComponent().getFontMetrics(dialogFont); DialogBaseUnits globalDialogBaseUnits = computeDialogBaseUnits(metrics); return globalDialogBaseUnits; }
/** * Looks up and returns the dialog base units for the given component. * In case the component is {@code null} the global dialog base units * are answered.<p> * * Before we compute the dialog base units we check whether they * have been computed and cached before - for the same component * {@code FontMetrics}. * * @param c the component that provides the graphics object * @return the DialogBaseUnits object for the given component */ private DialogBaseUnits getDialogBaseUnits(Component c) { FormUtils.ensureValidCache(); if (c == null) { // || (font = c.getFont()) == null) { // logInfo("Missing font metrics: " + c); return getGlobalDialogBaseUnits(); } FontMetrics fm = c.getFontMetrics(getDefaultDialogFont()); if (fm.equals(cachedFontMetrics)) { return cachedDialogBaseUnits; } DialogBaseUnits dialogBaseUnits = computeDialogBaseUnits(fm); cachedFontMetrics = fm; cachedDialogBaseUnits = dialogBaseUnits; return dialogBaseUnits; }
/** * Computes and returns the width of this Size's prototype in pixel. * Ignores the component list and measures. Obtains the FontMetrics * from the given layout {@code container} for the default dialog font * provided by {@link DefaultUnitConverter#getDefaultDialogFont()}.<p> * * Invoked by {@link com.jgoodies.forms.layout.FormSpec} to determine * the size of a column or row. * * @param container the layout container * @param components the list of components used to compute the size * @param minMeasure the measure that determines the minimum sizes * @param prefMeasure the measure that determines the preferred sizes * @param defaultMeasure the measure that determines the default sizes * * @return the {@code stringWidth} for this size's prototype string * computed by the {@code container}'s FontMetrics for the * {@code DefaultUnitConverter}'s default dialog font */ public int maximumSize(Container container, List components, FormLayout.Measure minMeasure, FormLayout.Measure prefMeasure, FormLayout.Measure defaultMeasure) { Font font = DefaultUnitConverter.getInstance().getDefaultDialogFont(); FontMetrics fm = container.getFontMetrics(font); return fm.stringWidth(getPrototype()); }
/** * Returns the current {@link UnitConverter}. If it has not been initialized * before it will get an instance of {@link DefaultUnitConverter}. * * @return the current <code>UnitConverter</code> */ public static UnitConverter getUnitConverter() { if (unitConverter == null) { unitConverter = DefaultUnitConverter.getInstance(); } return unitConverter; }
/** * Lazily creates and returns the dialog font used to compute the dialog * base units. * * @return the font used to compute the dialog base units */ public Font getDefaultDialogFont() { if (defaultDialogFont == null) { defaultDialogFont = lookupDefaultDialogFont(); } return defaultDialogFont; }
/** * Computes and returns the horizontal dialog base units. Honors the font, * font size and resolution. * <p> * * Implementation Note: 14dluY map to 22 pixel for 8pt Tahoma on 96 dpi. I * could not yet manage to compute the Microsoft compliant font height. * Therefore this method adds a correction value that seems to work well * with the vast majority of desktops. * <p> * * TODO: revise the computation of vertical base untis, as soon as there are * more information about the original computation in Microsoft * environments. * * @param metrics * the FontMetrics used to measure the dialog font * @return the horizontal and vertical dialog base units */ private DialogBaseUnits computeDialogBaseUnits(FontMetrics metrics) { double averageCharWidth = computeAverageCharWidth(metrics, averageCharWidthTestString); int ascent = metrics.getAscent(); double height = ascent > 14 ? ascent : ascent + (15 - ascent) / 3; DialogBaseUnits dialogBaseUnits = new DialogBaseUnits(averageCharWidth, height); logInfo("Computed dialog base units " + dialogBaseUnits + " for: " + metrics.getFont()); return dialogBaseUnits; }
computeAverageCharWidth(metrics, averageCharWidthTestString); int ascent = metrics.getAscent(); double height = ascent > 14 ? ascent : ascent + (15 - ascent) / 3;
/** * Computes the global dialog base units. The current implementation * assumes a fixed 8pt font and on 96 or 120 dpi. A better implementation * should ask for the main dialog font and should honor the current * screen resolution.<p> * * Should be re-computed if the l&f, platform, or screen changes. * * @return a DialogBaseUnits object used globally if no container is available */ private DialogBaseUnits computeGlobalDialogBaseUnits() { LOGGER.config("Computing global dialog base units..."); Font dialogFont = getDefaultDialogFont(); FontMetrics metrics = createDefaultGlobalComponent().getFontMetrics(dialogFont); DialogBaseUnits globalDialogBaseUnits = computeDialogBaseUnits(metrics); return globalDialogBaseUnits; }
/** * Looks up and returns the dialog base units for the given component. * In case the component is <code>null</code> the global dialog base units * are answered.<p> * * Before we compute the dialog base units we check whether they * have been computed and cached before - for the same component * <code>FontMetrics</code>. * * @param c the component that provides the graphics object * @return the DialogBaseUnits object for the given component */ private DialogBaseUnits getDialogBaseUnits(Component c) { FormUtils.ensureValidCache(); if (c == null) { // || (font = c.getFont()) == null) { // logInfo("Missing font metrics: " + c); return getGlobalDialogBaseUnits(); } FontMetrics fm = c.getFontMetrics(getDefaultDialogFont()); DialogBaseUnits dialogBaseUnits = (DialogBaseUnits) cachedDialogBaseUnits.get(fm); if (dialogBaseUnits == null) { dialogBaseUnits = computeDialogBaseUnits(fm); cachedDialogBaseUnits.put(fm, dialogBaseUnits); } return dialogBaseUnits; }
/** * Computes and returns the width of this Size's prototype in pixel. * Ignores the component list and measures. Obtains the FontMetrics * from the given layout {@code container} for the default dialog font * provided by {@link DefaultUnitConverter#getDefaultDialogFont()}.<p> * * Invoked by {@link com.jgoodies.forms.layout.FormSpec} to determine * the size of a column or row. * * @param container the layout container * @param components the list of components used to compute the size * @param minMeasure the measure that determines the minimum sizes * @param prefMeasure the measure that determines the preferred sizes * @param defaultMeasure the measure that determines the default sizes * * @return the {@code stringWidth} for this size's prototype string * computed by the {@code container}'s FontMetrics for the * {@code DefaultUnitConverter}'s default dialog font */ @Override public int maximumSize(Container container, List components, FormLayout.Measure minMeasure, FormLayout.Measure prefMeasure, FormLayout.Measure defaultMeasure) { Font font = DefaultUnitConverter.getInstance().getDefaultDialogFont(); FontMetrics fm = container.getFontMetrics(font); return fm.stringWidth(getPrototype()); }
/** * Clears cached internal Forms state that is based * on the Look&Feel, for example dialog base units.<p> * * There's typically no need to call this method directly. * It'll be invoked automatically, if the L&F has been changed * via {@link UIManager#setLookAndFeel} and cached data is requested. * It's been made public to allow cache invalidation for cases * where the L&F is changed temporarily by replacing the UIDefaults, * for example in a visual editor. * * @since 1.2.1 */ public static void clearLookAndFeelBasedCaches() { cachedIsLafAqua = null; DefaultUnitConverter.getInstance().clearCache(); }
/** * Returns the current {@link UnitConverter}. If it has not been initialized * before it will get an instance of {@link DefaultUnitConverter}. * * @return the current {@code UnitConverter} */ public static UnitConverter getUnitConverter() { if (unitConverter == null) { unitConverter = DefaultUnitConverter.getInstance(); } return unitConverter; }
/** * Lazily creates and returns a fallback for the dialog font * that is used to compute the dialog base units. * This fallback font is cached and will be reset if the L&F changes. * * @return the cached fallback font used to compute the dialog base units */ private Font getCachedDefaultDialogFont() { FormUtils.ensureValidCache(); if (cachedDefaultDialogFont == null) { cachedDefaultDialogFont = lookupDefaultDialogFont(); } return cachedDefaultDialogFont; }
/** * Computes and returns the horizontal dialog base units. * Honors the font, font size and resolution.<p> * * Implementation Note: 14dluY map to 22 pixel for 8pt Tahoma on 96 dpi. * I could not yet manage to compute the Microsoft compliant font height. * Therefore this method adds a correction value that seems to work * well with the vast majority of desktops.<p> * * TODO: Revise the computation of vertical base units as soon as * there are more information about the original computation * in Microsoft environments. * * @param metrics the FontMetrics used to measure the dialog font * @return the horizontal and vertical dialog base units */ private DialogBaseUnits computeDialogBaseUnits(FontMetrics metrics) { double averageCharWidth = computeAverageCharWidth(metrics, averageCharWidthTestString); int ascent = metrics.getAscent(); double height = ascent > 14 ? ascent : ascent + (15 - ascent) / 3; DialogBaseUnits dialogBaseUnits = new DialogBaseUnits(averageCharWidth, height); LOGGER.config( "Computed dialog base units " + dialogBaseUnits + " for: " + metrics.getFont()); return dialogBaseUnits; }