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

JTable新增行高亮异常:首行生效次行失效问题求助

问题分析与解决方案

你遇到的问题核心在于每次设置默认渲染器时都会覆盖之前的实例,导致只有最后一个被设置的行能被高亮。你的循环代码中,每遍历一个rowToAdd[k]就新建一个GrayWhiteRenderer并设置为表格的默认渲染器,这意味着之前的渲染器会被完全替换,最终只有最后一行的索引被渲染器记住,其他行自然无法高亮。

另外你的测试代码里,actionPerformed方法中的循环逻辑也有问题:你遍历的是列数,然后把列索引传给渲染器,这完全不符合需求,应该是记录新增的行索引。

修复方案

我们需要修改渲染器,让它能够存储所有需要高亮的行索引,而不是单个行。具体步骤如下:

  1. 让GrayWhiteRenderer持有一个Set<Integer>来保存所有需要高亮的行ID
  2. 在渲染方法中判断当前行是否在这个集合中,是则设置灰色背景
  3. 新增行时,将新行的索引添加到集合中,并通知表格刷新

修改后的代码示例

1. 修复后的GrayWhiteRenderer

class GrayWhiteRenderer extends DefaultTableCellRenderer {
    // 存储所有需要高亮的行索引
    private final Set<Integer> highlightedRows;

    GrayWhiteRenderer(Set<Integer> highlightedRows) {
        this.highlightedRows = highlightedRows;
    }

    @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);
        
        // 如果行被选中,优先使用选中样式(避免和高亮冲突)
        if (isSelected) {
            return c;
        }
        
        // 判断当前行是否需要高亮
        if (highlightedRows.contains(row)) {
            c.setBackground(Color.GRAY.brighter());
        } else {
            // 使用表格默认的行背景色,而不是硬写白色,更适配LAF
            c.setBackground(UIManager.getColor("Table.background"));
        }
        return c;
    }
}

2. 测试类的修改

package Graphic;

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.util.HashSet;
import java.util.Set;

class Test implements Runnable, ActionListener {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Test());
    }

    JTable table;
    // 用于存储所有需要高亮的行索引
    private final Set<Integer> highlightedRows = new HashSet<>();

    @Override
    public void run() {
        JFrame frame = new JFrame("Custom Cell Renderer");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        table = new JTable(new DefaultTableModel(0, 2) {
            @Override
            public Class<?> getColumnClass(int c) {
                return Object.class;
            }
        });

        // 初始化渲染器,传入高亮行集合
        GrayWhiteRenderer renderer = new GrayWhiteRenderer(highlightedRows);
        table.setDefaultRenderer(Object.class, renderer);
        table.setTableHeader(null);

        JButton btn = new JButton("Add Row");
        btn.addActionListener(this);

        JToolBar bar = new JToolBar();
        bar.setFloatable(false);
        bar.add(btn);

        JPanel content = new JPanel(new BorderLayout());
        content.add(bar, BorderLayout.NORTH);
        content.add(new JScrollPane(table), BorderLayout.CENTER);

        frame.setContentPane(content);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        int nextRow = table.getRowCount();
        DefaultTableModel model = (DefaultTableModel) table.getModel();
        model.addRow(new Object[]{"" + nextRow, "" + nextRow});
        
        // 将新增的行索引加入高亮集合
        highlightedRows.add(nextRow);
        // 通知表格刷新渲染
        table.repaint();
    }
}

额外说明

  • 我移除了原代码中UIManager.getColor("table.row")==Color.GRAY的判断,因为直接用==比较Color对象可能不准确(不同实例的同色值会返回false),如果需要适配LAF的默认行色,建议用equals或者直接使用表格的默认背景色。
  • 新增了选中行的判断,避免高亮样式覆盖表格默认的选中高亮效果,提升用户体验。
  • 使用Set存储行索引可以自动去重,避免重复添加同一行的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:38:37