需要时更改 JList 项目颜色

Posted

技术标签:

【中文标题】需要时更改 JList 项目颜色【英文标题】:Change JList item colour when I want 【发布时间】:2017-04-27 08:36:20 【问题描述】:

我正在尝试构建一个JList,其中一些项目的背景颜色与其他项目不同,但仅在我需要时。

我一直在尝试做这样的事情,它会产生错误。

 static DefaultListModel<String> model = new DefaultListModel<>();

 for(int K=0;K<Collectionsize();K++)
        Jlist.setForeground(Color.red); 
        model.addElement(type 1);

        for(int I=0;I<(subcollection.size();I++)
            Jlist.setForeground(Color.white); 
            model.addElement(type 2);
            
        

类型 1 和 2 之间没有模式,所以我想在需要时更改颜色,而不是依赖 if 语句。

我看到很多人都在谈论构建自定义渲染类,但我的目标是一些更简单的东西。

【问题讨论】:

“我看到很多人都在谈论构建自定义渲染类,但我的目标是一些更简单的东西。” 你错误地认为不同的方法会更简单。 我投票结束这个问题,因为 OP 想要最简单的方法,但已经拒绝了! (1-) I see a lot of people... - 如果存在更简单的解决方案,为什么很多人会使用复杂的解决方案?您不认为很多人会使用更简单且普遍接受的方法吗? @AndrewThompson 我看到很多客户渲染类,但它们似乎都集中在“如果它包含字符 Y 颜色为蓝色”,我正在寻找的是一个简单的动作,它可以让我只在需要时更改颜色。如果我必须使用自定义渲染类,我会使用它,但我希望避免它。 “当我想要它时” 以及您想要它何时发生?为了尽快获得更好的帮助,请发布有效的minimal reproducible example 并遵循上述建议,即使用渲染类,别无他法 【参考方案1】:

注意:每个项目包含两条信息的项目列表更适合显示在表格中而不是列表中,但如果需要,您可以将其调整为列表。同样的基本原则也适用(使用渲染组件)。

这就是我的意思:

这是通过这个渲染类实现的:

class TrackCellRenderer extends DefaultTableCellRenderer 

    HashMap<String, Color> colorMap = new HashMap<>();
    Random r = new Random();

    @Override
    public Component getTableCellRendererComponent(
            JTable table,
            Object value,
            boolean isSelected, boolean hasFocus,
            int row, int column) 
        Component c = super.getTableCellRendererComponent(
                table, value, isSelected, hasFocus, row, column);
        JLabel l = (JLabel) c;

        String s = (String) value;
        if (column == 0) 
            if (!colorMap.containsKey(s)) 
                Color clr = new Color(
                        150 + r.nextInt(105),
                        150 + r.nextInt(105),
                        150 + r.nextInt(105));
                colorMap.put(s, clr);
            
            Color color = colorMap.get(s);
            l.setBackground(color);
            l.setOpaque(true);
         else 
            l.setOpaque(false);
        

        return l;
    

注意:最好使用枚举而不是随机分配颜色,但有 3 个专辑和超过一百万种可能的颜色,我们应该是相当安全的。

在这个只有 100 多行代码的(二级)MCVE 中:

import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.*;
import java.util.*;

public class AlbumTrackTable 

    private JComponent ui = null;
    String[][] playList = 
        "The Will to Live", "Faded",
        "The Will to Live", "Homeless Child",
        "Oh Mercy", "Political Wrold",
        "Oh Mercy", "What Was it You Wanted?",
        "Red Sails in the Sunset", "Helps Me Helps You",
        "Red Sails in the Sunset", "Redneck Wonderland"
    ;
    String[] columnNames = "Album", "Track";

    AlbumTrackTable() 
        initUI();
    

    public void initUI() 
        if (ui != null) 
            return;
        

        ui = new JPanel(new BorderLayout(4, 4));
        ui.setBorder(new EmptyBorder(4, 4, 4, 4));

        DefaultTableModel trackModel = new DefaultTableModel(playList, columnNames);
        JTable table = new JTable(trackModel);
        ui.add(new JScrollPane(table));
        TableCellRenderer renderer = new TrackCellRenderer();
        table.setDefaultRenderer(Object.class, renderer);
        table.setAutoCreateRowSorter(true);
    

    public JComponent getUI() 
        return ui;
    

    public static void main(String[] args) 
        Runnable r = new Runnable() 
            @Override
            public void run() 
                try 
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                 catch (Exception useDefault) 
                
                AlbumTrackTable o = new AlbumTrackTable();

                JFrame f = new JFrame(o.getClass().getSimpleName());
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            
        ;
        SwingUtilities.invokeLater(r);
    


class TrackCellRenderer extends DefaultTableCellRenderer 

    HashMap<String, Color> colorMap = new HashMap<>();
    Random r = new Random();

    @Override
    public Component getTableCellRendererComponent(
            JTable table,
            Object value,
            boolean isSelected, boolean hasFocus,
            int row, int column) 
        Component c = super.getTableCellRendererComponent(
                table, value, isSelected, hasFocus, row, column);
        JLabel l = (JLabel) c;

        String s = (String) value;
        if (column == 0) 
            if (!colorMap.containsKey(s)) 
                Color clr = new Color(
                        150 + r.nextInt(105),
                        150 + r.nextInt(105),
                        150 + r.nextInt(105));
                colorMap.put(s, clr);
            
            Color color = colorMap.get(s);
            l.setBackground(color);
            l.setOpaque(true);
         else 
            l.setOpaque(false);
        

        return l;
    

【讨论】:

以上是关于需要时更改 JList 项目颜色的主要内容,如果未能解决你的问题,请参考以下文章

如何生成具有交替颜色的 Jlist

Swing JList SetCellRenderer 背景颜色不起作用

滚动时更改 UIButton 色调颜色

ListItem 应在按下时更改背景颜色、文本和图像的颜色

ionic 4 在离子项目中聚焦时更改离子标签颜色

如何在 Flutter 中选择项目时更改卡片颜色?