Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • 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

like image 464
kleopatra Avatar asked Jul 03 '12 11:07

kleopatra


People also ask

What is the default font in Java Swing?

That code is written in Scala, but as you can see, it converts easily to Java. On Mac OS X 10.10, fontFamily ends up being “Lucida Grande”.

How do I change the font in swing?

To set the font for a Swing component, use its setFont() method of the component. JButton closeButton = new JButton("Close"); closeButton. setFont(f4);


1 Answers

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]
like image 173
mKorbel Avatar answered Oct 17 '22 07:10

mKorbel