JTable 中的混合颜色渲染

问题描述 投票:0回答:1

我有一个 JTable,在其中放置了一组代表齿轮比的数字。数据中有一些重复,所以我想要为它们使用不同颜色的背景;但是,每组重复项必须具有不同的颜色。重复项可能由两个、三个或四个单元格组成。重复项列表(ArrayList)包括每个重复项所在的行和列,以及分配给该组重复项的 RGB 颜色(背景和前景)。它的定义如下:

    private Double ratio;       
    private int row;
    private int col;
    private int backgroundRed;
    private int backgroundGreen;
    private int backgroundBlue;
    private int foregroundRed;
    private int foregroundGreen;
    private int foregroundBlue;

列表被发送到单元格渲染器,因此看起来很简单 - 它所要做的就是读取列表并渲染颜色。我遇到的问题是,我似乎无法让渲染器重置为那些不重复的比率所需的默认黑白。

表格应该是这样的。所有非重复的单元格都以黑色字体呈现在白色背景中。

这是我迄今为止开发的输出:

输出中的第 0 行几乎是正确的,因为它以黑白显示前 3 列,因为它们不重复,并且该行中的其余单元格具有不同的颜色。问题从第 1 行、第 0 列和第 1 列开始,其中这两个单元格也应该是黑白的,但与第 0 行第 8 列的颜色相同。这告诉我,它没有重置为默认值(即,黑色白色的)。这种情况再次出现在第 3 行(第 5、6 和 7 列)、第 4 行(第 6、7 和 8 列)、第 5 行(第 0、1 和 2 列)以及所有第 6 行和第 8 行。

这是渲染器的代码。您会注意到我尝试了两种不同的比较(IF 语句):一种比较比率值,另一种识别每组重复项的行和列。这两者都会产生相似的结果。所以我的问题是,如何将渲染器重置为那些不重复的单元格的默认颜色?

public class NumberCellRenderer extends DefaultTableCellRenderer
{
    private static final long serialVersionUID = 1L;
    private JLabel label;
    private DecimalFormat numberFormat = new DecimalFormat("#0.000"); 
    private List<DuplicateValues> duplicateValues = new ArrayList<>();
    private String text;

    public NumberCellRenderer (List<DuplicateValues> duplicateValues)
    {
        this.duplicateValues = duplicateValues;
    }
    
    @Override
    public JLabel getTableCellRendererComponent(JTable jTable, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    {
        Component c = super.getTableCellRendererComponent(jTable, value, isSelected, hasFocus, row, column);
        if (c instanceof JLabel && value instanceof Number)
        {
            label = (JLabel) c;
            label.setHorizontalAlignment(JLabel.CENTER);
            Number num = (Number) value;
            text = numberFormat.format(num);
            label.setText(text);
        }
        for(int i=0; i<duplicateValues.size(); i++)
        {
//          if(duplicateValues.get(i).getRatio() == Double.parseDouble(value.toString()))
            if(row == duplicateValues.get(i).getRow() && column == duplicateValues.get(i).getCol())
            {
                label.setBackground(new Color(duplicateValues.get(i).getBackgroundRed(), duplicateValues.get(i).getBackgroundGreen(), duplicateValues.get(i).getBackgroundBlue()));
                label.setForeground(new Color(duplicateValues.get(i).getForegroundRed(), duplicateValues.get(i).getForegroundGreen(), duplicateValues.get(i).getForegroundBlue()));
            }
            else
            {
                label.setBackground(getBackground());
                label.setForeground(getForeground());
            }
        }
    return label;
    }
    return label;
    }
}

我看过其他解决方案,但大多数都希望将整个列或行渲染为相同的颜色。这个应用程序要求相同的颜色分散在整个桌子上。

java jtable background-color tablecellrenderer
1个回答
0
投票

让我们完成这个循环......

for(int i=0; i<duplicateValues.size(); i++)
{
    if(row == duplicateValues.get(i).getRow() && column == duplicateValues.get(i).getCol())
    {

当上述

if
测试为真时,代码将自定义颜色应用于标签:

        label.setBackground(new Color(duplicateValues.get(i).getBackgroundRed(), duplicateValues.get(i).getBackgroundGreen(), duplicateValues.get(i).getBackgroundBlue()));
        label.setForeground(new Color(duplicateValues.get(i).getForegroundRed(), duplicateValues.get(i).getForegroundGreen(), duplicateValues.get(i).getForegroundBlue()));

那就完美了……只要程序不将标签的颜色更改为其他颜色即可。但是,由于此循环继续进行(在大多数情况下),循环的下一次迭代将“不会”设置这些相同的颜色。相反,它将进入 else 部分:

    }
    else
    {
        label.setBackground(getBackground());
        label.setForeground(getForeground());
    }

现在根据重复值设置自定义颜色的代码已被撤消。您的自定义颜色丢失了。

解决方案是仅在循环完成后

调用 label.setForeground 和 label.setBackground

Color foreground; Color background; if (isSelected) { foreground = table.getSelectionForeground(); background = table.getSelectionBackground(); } else { foreground = table.getForeground(); background = table.getBackground(); for (DuplicateValues d : duplicateValues) { if (row == d.getRow() && column == d.getCol()) { foreground = new Color( d.getForegroundRed(), d.getForegroundGreen(), d.getForegroundBlue()); background = new Color( d.getBackgroundRed(), d.getBackgroundGreen(), d.getBackgroundBlue()); // We found a match. No need to keep checking! break; } } } label.setForeground(foreground); label.setBackground(background);

© www.soinside.com 2019 - 2024. All rights reserved.