Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8224098

Nimbus JList selection colors are wrong when cell renderer is overridden


    • Subcomponent:
    • Introduced In Version:
    • CPU:
    • OS:


      When the cell renderer is overridden on a JList, and the look and feel is set to Nimbus, the list's selection color is ignored. Black on gray is used instead. Since the overridden cell renderer is not changing the color, but merely (and correctly) using the defaults, the displayed color should not change.

      It seems that something in Nimbus ignores the configured color if it is an instance of UIResource. Although the default colors are supposed to be instances of UIResource, they are also not supposed to be ignored by the renderer.

      I know this problem did not occur in some older version of Java, but I do not remember exactly when it started. It is very probably related to:
      JDK-8041725 Nimbus JList selection colors persist across L&F changes
      JDK-8057791 Selection in JList is drawn with wrong colors in Nimbus L&F

      The attached test case creates three side-by-side JLists.
      List 1 has the default list cell renderer, and the selection color is correct.
      List 2 has a DefaultListCellRenderer, and the selection color is displayed wrong, even though the code in DefaultListCellRenderer sets it correctly.
      List 3 has a DefaultListCellRenderer, with a workaround that sets the color to a non-UIResource instance to restore correct behavior.

      EXPECTED -
      All three lists should have the same selection color.
      ACTUAL -
      The middle list has a different color.

      ---------- BEGIN SOURCE ----------
      import java.awt.*;
      import javax.swing.*;

      class NimbusJListSelectionColor {
          public static void main(String[] args) {
              SwingUtilities.invokeLater(() -> {
                  try {
                  } catch (Exception checkedExceptionsPleaseDie) {
                      throw new RuntimeException(checkedExceptionsPleaseDie);
                  JFrame frame = new JFrame();
                  frame.setLayout(new GridLayout(1, 0));
                  JList<String> list1 = new JList<>();
                  JList<String> list2 = new JList<>();
                  JList<String> list3 = new JList<>();
                  list1.setListData(new String[] { "One", "Two", "Three" });
                  list2.setListData(new String[] { "One", "Two", "Three" });
                  list3.setListData(new String[] { "One", "Two", "Three" });
                  frame.add(new JScrollPane(list1));
                  frame.add(new JScrollPane(list2));
                  frame.add(new JScrollPane(list3));
                  // list1 is not customized; the selection color is correct as configured by Nimbus, white on blue
                  // list2 has overridden the list cell renderer;
                  // on its own, this should not change the color, and didn't used to in older Java versions,
                  // but now the selection color is now black on light gray
                  list2.setCellRenderer(new DefaultListCellRenderer() {
                      public Component getListCellRendererComponent(
                              JList<?> list,
                              Object value,
                              int index,
                              boolean isSelected,
                              boolean cellHasFocus) {
                          return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                  // list3 contains a workaround; the selection color is correct again
                  list3.setCellRenderer(new DefaultListCellRenderer() {
                      public Component getListCellRendererComponent(
                              JList<?> list,
                              Object value,
                              int index,
                              boolean isSelected,
                              boolean cellHasFocus) {
                          super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                          // this print statement shows the correct color, as it is configured, and as it should appear:
                          // 57,105,138 a.k.a. #39698A (blue)
                          // but the configured color is ignored; what is drawn on screen is:
                          // 214,217,223 a.k.a. #D6D9DF (light gray)
                          if (isSelected) {
                          // this workaround bypasses the bug by creating a non-UIResource Color instance:
                          this.setBackground(new Color(this.getBackground().getRGB(), true));
                          this.setForeground(new Color(this.getForeground().getRGB(), true));
                          return this;
      ---------- END SOURCE ----------

      FREQUENCY : always




            • Assignee:
              alitvinov Anton Litvinov
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              3 Start watching this issue


              • Created: