kleopatra
kleopatra

Reputation: 51536

Bug or feature: Swing default gui font incorrect for Win6+

just (astonishingly ;-) noticed the reason why apps look so cramped on my win6+ machines (same for Vista and Win7, both with 120dpi setting, jdk6 and jdk7): the control font looked up from the the desktop property has both the wrong font family and the wrong size:

public static void main(String[] args) {
    Font guiFont = (Font) Toolkit.getDefaultToolkit().getDesktopProperty("win.defaultGUI.font");
    int guiSize = guiFont.getSize();
    Font iconFont = (Font) Toolkit.getDefaultToolkit().getDesktopProperty("win.icon.font");
    System.out.println("gui default: " + guiFont + "\nicon default: " + iconFont);
}

output:

gui default: java.awt.Font[family=Tahoma,name=Tahoma,style=plain,size=13]
icon default: java.awt.Font[family=Segoe UI,name=Segoe UI,style=plain,size=15] 

The latter is used in native applications for nearly all text, while Swing uses the former ...

Questions:

Options for solving the last:

Edit

Just in case anybody is interested, here's the dirty hack:

/**
 * Replaces the default gui desktop font property with the icon font
 * if the former is smaller.
 * 
 */
public static void ensureDefaultGUIFontSize() {
    Toolkit toolkit = Toolkit.getDefaultToolkit();
    Font guiFont = (Font) toolkit.getDesktopProperty("win.defaultGUI.font");
    Font iconFont = (Font) toolkit.getDesktopProperty("win.icon.font");
    if (guiFont.getSize() < iconFont.getSize()) {
        invokeDeclaredMethod("setDesktopProperty", Toolkit.class, 
            toolkit, "win.defaultGUI.font", iconFont);
    }
}

private static void invokeDeclaredMethod(String methodName,
        Class<?> clazz, Object instance, String propertyName,
        Object propertyValue) {
    try {
        Method method = clazz.getDeclaredMethod(methodName, String.class, Object.class);
        method.setAccessible(true);
        method.invoke(instance, propertyName, propertyValue);
    } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        LOG.finer("forcing desktop property failed " + e.getStackTrace());
    }

}

Edit 2

Just to clarify: the hack is fully effective only for WindowsLAF. Nimbus ignores system settings completely, Metal partly: the latter's font is always Dialog, only size is taken from desktopProperties. Sounds half-way good, but isn't: the mapping is rather weird for the main fonts, f.i. the heavily used controlFont size is set to "win.ansiVar.font.height" (what fossil leftover is that?) which is 13 on my machine ...

Edit 3

Even in windows ui, the hack is ... a hack with limitations, f.i. those mentioned in @Walter's comment:

This bug is especially noticeable when you scale the Windows UI. FYI, opening a JFileChooser reverts the hack. Also JTree/JTable row height will not be automatically updated to the new font size and you'll need to scale your icons as well

Upvotes: 18

Views: 2704

Answers (1)

mKorbel
mKorbel

Reputation: 109823

I think that isn't a bug but basic property of Win7 and built_in themes, interesting size of Font, I still use smaller Fonts (default setting from OS instalation)

for example if I set / switch

1.Windows7 Basic theme

gui default: java.awt.Font[family=Tahoma,name=Tahoma,style=plain,size=11]
icon default: java.awt.Font[family=Segoe UI,name=Segoe UI,style=plain,size=12]

2.Windows7 Classic theme

gui default: java.awt.Font[family=Tahoma,name=Tahoma,style=plain,size=11]
icon default: java.awt.Font[family=Tahoma,name=Tahoma,style=plain,size=11]

don't touched the Font property, will be continue for from WinXP

3.WindowXP modified theme

gui default: java.awt.Font[family=Tahoma,name=Tahoma,style=plain,size=11]
icon default: java.awt.Font[family=Tahoma,name=Tahoma,style=plain,size=13]

4.Windows7 Classic theme

gui default: java.awt.Font[family=Tahoma,name=Tahoma,style=plain,size=11]
icon default: java.awt.Font[family=Tahoma,name=Tahoma,style=plain,size=11]

Upvotes: 5

Related Questions