我是 Java Nimbus 外观和感觉 的新手。我正在尝试使用 Nimbus 的功能来自定义单个组件实例,使用 putClientProperty("Nimbus.Overrides", overrides)
: https://docs.oracle.com/javase/8/docs/api/javax/swing/plaf/nimbus/package-summary.html
我遇到了以下问题(错误?):
不幸的是,“Nimbus.Overrides”值显然不仅会影响其明确设置的组件对象,还会影响其他对象。
似乎自定义属性以某种方式“继承”到相同类型的其他(后来“样式化”,显然不是以前)实例。我需要确保只对一个单独的实例进行更改(不影响任何其他对象)。示例 - JButton
使用过,但遇到了与例如相同的问题JTabbedPane
和定制画家:
-
button 1
- 自定义属性 A(内容边距)。 -
button 2
- 仅属性 B(字体)自定义 - 但属性 A 的更改也可见(更大的 manrgins),“以某种方式继承”自button 1
. -
button 3
- 没有自定义属性(使用空属性映射) - 两个更改 (A+B) 似乎都是从button1
继承的(更大的边距,更大的字体)和button2
button 4
- 默认外观 o JButton(无自定义)import java.awt.FlowLayout; import java.awt.Font; import java.awt.Insets; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.UIDefaults; public class NimbusPerComponentTest extends JFrame { public NimbusPerComponentTest() { super("Test"); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setLayout(new FlowLayout()); // 4 buttons to test JButton button1 = new JButton("Button 1"); JButton button2 = new JButton("Button 2"); JButton button3 = new JButton("Button 3"); JButton button4 = new JButton("Button 4"); add(button1); add(button2); add(button3); add(button4); pack(); // style // button 1 UIDefaults overrides1 = new UIDefaults(); overrides1.put("Button.contentMargins", new Insets(10,10,10,10)); button1.putClientProperty("Nimbus.Overrides", overrides1); // button 2 UIDefaults overrides2 = new UIDefaults(); overrides2.put("Button.font", new Font("Sans Serif", Font.BOLD, 15)); button2.putClientProperty("Nimbus.Overrides", overrides2); // button 3 UIDefaults overrides3 = new UIDefaults(); // nothing = left empty button3.putClientProperty("Nimbus.Overrides", overrides3); // button 4 // no styling } public static void main(String args[]) { try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(NimbusPerComponentTest.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new NimbusPerComponentTest().setVisible(true); } }); } }
知道为什么吗?我错过了什么?任何优雅的解决方法? (Java 8, Windows 10)
编辑
经过一些答案的启发:
尝试在我的原始代码末尾重置外观(为 null 并再次返回到 Nimbus,包括 SwingUtilities.updateComponentTreeUI),唯一的结果是:
现在即使是 button4 也画错了(边距和字体都改变了),尽管通用默认值从未被触及......很奇怪。
编辑 2
我设法找到了一个单行解决方法/hack。查看我自己对我的问题的回答...
最佳答案
如果我更改 UIDefaults
的创建,它对我有用。而不是
UIDefaults overrides1 = new UIDefaults();
我用过
UIDefaults overrides1 = (UIDefaults) UIManager.getLookAndFeelDefaults().clone();
对 overrides2
和 overrides3
也执行此操作:
// style
// button 1
UIDefaults overrides1 = (UIDefaults) UIManager.getLookAndFeelDefaults().clone();
overrides1.put("Button.contentMargins", new Insets(10, 10, 10, 10));
button1.putClientProperty("Nimbus.Overrides", overrides1);
// button 2
UIDefaults overrides2 = (UIDefaults) UIManager.getLookAndFeelDefaults().clone();
overrides2.put("Button.font", new Font("Sans Serif", Font.BOLD, 15));
button2.putClientProperty("Nimbus.Overrides", overrides2);
// button 3
UIDefaults overrides3 = (UIDefaults) UIManager.getLookAndFeelDefaults().clone();
// nothing = left empty
button3.putClientProperty("Nimbus.Overrides", overrides3);
// button 4
// no styling
这会在我的机器上产生以下输出:
请注意,以这种方式创建的 UIDefaults
的大小可能非常大。
关于Java Nimbus Look and Feel per component customization ("Nimbus.Overrides") - 其他实例也受影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49815702/