如何使用Nimbus外观改变JPanels的背景颜色?

我想为应用程序中的所有JPanel使用不同的背景颜色。 使用Nimbus外观时我该怎么做?

我按照更改颜色主题来更改Nimbus外观中的组件颜色。

它有时只能随机工作 。 如果我在更改颜色之前设置了PropertyChagneListener ,则只会通知一次

这是一些测试代码:

 public class RedPanels extends JFrame { public RedPanels() { JPanel panel = new JPanel(); add(panel); setPreferredSize(new Dimension(100, 100)); pack(); setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { UIManager.setLookAndFeel(info.getClassName()); UIManager.getDefaults().addPropertyChangeListener( new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent event) { if (event.getPropertyName().equals("Panel.background")) { System.out.println("color changed"); } }); UIManager.put("Panel.background", new Color(255,0,0)); break; } } } catch (Exception e) { // Nimbus is not available. } new RedPanels(); } }); } } 

 UIManager.getLookAndFeelDefaults().put("Panel.background", Color.RED); 

有三种方式

1)覆盖设置DerivedColor

2)创建自己的Painter ,只有一个例子 – > aephyr codesource ,

3)简单而肮脏的黑客直接设置颜色

在此处输入图像描述

 import java.awt.*; import javax.swing.*; import javax.swing.border.LineBorder; public class NimbusJPanelBackGround { public NimbusJPanelBackGround() { JPanel p = new JPanel(); UIDefaults nimbusOverrides = new UIDefaults(); nimbusOverrides.put("Panel.background", Color.blue); p.putClientProperty("Nimbus.Overrides", nimbusOverrides); SwingUtilities.updateComponentTreeUI(p); JPanel p1 = new JPanel(); nimbusOverrides = new UIDefaults(); nimbusOverrides.put("Panel.background", Color.green); p1.putClientProperty("Nimbus.Overrides", nimbusOverrides); SwingUtilities.updateComponentTreeUI(p1); p1.setBorder(new LineBorder(Color.black, 1)); JPanel p2 = new JPanel(); nimbusOverrides = new UIDefaults(); nimbusOverrides.put("Panel.background", Color.ORANGE); p2.putClientProperty("Nimbus.Overrides", nimbusOverrides); SwingUtilities.updateComponentTreeUI(p2); JFrame f = new JFrame(); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.add(p, BorderLayout.NORTH); f.add(p1, BorderLayout.CENTER); f.add(p2, BorderLayout.SOUTH); f.setSize(200, 100); f.setLocation(150, 150); f.setVisible(true); } public static void main(String[] args) { try { for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(laf.getName())) { UIManager.setLookAndFeel(laf.getClassName()); } } } catch (Exception e) { e.printStackTrace(); } EventQueue.invokeLater(new Runnable() { @Override public void run() { NimbusJPanelBackGround nimbusJPanelBackGround = new NimbusJPanelBackGround(); } }); } } 

看起来像jdk6中的一个错误,Panel.background是未采取的属性之一。 以下是在jdk7中工作(注意顺序:首先设置颜色,然后是LAF)

  UIManager.put("Panel.background", new Color(255,0,0)); UIManager.setLookAndFeel(info.getClassName()); 

我的猜测是,它仍然是某种错误,因为Nimbus应该在接收管理器设置的任何变化时更新其属性,因此将序列转换为首先设置Nimbus,然后将颜色也应该工作,但是甚至不行在jdk7

  UIManager.setLookAndFeel(info.getClassName()); UIManager.put("Panel.background", new Color(255,0,0)); //UIManager.put("control", Color.MAGENTA); 

似乎是特定于Panel.background(并且很可能是其他一些),“控制”在两个jdks中都可以,无论是在设置LAF之前还是之后。