【问题标题】:Java: Altering UI fonts (Nimbus) doesn't work!Java:更改 UI 字体 (Nimbus) 不起作用!
【发布时间】:2010-10-31 06:21:48
【问题描述】:

我指的是this Nimbus reference

我尝试将全局字体设置为稍大:

UIManager.put("defaultFont", new Font(Font.SANS_SERIF, 0, 16));

...仅适用于菜单,但没有其他(按钮、标签)。

我尝试用

更改标签和按钮字体
UIManager.put("Button.font", new Font(Font.SANS_SERIF, 0, 16));
UIManager.put("Label.font", new Font(Font.SANS_SERIF, 0, 16));

但字体保留

唯一对我有用的是派生字体:

someButton.setFont(someButton.getFont().deriveFont(16f));

但这不是一个选项,因为必须为 每个 手动元素。

注意,为 UIManager 派生字体也不起作用

UIManager.put("Label.font",
    UIManager.getFont("Label.font").deriveFont(16f));

我在 Linux 和 Windows 下测试了所有内容:行为相同。

我只是无法理解 API 怎么会如此混乱。如果调用了一个方法 setFont(..) 然后 我希望它 设置字体。如果此方法失败 在任何可能的情况下设置字体,那么它应该被弃用。

编辑:
这个问题不仅适用于 Nimbus,也适用于默认的 LAF。

【问题讨论】:

  • 您是否尝试在更新 UI 默认值后调用 SwingUtilities.updateComponentTreeUI(frame);
  • 该代码甚至无法编译;没有将浮点数作为第三个参数的 Font 构造函数。
  • 该代码是不需要编译的示例代码;)在实际代码中,我使用了静态变量,当我删除它们以执行此示例时,我正在查看deriveFont(. .) 需要浮动。
  • SwingUtilities.updateComponentTreeUI(frame) 也无济于事
  • 实际上 Nimbus 具有“Label.font”属性,但当用户定义自定义值时它不起作用。这可能是另一个 Nimbus/Synth 错误。在此之前我遇到过类似的问题,这就是为什么我选择 Metal/Basic 具有自定义 LAF 的基础。

标签: java swing user-interface fonts nimbus


【解决方案1】:

一行代码的答案(假设你已经设置了 Nimbus LaF):

UIManager.getLookAndFeelDefaults().put("defaultFont", new Font(Font.SANS_SERIF, 0, 20));

当然,您需要在创建任何 GUI 组件之前调用它,即在设置 Nimbus LaF 之后就在您的 main 中。

【讨论】:

    【解决方案2】:

    nimbus 默认值是惰性创建的,因此在绘制屏幕之前设置 'defaultFont' 会将字体添加到父级默认值,而不是 nimbus 默认值。

    解决方法:强制 nimbus 初始化默认值,然后设置默认值:

    NimbusLookAndFeel laf = new NimbusLookAndFeel();
    UIManager.setLookAndFeel(laf);
    laf.getDefaults().put("defaultFont", new Font("Monospaced", Font.BOLD, 12));
    

    注意:此代码比上面建议的覆盖 getDefaults() 更有效。

    【讨论】:

      【解决方案3】:

      适用于 JDK6 和 JDK7。 复制+粘贴,玩得开心;)

      注意:对于 JDK6,请将
      javax.swing.plaf.nimbus 更改为
      com.​sun.​java.​swing.​plaf.​nimbus

      代码

      import java.awt.*;
      import java.lang.reflect.*;
      import javax.swing.*;
      import javax.swing.plaf.nimbus.*;
      
      public class Main {
      
       public static void main(String[] args)
         throws InterruptedException, InvocationTargetException {
      
        SwingUtilities.invokeAndWait(new Runnable() {
      
         @Override
         public void run() {
          try {
           UIManager.setLookAndFeel(new NimbusLookAndFeel() {
      
            @Override
            public UIDefaults getDefaults() {
             UIDefaults ret = super.getDefaults();
             ret.put("defaultFont",
               new Font(Font.MONOSPACED, Font.BOLD, 16)); // supersize me
             return ret;
            }
      
           });
      
           new JFrame("Hello") {
      
            {
             setDefaultCloseOperation(EXIT_ON_CLOSE);
             setLayout(new FlowLayout(FlowLayout.LEFT));
      
             setSize(500, 500);
             setLocationRelativeTo(null);
      
             add(new JLabel("someLabel 1"));
             add(new JButton("someButton 1"));
             add(new JLabel("someLabel 2"));
             add(new JButton("someButton 2"));
      
             setVisible(true);
            }
      
           };     
          } catch (Exception ex) {
           throw new Error(ex);
          }
         }
      
        });
       }
      
      }
      

      【讨论】:

      • 谢谢,在我发现的所有提示中,这是唯一能解决 Nimbus 错误的提示。
      【解决方案4】:

      Java LAF API 有点笨拙,但没有什么比检查源代码来获得答案更好的了。

      请注意,MetalLookAndFeel 和 Nimbus 是不同的实现,每个的属性不必相同。

      以下示例使用 MetalLookAndFeel。

      package com.stackoverflow.laf.font;
      
      import java.awt.Font;
      
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.SwingUtilities;
      import javax.swing.UIManager;
      
      public class SetFontExample {
      
        public static void main(String[] args) {
      
          SwingUtilities.invokeLater(new Runnable() {
            @Override public void run() {
              UIManager.put("Label.font", new Font(Font.SANS_SERIF, 0, 20));
              try {
                UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
              } catch (Exception e) {
                e.printStackTrace();
              }
      
              JFrame frame = new JFrame("Set font example");
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.add(new JLabel("Font test"));
              frame.pack();
              frame.setVisible(true);
            }
          });
        }
      }
      

      这是因为“Label.font”属性存在于 Metal 上并且它正确使用了该属性。

      你可以这样检查:

      package com.stackoverflow.laf;
      
      import javax.swing.SwingUtilities;
      import javax.swing.UIDefaults;
      import javax.swing.UIManager;
      
      public class ListLAFUIDefaults {
      
        public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
            @Override public void run() {
              try {
                // Choose LAF
                UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
              } catch (Exception e) {
                e.printStackTrace();
              }
              UIDefaults defaults = UIManager.getLookAndFeel().getDefaults();
              System.out.println(defaults);
      
              // Check a property
              String propertyKey = "defaultFont";
              System.out.println(UIManager.getLookAndFeel().getName() +
                  (defaults.containsKey(propertyKey) ? " contains " : " doesn't contain ") +
                  "property " + propertyKey);
            }
          });
        }
      }
      

      【讨论】:

      • 注意:因为我在通过执行 UIManager.put("Label.font", UIManager.getFont("Label.font").deriveFont(16f));必须有这样的属性“Label.font”。
      • 确实,您的示例有效!但只要我不使用 Nimbus UI 而不是跨平台 LAF。
      • 这是一个 Nimbus 错误。请查看jasperpotts.com/blog/2008/08/nimbus-uimanager-uidefaults/…
      【解决方案5】:

      FontUIResource 包裹你的字体。 UIManager 颜色和 ColorUIResource 解决了所有问题,我遇到了完全相同的问题。在不深入研究 JDK 的情况下,我认为组件在某些地方期望(阅读:通过 instanceof 检查)UIResources(也许有人可以确认这一点)

      【讨论】:

      • 嗯,值得一试。如果您想更改颜色,请记住这一点。
      • 使用 UIManager.put("nimbusBase", new Color(someColor));
      【解决方案6】:

      至今令我惊讶的一件事是 LaF 设置器 [setFont、setBackground 等] 实际上并没有设置真正的属性。规范说 LaF 可以忽略用户设置的字体、颜色等。这就是 GTKLaF 完全被破坏的原因。它使用系统 gtk 主题设置,而不是程序员的设置。 IIRC Nimbus 有一个单独的包私有类,其中包含默认值(NimbusDefaults?)并且不容易访问。

      如果您打算以任何方式自定义外观,我建议不要使用 GTK 或 Nimbus LAF。

      一个快速的谷歌搜索出现this GTK

      关于 nimbus 中这些问题的讨论可以找到here

      【讨论】:

      • 好吧,设置这些属性实际上对我有用!我引用我的问题:唯一对我有用的是派生字体: someButton.setFont(someButton.getFont().deriveFont(16f));
      • 但是做 someComponent.setFont(..) 不是一种选择,因为这样,我必须为每个组件都这样做! == 复制和粘贴代码。
      猜你喜欢
      • 2014-02-02
      • 2012-07-31
      • 1970-01-01
      • 2018-09-10
      • 1970-01-01
      • 2016-01-02
      • 2018-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多