如何在Swing GTK LookAndFeel中更改默认字体大小?

有没有办法在Swing GTK LaF中更改默认字体大小?

GTK LaF似乎假定为72dpi,所以所有字体只有使用96dpi屏幕时应该是的大小的3/4。 有关详细信息,请参阅此Fedora错误 。 我想在此期间找到一个解决方法,同时我等待修复。

我已经尝试过通过UIDefaults重置字体大小,例如, 这里推荐的,但是(如前所述)GTK LaF似乎忽略了这一点。

可以构建一个小部件工厂,它也可以设置所需的字体大小来创建我的所有Swing小部件,但这将是大规模侵入性的,所以如果有任何其他方式我想避开这条路线。

编辑:以下不起作用:

 public class GTKLaF extends com.sun.java.swing.plaf.gtk.GTKLookAndFeel { @Override public UIDefaults getDefaults() { final float scale = 3f; final UIDefaults defaults = super.getDefaults(); final Map changes = new HashMap(); for (Map.Entry e : defaults.entrySet()) { final Object key = e.getKey(); final Object val = e.getValue(); if (val instanceof FontUIResource) { final FontUIResource ores = (FontUIResource) val; final FontUIResource nres = new FontUIResource(ores.deriveFont(ores.getSize2D()*scale)); changes.put(key, nres); System.out.println(key + " = " + nres); } else if (val instanceof Font) { final Font ofont = (Font) val; final Font nfont = ofont.deriveFont(ofont.getSize2D()*scale); changes.put(key, nfont); System.out.println(key + " = " + nfont); } } defaults.putAll(changes); return defaults; } } 

您可能认为这会打印至少十二个键值对,但它只打印一个:TitledBorder.font。 显然,其他字体属性不是由GTLLookAndFeel提供的,而是来自其他地方!

我的建议是创建自己的GTKLookAndFeel子类并使用它。

在你的子类中,我可能会覆盖getDefaults() 。 在你的getDefaults()你可以获得GTKLookAndFeel将要返回的UIDefaults并在必要时进行调整。 (通过包装或子类化它们并覆盖UIDefaults.getFont方法。)

获取当前的DPI

 int dpi = Toolkit.getDefaultToolkit().getScreenResolution(); 

如果它不是72,你可以相应地改变字体大小。

编辑:您发布的链接不起作用,我相信因为GTKLookAndFeel会覆盖所涉及的方法,并且不允许其祖先的任何默认值通过。 反过来覆盖它应该可以让你避开这个问题。

似乎无法设置默认字体大小。 但是,问题中引用的错误已经修复,所以现在需要这样做是没有实际意义的。

您链接的代码有问题。 UIDefaults.get(key)函数不必返回Font实例。 它可能是一个javax.swing.plaf.FontUIResource实例。 以下代码段找到所有已安装的外观,而不是按比例更改所有字体大小

 float scale=1.1f; UIManager.LookAndFeelInfo looks[] = UIManager.getInstalledLookAndFeels(); for (UIManager.LookAndFeelInfo info : looks) { //if you want to change LaF to a spesific LaF,such as "GTK" //put here a if statement like: //if(info.getClassName().contains("GTK")) UIManager.setLookAndFeel(info.getClassName()); UIDefaults defaults = UIManager.getDefaults(); Enumeration newKeys = defaults.keys(); while (newKeys.hasMoreElements()) { Object obj = newKeys.nextElement(); Object current = UIManager.get(obj); if (current instanceof FontUIResource) { FontUIResource resource = (FontUIResource) current; defaults.put(obj, new FontUIResource(resource.deriveFont(resource.getSize2D()*scale))); // System.out.printf("%50s : %s\n", obj, UIManager.get(obj)); } else if (current instanceof Font) { Font resource = (Font) current; defaults.put(obj, resource.deriveFont(resource.getSize2D()*scale)); // System.out.printf("%50s : %s\n", obj, UIManager.get(obj)); } } } 

我找到了一本关于GTK LaF问题的书,一本书,第三版的Java例子。 看看这里

我失去了很多时间来弄清楚如何让我们的应用程序在ubuntu上体面,我来到了这个黑客。 我试过像某人建议扩展GTKLookAndFeel,但因为它使用了许多对GTKEngine的本地调用,我意识到它不可行。 我希望这有帮助

在设置外观之后调用我的hack checkGTKLookAndFeel()它会降低两点的字体标准:

 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); try { InvoicexUtil.checkGTKLookAndFeel(); } catch (Exception e) { e.printStackTrace(); } public static void checkGTKLookAndFeel() throws Exception { LookAndFeel look = UIManager.getLookAndFeel(); if (!look.getID().equals("GTK")) return; new JFrame(); new JButton(); new JComboBox(); new JRadioButton(); new JCheckBox(); new JTextArea(); new JTextField(); new JTable(); new JToggleButton(); new JSpinner(); new JSlider(); new JTabbedPane(); new JMenu(); new JMenuBar(); new JMenuItem(); Object styleFactory; Field styleFactoryField = look.getClass().getDeclaredField("styleFactory"); styleFactoryField.setAccessible(true); styleFactory = styleFactoryField.get(look); Field defaultFontField = styleFactory.getClass().getDeclaredField("defaultFont"); defaultFontField.setAccessible(true); Font defaultFont = (Font) defaultFontField.get(styleFactory); FontUIResource newFontUI; newFontUI = new FontUIResource(defaultFont.deriveFont((float)(defaultFont.getSize() - 2f))); defaultFontField.set(styleFactory, newFontUI); Field stylesCacheField = styleFactory.getClass().getDeclaredField("stylesCache"); stylesCacheField.setAccessible(true); Object stylesCache = stylesCacheField.get(styleFactory); Map stylesMap = (Map) stylesCache; for (Object mo : stylesMap.values()) { Field f = mo.getClass().getDeclaredField("font"); f.setAccessible(true); Font fo = (Font)f.get(mo); f.set(mo, fo.deriveFont((float)(fo.getSize() - 2f))); } } 

调用各种swing组件构造函数来初始化GTK样式。 不是很优雅,但它的工作原理

Interesting Posts