Пользовательский ListCellRenderer не изменит цвет фона

У меня есть этот класс:

 @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;
    }
  }

Проблема в том, что мой фон не станет красным, когда я выберу ячейку в своем JList. Часть setText работает, но я не могу понять, почему она не изменит цвет фона ячейки. У кого какие идеи, спасибо!


person Grammin    schedule 24.10.2011    source источник


Ответы (3)


Основная проблема заключается в том, что метки по умолчанию непрозрачны, поэтому вам нужно сделать метку непрозрачной, чтобы фон был закрашен.

Но для этого не нужно создавать собственный рендерер. Средство визуализации по умолчанию непрозрачно. Все, что вам нужно сделать, это установить свойство выбора фона списка:

list.setSelectionBackground(Color.RED);

Если вы пытаетесь создать средство визуализации для выравнивания текста по правому краю, вы можете просто установить свойство средства визуализации по умолчанию:

DefaultListCellRenderer renderer = (DefaultListCellRenderer)list.getCellRenderer();
renderer.setHorizontalAlignment(SwingConstants.RIGHT);
person camickr    schedule 24.10.2011

Например

введите здесь описание изображения

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;
        }
    }
}
person mKorbel    schedule 24.10.2011
comment
Просто примечание: важно иметь там setOpaque(true);, я думаю, именно поэтому рендерер OP вел себя неправильно. - person Jeffrey; 25.10.2011
comment
Нет необходимости вызывать setPreferredSize() или setEnabled в средстве визуализации. Кроме того, метод setOpaque() должен вызываться в конструкторе, нет необходимости выполнять его каждый раз при вызове рендерера. Кроме того, JList имеет свойства для установки фона выделения и переднего плана. Вы не должны жестко кодировать эти цвета в рендерере. - person camickr; 25.10.2011
comment
@camickr - на самом деле, setEnabled является необходимым, если список должен казаться отключенным :-) Установка непрозрачности (но на значение списка, а не безоговорочно) может потребоваться, если вы хотите показать фоновое изображение. - person kleopatra; 25.10.2011
comment
Я знаю, что это только пример, но на самом деле я бы рекомендовал никогда не писать средство визуализации с нуля — слишком многое нужно забыть (здесь, например, отзыв о перетаскивании). Но пока вы при правильном отображении значка файла сделайте то же самое с его именем :-) - person kleopatra; 25.10.2011
comment
Спасибо за этот пример - person Hovercraft Full Of Eels; 23.05.2016

По умолчанию JLabel прозрачен. Если вы хотите, чтобы он показывал фон, вам нужно:

label.setOpaque(true);

Кроме того, вы часто хотите использовать цвет фона по умолчанию для родительского списка, который будет соответствовать теме пользовательского интерфейса или настройке самого списка:

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

Собираем все вместе:

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;
    }
}
person Drew Noakes    schedule 14.08.2014