Как изменить цвет фона для JPanels с помощью Nimbus Look and Feel?
Я хочу использовать другой цвет фона для всех моих JPanels в приложении. Как я могу это сделать при использовании Nimbus Look and Feel?
Я следую за изменением цветовой темы, чтобы изменить цвет компонентов в Nimbus Look and Feel.
Это работает только иногда, случайно. Если я установлю 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();
}
});
}
}
3 ответа
UIManager.getLookAndFeelDefaults().put("Panel.background", Color.RED);
Похоже, ошибка в 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 (и, скорее всего, куча других), "control" в обоих jdks подходит как до, так и после установки LAF.
Есть три способа
1) переопределить nimbusBase
для набора DerivedColor
2) создать свой Painter
есть только один пример -> aephyr codeource,
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();
}
});
}
}