Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Nimbus每个组件的外观定制(“Nimbus.Overrides”)—其他实例也受到影响_Java_Swing_Look And Feel_Nimbus - Fatal编程技术网

Java Nimbus每个组件的外观定制(“Nimbus.Overrides”)—其他实例也受到影响

Java Nimbus每个组件的外观定制(“Nimbus.Overrides”)—其他实例也受到影响,java,swing,look-and-feel,nimbus,Java,Swing,Look And Feel,Nimbus,我不熟悉Java Nimbus的外观和感觉。我正在尝试使用Nimbus的功能,使用putClientProperty(“Nimbus.Overrides”,Overrides)自定义单个组件实例: 我遇到了以下问题(bug?): 不幸的是,“Nimbus.Overrides”值不仅会影响明确设置它的组件对象,还会影响其他对象。 定制属性似乎是以某种方式“继承”到同一类型的其他实例(后来是“样式化”的,显然以前不是)。我需要确保只对一个实例进行更改(不影响任何其他对象)。示例-JButton已使用

我不熟悉Java Nimbus的外观和感觉。我正在尝试使用Nimbus的功能,使用
putClientProperty(“Nimbus.Overrides”,Overrides)
自定义单个组件实例:

我遇到了以下问题(bug?):

不幸的是,“Nimbus.Overrides”值不仅会影响明确设置它的组件对象,还会影响其他对象。

定制属性似乎是以某种方式“继承”到同一类型的其他实例(后来是“样式化”的,显然以前不是)。我需要确保只对一个实例进行更改(不影响任何其他对象)。示例-
JButton
已使用,但与例如
JTabbedPane
和自定义画师遇到的问题相同:

  • 按钮1
    -自定义属性A(内容边距)
  • 按钮2
    -仅自定义属性B(字体)-但属性A中的更改也可见(更大的字体),“以某种方式继承”自
    按钮1
  • 按钮3
    -未自定义属性(使用空属性映射)-这两个更改(A+B)似乎都是从
    按钮1
    按钮2
    继承的(边距越大,字体越大)
  • 按钮4
    -默认外观为JButton(无自定义)

知道为什么吗?我错过了什么?有什么优雅的解决办法吗? (Java 8、Windows 10)

编辑

在一些答案的启发下:

尝试在我的原始代码末尾重置lookandfeel(设置为null并再次返回Nimbus,包括SwingUtilities.updateComponentTreeUI),唯一的结果是:

现在,即使是按钮4也画错了(边距和字体都改变了),尽管通用默认值从未被触摸过。。。奇怪

编辑2


我设法找到了一个单行解决方法/黑客。查看我自己对我的问题的答案…

如果我更改
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
的大小可能相当大。

我怀疑这是由于javax.swing.plaf.nimbus.NimbusLookAndFeel的
shouldUpdatestyleOneEvent
方法中的错误造成的。发件人:


不用说,这不是比较字符串的有效方法。我在bug数据库中找不到任何关于这个的信息;也许等我有时间的时候,我会提交一份bug报告。

经过很长时间的调试,似乎我已经找到了一个单行解决方法/hack,这可能也暗示了问题的原因:

if ("UIDefaults".equals(key)) {
    compiledDefaults = null;
}
在使用
putClientProperty(“Nimbus.Overrides”,Overrides)”设置每个组件的样式后,可以立即使用此代码防止将属性“继承”到随后设置样式的组件:

button1.putClientProperty("Nimbus.Overrides", overrides1);
UIManager.getDefaults().putDefaults(new Object[0]); 
  // add after each "styling"
  // - clears the compiledDefaults in NimbusLookAndFeel
它是干什么的

从功能上讲,没有(empy array=nothing put),但它会触发PropertyChange事件(请参阅源代码),在
NimbusLookAndFeel
类(请参阅源代码)的
DefaultsListener
私有类中侦听该事件,这是我找到以清除
编译默认结果的唯一方法在
NimbusLookAndFeel
中,在我看来,这是导致问题的原因:

if ("UIDefaults".equals(key)) {
    compiledDefaults = null;
}
NimbusLookAndFeel
类中的
getDefaultsForPrefix
方法(使用
compiledDefaults
)的调试过程中,我注意到了这个问题-请参阅源代码对于以后的组件,它不仅返回“真正的默认值”,而且出于某种原因还返回设置到以前组件的自定义属性。

明确地说:我完全是个业余爱好者,对Nimbus课程的细节或架构没有详细的知识或理解。我可能错了,但解决方案对我来说是有效的

不知什么原因,它不合适吗?有风险吗?它真的是一只虫子吗

一个问题:

if ("UIDefaults".equals(key)) {
    compiledDefaults = null;
}

我注意到,如果我
pack()
myframe不是在使用putClientProperty设置组件样式之前(如我的问题中的代码),而是在之后,则解决方案不起作用(没有任何帮助).

这是一个解决方案,但应该没有必要。文档中明确指出,覆盖UIDefaults应该与外观的默认值合并。是的,这个答案可能有效(尚未测试),但它取消了覆盖某些选定属性并将其与默认属性合并的整个过程。将默认属性的整个映射复制到每个单独的组件中一定非常重要…@VGR是的,但这正是不符合预期/记录的工作,请参见我的示例当我编写答案时,我假设Nimbus中存在错误(@VGR感谢深入了解源代码),但我觉得我应该提供一个解决方法。这就是我的答案试图描述的。谢谢你的提示。可能是我做错了,但我尝试在我的NetBeans中调试此方法,并且在我的示例中,在所有情况下,给定字符串的条件都为true(即正确)(尽管比较代码错误),即clearOverridesCache似乎正在运行。似乎问题可能在另一个“缓存”中-看看我自己对我的问题的回答。。。