Custom ListCellRenderer will not change background color
Asked Answered
C

3

5

I have this class:

 @SuppressWarnings("serial")
  private class DataCellRenderer extends JLabel implements ListCellRenderer 
  {
    public DataCellRenderer()
    {
      setHorizontalAlignment(SwingConstants.RIGHT); 
    }

    @Override
    public Component getListCellRendererComponent(
        JList list,
        Object value,
        int index,
        boolean isSelected,
        boolean cellHasFocus)
    {

      if(isSelected)
        setBackground(Color.red);

      setText("  " + value.toString());

      return this;
    }
  }

The problem is that my Background will not turn red when I select a cell in my JList. The setText part works but I can't figure out why it will not change my background color of the cell. Anyone have any ideas, Thanks!

Conjunctive answered 24/10, 2011 at 20:58 Comment(0)
I
9

The main problem is that labels are non-opaque by default, so you need to make the label opaque in order for the background to be painted.

But you don't need to create a custom renderer for this. The default renderer is opaque. All you need to do is set the selection background property of the list:

list.setSelectionBackground(Color.RED);

If you are trying to create a renderer to right align the text then you can just set a property on the default renderer:

DefaultListCellRenderer renderer = (DefaultListCellRenderer)list.getCellRenderer();
renderer.setHorizontalAlignment(SwingConstants.RIGHT);
Indubitable answered 24/10, 2011 at 21:56 Comment(0)
L
6

for example

enter image description here

import java.awt.*;
import java.io.File;
import javax.swing.*;
import javax.swing.filechooser.FileSystemView;

public class FilesInTheJList {

    private static final int COLUMNS = 5;
    private Dimension size;

    public FilesInTheJList() {
        final JList list = new JList(new File("C:\\").listFiles()) {

            private static final long serialVersionUID = 1L;

            @Override
            public Dimension getPreferredScrollableViewportSize() {
                if (size != null) {
                    return new Dimension(size);
                }
                return super.getPreferredScrollableViewportSize();
            }
        };
        list.setFixedCellHeight(50);
        list.setFixedCellWidth(150);
        size = list.getPreferredScrollableViewportSize();
        size.width *= COLUMNS;
        list.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        list.setCellRenderer(new MyCellRenderer());
        list.setVisibleRowCount(0);
        list.setLayoutOrientation(JList.HORIZONTAL_WRAP);

        JFrame f = new JFrame("Files In the JList");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new JScrollPane(list));
        f.pack();
        f.setVisible(true);
    }

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

            @Override
            public void run() {
                FilesInTheJList fITJL = new FilesInTheJList();
            }
        });
    }

    private static class MyCellRenderer extends JLabel implements ListCellRenderer {

        private static final long serialVersionUID = 1L;

        @Override
        public Component getListCellRendererComponent(JList list, Object value,
                int index, boolean isSelected, boolean cellHasFocus) {
            if (value instanceof File) {
                File file = (File) value;
                setText(file.getName());
                setIcon(FileSystemView.getFileSystemView().getSystemIcon(file));
                if (isSelected) {
                    setBackground(Color.red);
                    setForeground(Color.blue);
                } else {
                    setBackground(list.getBackground());
                    setForeground(list.getForeground());
                }
                //setPreferredSize(new Dimension(250, 25));
                //setEnabled(list.isEnabled());
                setFont(list.getFont());
                setOpaque(true);
            }
            return this;
        }
    }
}
Leede answered 24/10, 2011 at 21:3 Comment(4)
Just a note: It's important to have the setOpaque(true); in there, I think that's why the OP's renderer was not behaving correctly.Steere
There is no need to invoke setPreferredSize() or setEnabled in the renderer. Also, the setOpaque() method should be invoked in the constructor, there is no need for it to be executed every time the renderer is invoked. Also, the JList has properties for setting the selection background and foreground. You should not be hardcoding these colors in the renderer.Indubitable
@Indubitable - in fact, setEnabled is necessary if the list should appear disabled :-) Setting opaqueness (but to the list's value instead of unconditionally) may be needed if you want to show a background image.Michelemichelina
I'm aware that this is an example only, but actually, I would recommend to never write a renderer from scratch - there is simply too much to forget (here f.i. the drag&drop feedback) But while you are at showing a file's icon correctly, do the same with its name :-)Michelemichelina
P
2

By default JLabel is transparent. If you want it to show a background, you need:

label.setOpaque(true);

Also, you often want to use the default background colour of the parent list, which will fit with the UI theme or customisation of the list itself:

if (isSelected) {
    label.setForeground(list.getSelectionForeground());
    label.setBackground(list.getSelectionBackground());
} else {
    label.setForeground(list.getForeground());
    label.setBackground(list.getBackground());
}

Putting it all together:

import javax.swing.*;
import java.awt.*;

public class CustomListCellRenderer implements ListCellRenderer<MyObject>
{
    @Override
    public Component getListCellRendererComponent(JList<? extends MyObject> list,
                                                  MyObject value,
                                                  int index,
                                                  boolean isSelected,
                                                  boolean cellHasFocus)
    {
        JLabel label = new JLabel();
        label.setOpaque(true);
        label.setText(value.getName());
        if (isSelected) {
            label.setForeground(list.getSelectionForeground());
            label.setBackground(list.getSelectionBackground());
        } else {
            label.setForeground(list.getForeground());
            label.setBackground(list.getBackground());
        }
        return label;
    }
}
P answered 14/8, 2014 at 21:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.