From 930c1fedb44757e3b5d4139ba36d6575ee7dff22 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 29 Mar 2012 12:18:06 +0200 Subject: [PATCH] Platform-independent detection of default UI font --- .../src/com/intellij/ide/ui/UISettings.java | 136 ++++++++---------- .../com/intellij/ide/ui/LafManagerImpl.java | 18 +-- .../com/intellij/util/SystemProperties.java | 17 +++ .../util/src/com/intellij/util/ui/UIUtil.java | 18 ++- 4 files changed, 99 insertions(+), 90 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ide/ui/UISettings.java b/platform/platform-api/src/com/intellij/ide/ui/UISettings.java index f4175389bee6..705df1ef8530 100644 --- a/platform/platform-api/src/com/intellij/ide/ui/UISettings.java +++ b/platform/platform-api/src/com/intellij/ide/ui/UISettings.java @@ -26,8 +26,11 @@ import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.SystemInfo; import com.intellij.util.PlatformUtils; +import com.intellij.util.SystemProperties; +import com.intellij.util.ui.UIUtil; import com.intellij.util.xmlb.Accessor; import com.intellij.util.xmlb.SerializationFilter; import com.intellij.util.xmlb.XmlSerializerUtil; @@ -107,19 +110,15 @@ public class UISettings implements PersistentStateComponent, Exporta */ public static final int TABS_NONE = 0; - /** - * Invoked by reflection. - */ public UISettings() { - tweakPlatformDefaults(); myListenerList = new EventListenerList(); + tweakPlatformDefaults(); setSystemFontFaceAndSize(); } private void tweakPlatformDefaults() { // TODO: Make it pluggable if (PlatformUtils.isCidr()) { - //HIDE_TOOL_STRIPES = true; SHOW_MAIN_TOOLBAR = false; SHOW_ICONS_IN_MENUS = false; SHOW_MEMORY_INDICATOR = false; @@ -133,7 +132,7 @@ public class UISettings implements PersistentStateComponent, Exporta myListenerList.add(UISettingsListener.class, listener); } - public void addUISettingsListener(@NotNull final UISettingsListener listener, @NotNull Disposable parentDisposable){ + public void addUISettingsListener(@NotNull final UISettingsListener listener, @NotNull Disposable parentDisposable) { myListenerList.add(UISettingsListener.class,listener); Disposer.register(parentDisposable, new Disposable() { @Override @@ -146,7 +145,7 @@ public class UISettings implements PersistentStateComponent, Exporta /** * Notifies all registered listeners that UI settings has been changed. */ - public void fireUISettingsChanged(){ + public void fireUISettingsChanged() { UISettingsListener[] listeners= myListenerList.getListeners(UISettingsListener.class); for (UISettingsListener listener : listeners) { listener.uiSettingsChanged(this); @@ -166,29 +165,18 @@ public class UISettings implements PersistentStateComponent, Exporta return application != null ? getInstance() : new UISettings(); } - public void removeUISettingsListener(UISettingsListener listener){ + public void removeUISettingsListener(UISettingsListener listener) { myListenerList.remove(UISettingsListener.class,listener); } - private void setDefaultFontSettings() { - final Application application = ApplicationManager.getApplication(); - if (application == null) { - // we're the shadow settings - return; - } - FONT_FACE = SystemInfo.isLinux && application.isUnitTestMode() ? "Dialog.plain" : "Dialog"; - FONT_SIZE = 12; - } - - private static boolean isValidFont(final Font font){ + private static boolean isValidFont(final Font font) { try { - return - font.canDisplay('a') && - font.canDisplay('z') && - font.canDisplay('A') && - font.canDisplay('Z') && - font.canDisplay('0') && - font.canDisplay('1'); + return font.canDisplay('a') && + font.canDisplay('z') && + font.canDisplay('A') && + font.canDisplay('Z') && + font.canDisplay('0') && + font.canDisplay('1'); } catch (Exception e) { // JRE has problems working with the font. Just skip. @@ -196,30 +184,41 @@ public class UISettings implements PersistentStateComponent, Exporta } } - /** - * Under Win32 it's possible to determine face and size of default fount. - */ - private void setSystemFontFaceAndSize(){ - if(FONT_FACE == null || FONT_SIZE <= 0){ - if(SystemInfo.isWindows){ - //noinspection HardCodedStringLiteral - Font font=(Font)Toolkit.getDefaultToolkit().getDesktopProperty("win.messagebox.font"); - if(font != null){ - FONT_FACE = font.getName(); - FONT_SIZE = font.getSize(); - }else{ - setDefaultFontSettings(); - } - }else{ // UNIXes go here - setDefaultFontSettings(); + private void setSystemFontFaceAndSize() { + if (FONT_FACE == null || FONT_SIZE <= 0) { + final Pair fontData = getSystemFontFaceAndSize(); + FONT_FACE = fontData.first; + FONT_SIZE = fontData.second; + } + } + + private static Pair getSystemFontFaceAndSize() { + final Pair fontData = UIUtil.getSystemFontData(); + if (fontData != null) { + return fontData; + } + + if (SystemInfo.isWindows) { + //noinspection HardCodedStringLiteral + final Font font = (Font)Toolkit.getDefaultToolkit().getDesktopProperty("win.messagebox.font"); + if (font != null) { + return Pair.create(font.getName(), font.getSize()); } } + + return Pair.create("Dialog", 12); + } + + public static class FontFilter implements SerializationFilter { + public boolean accepts(Accessor accessor, Object bean) { + UISettings settings = (UISettings)bean; + return !hasDefaultFontSetting(settings); + } } private static boolean hasDefaultFontSetting(final UISettings settings) { - Font font=(Font)Toolkit.getDefaultToolkit().getDesktopProperty("win.messagebox.font"); - return SystemInfo.isWindows && font != null && settings.FONT_FACE.equals(font.getName()) && settings.FONT_SIZE == font.getSize(); - + final Pair fontData = getSystemFontFaceAndSize(); + return fontData.first.equals(settings.FONT_FACE) && fontData.second.equals(settings.FONT_SIZE); } public UISettings getState() { @@ -230,28 +229,27 @@ public class UISettings implements PersistentStateComponent, Exporta XmlSerializerUtil.copyBean(object, this); // Check tab placement in editor - if( - EDITOR_TAB_PLACEMENT != TABS_NONE && - EDITOR_TAB_PLACEMENT != SwingConstants.TOP&& - EDITOR_TAB_PLACEMENT != SwingConstants.LEFT&& - EDITOR_TAB_PLACEMENT != SwingConstants.BOTTOM&& - EDITOR_TAB_PLACEMENT != SwingConstants.RIGHT - ){ - EDITOR_TAB_PLACEMENT=SwingConstants.TOP; + if (EDITOR_TAB_PLACEMENT != TABS_NONE && + EDITOR_TAB_PLACEMENT != SwingConstants.TOP && + EDITOR_TAB_PLACEMENT != SwingConstants.LEFT && + EDITOR_TAB_PLACEMENT != SwingConstants.BOTTOM && + EDITOR_TAB_PLACEMENT != SwingConstants.RIGHT) { + EDITOR_TAB_PLACEMENT = SwingConstants.TOP; } - // Check that alpha ration in in valid range - if(ALPHA_MODE_DELAY<0){ - ALPHA_MODE_DELAY=1500; + + // Check that alpha delay and ratio are valid + if (ALPHA_MODE_DELAY < 0) { + ALPHA_MODE_DELAY = 1500; } - if(ALPHA_MODE_RATIO< 0.0f ||ALPHA_MODE_RATIO>1.0f){ - ALPHA_MODE_RATIO=0.5f; + if (ALPHA_MODE_RATIO < 0.0f || ALPHA_MODE_RATIO > 1.0f) { + ALPHA_MODE_RATIO = 0.5f; } setSystemFontFaceAndSize(); - // 1. Sometimes system font cannot display standard ASCI symbols. If so we have + // 1. Sometimes system font cannot display standard ASCII symbols. If so we have // find any other suitable font withing "preferred" fonts first. boolean fontIsValid = isValidFont(new Font(FONT_FACE, Font.PLAIN, FONT_SIZE)); - if(!fontIsValid){ + if (!fontIsValid) { @NonNls final String[] preferredFonts = {"dialog", "Arial", "Tahoma"}; for (String preferredFont : preferredFonts) { if (isValidFont(new Font(preferredFont, Font.PLAIN, FONT_SIZE))) { @@ -263,7 +261,7 @@ public class UISettings implements PersistentStateComponent, Exporta // 2. If all preferred fonts are not valid in current environment // we have to find first valid font (if any) - if(!fontIsValid){ + if (!fontIsValid) { Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); for (Font font : fonts) { if (isValidFont(font)) { @@ -278,23 +276,13 @@ public class UISettings implements PersistentStateComponent, Exporta MAX_CLIPBOARD_CONTENTS = 5; } - fireUISettingsChanged(); } - public static class FontFilter implements SerializationFilter { - public boolean accepts(Accessor accessor, Object bean) { - UISettings settings = (UISettings)bean; - - return !hasDefaultFontSetting(settings); - } - - } - - private static final boolean DONT_TOUCH_ALIASING = "true".equalsIgnoreCase(System.getProperty("idea.use.default.antialiasing.in.editor")); + private static final boolean DEFAULT_ALIASING = SystemProperties.getBooleanProperty("idea.use.default.antialiasing.in.editor", false); public static void setupAntialiasing(final Graphics g) { - if (DONT_TOUCH_ALIASING) return; + if (DEFAULT_ALIASING) return; Graphics2D g2d=(Graphics2D)g; UISettings uiSettings=getInstance(); @@ -350,10 +338,8 @@ public class UISettings implements PersistentStateComponent, Exporta } public void initComponent() { - } public void disposeComponent() { - } } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java index 67cbb85de98b..2b29ce9e87ab 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java @@ -661,19 +661,19 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo defaults.put("Tree.ancestorInputMap", null); int uiFontSize = myUiSettings.FONT_SIZE; String uiFontFace = myUiSettings.FONT_FACE; - FontUIResource font = new FontUIResource(uiFontFace, Font.PLAIN, uiFontSize); - FontUIResource font1 = new FontUIResource("Serif", Font.PLAIN, uiFontSize); - FontUIResource font3 = new FontUIResource("Monospaced", Font.PLAIN, uiFontSize); + FontUIResource uiFont = new FontUIResource(uiFontFace, Font.PLAIN, uiFontSize); + FontUIResource textFont = new FontUIResource("Serif", Font.PLAIN, uiFontSize); + FontUIResource monoFont = new FontUIResource("Monospaced", Font.PLAIN, uiFontSize); for (String fontResource : ourPatchableFontResources) { - defaults.put(fontResource, font); + defaults.put(fontResource, uiFont); } - defaults.put("PasswordField.font", font3); - defaults.put("TextArea.font", font3); - defaults.put("TextPane.font", font1); - defaults.put("EditorPane.font", font1); - defaults.put("TitledBorder.font", font); + defaults.put("PasswordField.font", monoFont); + defaults.put("TextArea.font", monoFont); + defaults.put("TextPane.font", textFont); + defaults.put("EditorPane.font", textFont); + defaults.put("TitledBorder.font", uiFont); } diff --git a/platform/util/src/com/intellij/util/SystemProperties.java b/platform/util/src/com/intellij/util/SystemProperties.java index 6f7750c5d982..6a0bbdfa5e8c 100644 --- a/platform/util/src/com/intellij/util/SystemProperties.java +++ b/platform/util/src/com/intellij/util/SystemProperties.java @@ -110,4 +110,21 @@ public class SystemProperties { return defaultValue; } + + /** + * Returns the value of given property as a boolean. + * Returns {@code defaultValue} if property is not specified or malformed. + * + * @param key the property name + * @param defaultValue default value + * @return the property value as integer, or default value. + */ + public static boolean getBooleanProperty(@NotNull final String key, final boolean defaultValue) { + final String value = System.getProperty(key); + if (value != null) { + return Boolean.parseBoolean(value); + } + + return defaultValue; + } } diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index 002432d18d20..ce17aba15305 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -70,7 +70,6 @@ import java.util.regex.Pattern; */ @SuppressWarnings("StaticMethodOnlyUsedInOneClass") public class UIUtil { - private static final String TABLE_DECORATION_KEY = "TABLE_DECORATION_KEY"; private static final Color DECORATED_ROW_BG_COLOR = new Color(242, 245, 249); @@ -136,6 +135,8 @@ public class UIUtil { // accessed only from EDT private static final HashMap ourAppleDotSamples = new HashMap(); + private static volatile Pair ourSystemFontData = null; + @NonNls private static final String ROOT_PANE = "JRootPane.future"; private UIUtil() { } @@ -1745,18 +1746,23 @@ public class UIUtil { } } - /** @deprecated use {@linkplain #initDefaultLAF()} (to remove in IDEA 12) */ - public static void initDefaultLAF(final String productName) { - initDefaultLAF(); - } - public static void initDefaultLAF() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + + if (ourSystemFontData == null) { + final Font font = getLabelFont(); + ourSystemFontData = Pair.create(font.getName(), font.getSize()); + } } catch (Exception ignored) { } } + @Nullable + public static Pair getSystemFontData() { + return ourSystemFontData; + } + public static void addKeyboardShortcut(final JComponent target, final AbstractButton button, final KeyStroke keyStroke) { target.registerKeyboardAction( new ActionListener() {