Search code examples
javaswingcolorsnimbusuimanager

How do I use a default Nimbus color with UIManager?


I have a custom ListCellRenderer and would like to use the default Nimbus selection backround color. I can lookup the color with:

Color selectionBackground = UIManager.getColor("nimbusSelectionBackground");

and if I print it, it has the same values as on Nimbus default colors. But when I use it on a JPanel I get a different gray color, how can I use the color from UIManager?

When I do:

setBackground(Color.RED);

The JPanels backround is shown in red, but when I do:

setBackground(selectionBackground);

The "selectionBackground" color is not used, but a gray color.


Here is an example and screenshot:

enter image description here

The background should be:

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

public class PanelColor {

    public static void main(String[] args) {

        // switch to Nimbus Look And Feel
        for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                try {
                    UIManager.setLookAndFeel(info.getClassName());
                } catch (Exception e) { e.printStackTrace(); }
                break;
            }
        }

        Color selectionBackground = UIManager.getColor("nimbusSelectionBackground");

        JPanel panel = new JPanel(new BorderLayout());
        panel.setPreferredSize(new Dimension(300,50));
        panel.add(new JLabel(selectionBackground.toString()), BorderLayout.NORTH);

        // is not showing the selectionBackground color
        panel.setBackground(selectionBackground);

        JFrame frame = new JFrame();
        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

Solution

  • Nimbus apparently resists that its colors are used elsewhere. I stumbled across this a while ago too and back then my best solution was to create a new Color using the components (you can query) and use that. Of course, then you stick with that color even if the L&F is changed.

    I know that's the whole point of a DerivedColor you get back from the UIManager. I haven't found a better solution though.

    This goes similarly for other L&Fs and other things as well. E.g. the GTK L&F will happily give you icons you want to have but they won't draw in your own controls. I guess part of all this is that Swing is (a) horribly complex and (b) no L&F out there actually adheres to the contracts, not even Nimbus, despite being the newest and coolest one.