错误或功能:Swing 默认 GUI 字体对于 Win6+ 不正确

2022-09-02 22:37:07

只是(令人惊讶;-)注意到应用程序在我的win6 +机器上看起来如此局促的原因(Vista和Win7相同,都具有120dpi设置,jdk6和jdk7):从桌面属性查找的控件字体既有错误的字体系列,也有错误的大小:

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);
}

输出:

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] 

后者在几乎所有文本的本机应用程序中使用,而Swing使用前者...

问题:

  • 这可能有什么原因吗,或者只是一个错误?
  • 谁负责:Swing 查找(从相关系统资源读取桌面属性时)或操作系统未正确报告?
  • 如何强制使用后者?

解决最后一个问题的选项:

  • 通过对LAF的完全控制,可以考虑设置所有相关的文本字体(这就是JGoodies所做的,并考虑在FontPolicy/Set中)。
  • 一个肮脏的黑客是将 defaultGUI 桌面属性的值设置为正确的值 - 它涉及对工具包的反射访问,这自然会在安全受限的上下文中受到打击。
  • ??

编辑

为了以防万一有人感兴趣,这是肮脏的黑客:

/**
 * 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());
    }

}

编辑 2

只是为了澄清:黑客攻击仅对WindowsLAF完全有效。Nimbus完全忽略了系统设置,Metal部分:后者的字体始终是Dialog,只有大小取自桌面属性。听起来不错,但事实并非如此:对于主字体来说,映射相当奇怪,f.i.大量使用的controlFont大小设置为“win.ansiVar.font.height”(那是什么化石剩余?),在我的机器上是13...

编辑 3

即使在Windows UI中,黑客也是...一个有局限性的黑客,@Walter的评论中提到的那些:

当您缩放 Windows UI 时,此错误尤其明显。仅供参考,打开JFileChooser会恢复黑客攻击。此外,JTree/JTable行高不会自动更新为新的字体大小,您还需要缩放图标


答案 1

我认为这不是一个错误,而是Win7的基本属性,built_in主题,有趣的字体大小,我仍然使用较小的字体(操作系统安装的默认设置)

例如,如果我设置/切换

1.Windows7 基本主题

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 经典主题

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.窗口XP修改主题

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 经典主题

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]

答案 2

推荐