You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JTable重复数据单元格渲染:默认颜色重置异常问题

问题:JTable非重复单元格无法重置默认背景色

在Java Swing的JTable中展示齿轮比数值,数据存在重复项,需为每组重复单元格设置不同背景色(重复组包含2-4个单元格)。已通过ArrayList<DuplicateValues>存储重复项的行列位置及对应RGB背景、前景色,并传入自定义单元格渲染器NumberCellRenderer。目前遇到的核心问题:非重复数据的单元格无法重置为默认白背景黑字体,渲染结果异常(如部分非重复单元格继承其他单元格的颜色)。


DuplicateValues类定义

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;

当前存在问题的NumberCellRenderer代码

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

解决方案

问题根源在于遍历重复项的逻辑:每次循环遇到不匹配的单元格就重置默认颜色,导致重复单元格的自定义颜色会被后续不匹配的循环项覆盖,同时非重复单元格的状态也会因为多次重置出现异常。

修改后的渲染器代码:

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

    public NumberCellRenderer(List<DuplicateValues> duplicateValues)
    {
        this.duplicateValues = duplicateValues;
        // 统一设置默认对齐方式,避免重复操作
        setHorizontalAlignment(JLabel.CENTER);
    }
    
    @Override
    public Component getTableCellRendererComponent(JTable jTable, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    {
        // 调用父类方法初始化组件默认状态
        super.getTableCellRendererComponent(jTable, value, isSelected, hasFocus, row, column);
        
        // 格式化数值显示
        if (value instanceof Number)
        {
            Number num = (Number) value;
            setText(numberFormat.format(num));
        }
        
        // 先设置默认样式:非重复单元格直接使用表格默认颜色
        setBackground(jTable.getBackground());
        setForeground(jTable.getForeground());
        
        // 遍历重复项,仅为匹配的单元格设置自定义颜色
        for (DuplicateValues dv : duplicateValues)
        {
            if (dv.getRow() == row && dv.getCol() == column)
            {
                setBackground(new Color(dv.getBackgroundRed(), dv.getBackgroundGreen(), dv.getBackgroundBlue()));
                setForeground(new Color(dv.getForegroundRed(), dv.getForegroundGreen(), dv.getForegroundBlue()));
                // 找到匹配项后跳出循环,减少无效遍历
                break;
            }
        }
        
        return this;
    }
}

关键优化点

  1. 先设置默认状态:确保所有单元格初始为表格默认样式,非重复单元格无需额外处理。
  2. 遍历逻辑调整:仅在找到匹配的重复项时才覆盖颜色,避免后续循环重置已设置的自定义样式。
  3. 简化代码结构:利用DefaultTableCellRenderer本身是JLabel子类的特性,直接操作this,无需额外维护label变量。
  4. 使用表格默认颜色:通过jTable.getBackground()/getForeground()获取全局默认样式,保证和表格整体风格一致。

内容的提问来源于stack exchange,提问作者user5991980

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 16:33:23