自定义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部分工作,但我无法弄清楚为什么它不会改变我的单元格的背景颜色。 任何人有任何想法,谢谢!

主要问题是默认情况下标签是非透明的,因此您需要使标签不透明以便绘制背景。

但是您不需要为此创建自定义渲染器。 默认渲染器是不透明的。 您需要做的就是设置列表的选择背景属性:

 list.setSelectionBackground(Color.RED); 

如果您尝试创建渲染器以右对齐文本,则可以在默认渲染器上设置属性:

 DefaultListCellRenderer renderer = (DefaultListCellRenderer)list.getCellRenderer(); renderer.setHorizontalAlignment(SwingConstants.RIGHT); 

例如

在此处输入图像描述

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

默认情况下, JLabel是透明的。 如果您希望它显示背景,您需要:

 label.setOpaque(true); 

此外,您经常要使用父列表的默认背景颜色,这将适合UI主题或列表本身的自定义:

 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 { @Override public Component getListCellRendererComponent(JList 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; } }