我指的是这个 Nimbus 参考资料。
我尝试将全局字体设置得稍大一些:
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));
但这不是一个选项,因为必须对 each 执行此操作 手动元素。
注意,为 UIManager 派生字体不起作用:
UIManager.put("Label.font",
UIManager.getFont("Label.font").deriveFont(16f));
我在 Linux 和 Windows 下测试了所有内容:相同的行为。
我就是无法理解 API 怎么会这么混乱。如果调用一个方法 setFont(..) 然后我希望它设置字体。如果此方法失败 在任何可以想到的情况下设置字体,那么它应该被弃用。
编辑:
该问题不仅适用于 Nimbus,也适用于默认的 LAF。
这适用于 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 初始化默认值,然后设置默认值:
NimbusLookAndFeel laf = new NimbusLookAndFeel();
UIManager.setLookAndFeel(laf);
laf.getDefaults().put("defaultFont", new Font("Monospaced", Font.BOLD, 12));
注意:如上所述,此代码比重写 getDefaults() 更有效。
UIManager.getLookAndFeelDefaults().put("defaultFont", new Font(Font.SANS_SERIF, 0, 20));
请注意,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);
}
});
}
}
这是有效的,因为 Metal 上存在属性“Label.font”并且它正确地使用了该属性。
你可以这样检查:
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);
}
});
}
}
NimbusLookAndFeel nimbus = new NimbusLookAndFeel();
UIManager.setLookAndFeel(nimbus);
nimbus.getDefaults().put("internationalFont",
new Font(Font.SANS_SERIF, Font.PLAIN, 22));
这里我只是选择了名称“internationalFont”。你可以自己起名字。