Search code examples
javaswingjava-8look-and-feelnimbus

Wrong colors in JList when using Nimbus and Java 8U20


My application uses wrong colors for JList since I updated to the latest Java 8 version (U20). E.g. instead of dark blue for selected items a light gray is actually used.

Simple test application:

import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;



public class Test {

    public Test() {
        try {
            UIManager.setLookAndFeel(new NimbusLookAndFeel());

            JList<String> l = new JList<>();
            DefaultListModel<String> model = new DefaultListModel<>();
            model.add(0, "sssssssss");
            model.add(1, "sssssssss");
            model.add(2, "sssssssss");
            model.add(3, "sssssssss");
            l.setModel(model);

            JFrame f = new JFrame();
            f.setSize(500, 500);
            f.setLocationRelativeTo(null);
            f.add(l);
            f.pack();
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setVisible(true);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }


public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            new Test();
            }
        });
    }    
}

Java 7, Java 8

Java 7, Java 8 <U20

Java 8 U20:

Java 8 U20

JList.getSelectionBackground() returns

DerivedColor(color=57,105,138 parent=nimbusSelectionBackground offsets=0.0,0.0,0.0,0 pColor=57,105,138

but actually it is not RGB(57,105,138) but the above mentioned light gray.


Solution

  • You can restore the exact behavior of versions before 1.8.0_20 with the following initialization code:

    final NimbusLookAndFeel laf = new NimbusLookAndFeel();
    UIManager.setLookAndFeel(laf);
    UIDefaults defaults = laf.getDefaults();
    defaults.put("List[Selected].textForeground",
        laf.getDerivedColor("nimbusLightBackground", 0.0f, 0.0f, 0.0f, 0, false));
    defaults.put("List[Selected].textBackground",
        laf.getDerivedColor("nimbusSelectionBackground", 0.0f, 0.0f, 0.0f, 0, false));
    defaults.put("List[Disabled+Selected].textBackground",
        laf.getDerivedColor("nimbusSelectionBackground", 0.0f, 0.0f, 0.0f, 0, false));
    defaults.put("List[Disabled].textForeground",
        laf.getDerivedColor("nimbusDisabledText", 0.0f, 0.0f, 0.0f, 0, false));
    defaults.put("List:\"List.cellRenderer\"[Disabled].background",
        laf.getDerivedColor("nimbusSelectionBackground", 0.0f, 0.0f, 0.0f, 0, false));
    

    This reverts what have changed between 1.8.0_05 and 1.8.0_20 in the class NimbusDefaults. The parameter false has been removed (which turns it effectively to true via the overloaded method). This change turns the Colors into UIResources what may be formally correct, but for whatever reason it causes the problem you have encountered. So re-inserting the false restores the old behavior.