Search code examples
javajcomboboxlistcellrenderer

ListCellRenderer, selected value not visible


I have JComboBox where I apply ListCellRenderer as following:

    colorList = new JComboBox<>(COLORS_NAMES);
    ColorComboBoxRenderer renderer = new ColorComboBoxRenderer(colorList);
    renderer.setColors(COLORS);
    renderer.setColorNames(COLORS_NAMES);
    colorList.setRenderer(renderer);

it has result in modyfing cells, but I can't find reason why selected value is remembered but not pictured. Like following:

enter image description here

Here is my code for renderer ( omitting setColors, getColors etc..)

class ColorComboBoxRenderer extends JPanel implements ListCellRenderer{

    JPanel textPanel;
    JLabel text;

    public ColorComboBoxRenderer(JComboBox combo){
        textPanel = new JPanel();
        textPanel.add(this);
        text = new JLabel();
        text.setOpaque(true);
        text.setFont(combo.getFont());
        textPanel.add(text);
    }

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
            boolean cellHasFocus) {
        if (isSelected){
            list.setSelectionBackground(colors[list.getSelectedIndex()]);
        }
        else{}

        if(colors.length != colorNames.length){
            System.out.println("colors.length doesn't match colorNames.length");
            return this;
        }
        else if(colors == null){
            System.out.println("Set colors by setColors first.");
            return this;
        }
        else if(colorNames == null){
            System.out.println("Set colorNames by setColorNames first.");
            return this;
        }

        text.setText(" ");

        if(index > -1){
            text.setBackground(colors[index]);
            text.setText(" ");
        }

        return text;
    }
}

What also confuses me is that if(isSelected) block is done everytime I point cursor on specified cell, but my intuition would rather expect that happen when cellHasFocus param is true.

Thanks in advance, as I am struggling with it since 2 days ;/

EDIT 1

Added JComboBox field to ColorComboBoxRenderer class, and initializes it in constructor:

private JComboBox comboBox;
public ColorComboBoxRenderer(JComboBox combo) {
        this.comboBox = combo;
        //rest of code as it was 
    }

Changed that:

    if(isSelected){
        list.setSelectionBackground(colors[list.getSelectedIndex()]);
    }

To:

    if (isSelected){
        list.setSelectionBackground(colors[list.getSelectedIndex()]);
        comboBox.setBackground(colors[list.getSelectedIndex()]);
    }

Results in:

enter image description here

Now the effect is better, so maybe u have an idea how to change JComboBox background but do not affect dropdown arrow?


Solution

  • In EDIT 1 it is important that we did edit ComboBox, it is necessary, because ListRenderer just generates dropDown list and its cells, but wouldn't affect ComboBox fields. So what was necessary and I finally found it, was quite brute force approach. I changed whole ComboBox background when selected as in EDIT 1 but then returned Arrow State, which is at Index (0) of JComboBox. Finally that section of code should be like this:

           if (isSelected){
                list.setSelectionBackground(colors[list.getSelectedIndex()]);
                comboBox.setBackground(colors[list.getSelectedIndex()]);
                comboBox.getComponent(0).setBackground(new JButton().getBackground());
            }
    

    Now everything works as designed:

    enter image description here