Platform-independent detection of default UI font

This commit is contained in:
Roman Shevchenko
2012-03-29 12:18:59 +02:00
parent 0700053f70
commit 930c1fedb4
4 changed files with 99 additions and 90 deletions
@@ -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<UISettings>, 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<UISettings>, 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<UISettings>, 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<UISettings>, 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<UISettings>, 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<String, Integer> fontData = getSystemFontFaceAndSize();
FONT_FACE = fontData.first;
FONT_SIZE = fontData.second;
}
}
private static Pair<String, Integer> getSystemFontFaceAndSize() {
final Pair<String,Integer> 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<String, Integer> 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<UISettings>, 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<UISettings>, 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<UISettings>, 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<UISettings>, Exporta
}
public void initComponent() {
}
public void disposeComponent() {
}
}
@@ -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);
}
@@ -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;
}
}
@@ -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<Color, BufferedImage> ourAppleDotSamples = new HashMap<Color, BufferedImage>();
private static volatile Pair<String, Integer> 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<String, Integer> getSystemFontData() {
return ourSystemFontData;
}
public static void addKeyboardShortcut(final JComponent target, final AbstractButton button, final KeyStroke keyStroke) {
target.registerKeyboardAction(
new ActionListener() {