我有一个 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;
}
}
我看过其他解决方案,但大多数都希望将整个列或行渲染为相同的颜色。这个应用程序要求相同的颜色分散在整个桌子上。
让我们完成这个循环......
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);