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

1

18

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:

  • Could there be any reason for this, or just a bug?
  • Who's responsible: the Swing lookup (when reading-in the desktopProperty from relevant system resources) or the OS in not reporting it correctly?
  • How to force the usage of the latter?

Options for solving the last:

  • With full control about the LAF one might consider to set all relevant text fonts (that's what JGoodies does, factored into a FontPolicy/Set).
  • A dirty hack is to set the value of the defaultGUI desktop property to the correct value - it involves reflective access to the toolkit, which naturally will blow in security constrained contexts.
  • ??

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

Estus answered 3/7, 2012 at 11:22 Comment(7)
bugs.sun.com/bugdatabase/view_bug.do?bug_id=4950968 - guess the workaround doesn't work with the new WindowsMcdaniels
@WalterLaan hmm ... shouldn't that old workaround be replaced for ages, it was even before the MS Sans vs. Tahoma bug: bugs.sun.com/bugdatabase/view_bug.do?bug_id=5079742. The most recent I could find is bugs.sun.com/bugdatabase/view_bug.do?bug_id=6436509 which is closed as not reproducible (true, as the 0/null is gone but now doesn't return the correct value ...)Estus
Suggestion to switch to OS X instead of Windows is probably not helpful :-)Muster
My idea for the last question would be to try and see if changing the values in the UIManager defaults works. This is more of a vague hunch than anything else though, I just seem to recall that's where the control implementations ultimately read default values from, not a bunch of per-LAF properties.Scaffold
@Scaffold thanks for the suggestion: setting the fonts in UIManager definitely would work - the drawback is that we need intimate knowledge which components' fonts are based on defaultGUI. Fine for core, tricky for third-party components.Estus
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 @Estus did you file a official bug?Mcdaniels
@WalterLaan thanks for the warning! no didn't, my internal channels dried up ... and the normal route is ... unusable.Estus
B
5

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]
Begum answered 3/7, 2012 at 21:32 Comment(1)
thanks for testing :-) For the all non-classic themes the default native font is SegoeUI, IMO (see the UXGuide, pdf version at microsoft.com/en-us/download/details.aspx?id=2695) Which in fact is showing when I compare text in native apps against Swing text forced to Segoe.Estus

© 2022 - 2024 — McMap. All rights reserved.