繁体   English   中英

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

[英]How to change the default font size in the 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<Object,Object> changes = new HashMap<Object,Object>();

    for (Map.Entry<Object,Object> 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会覆盖所涉及的方法,并且不会让其祖先的任何默认值通过。 反过来覆盖它应该可以让你绕过这个问题。

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

我失去了很多时间来弄清楚如何让我们的应用程序在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样式。 不是很优雅,但它的工作原理

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

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例子,第三版。 看看这里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM