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

JTable选中行高亮时如何保留显示单元格原有背景颜色

JTable 半透明选中高亮实现方案

现有实现选中单元格时直接用纯不透明的浅灰色替换原单元格背景,会完全覆盖预设的单元格底色,要实现类似Excel选中时既保留原有底色、又清晰显示选中状态的半透明效果,只需要调整单元格渲染器的背景色处理逻辑即可。

效果参考

  • 初始自定义单元格背景效果:
    示例初始效果
  • 默认纯不透明选中效果(原有底色被完全遮挡):
    默认选中效果
  • 目标半透明选中效果:
    目标半透明选中效果

实现要点

  • 不要直接给Swing组件设置带Alpha通道的透明背景色,否则会出现重绘残影、脏区问题
  • 先计算单元格未选中状态下的自定义背景色,选中状态下将原背景色和半透明高亮色做RGB混合,得到完全不透明的叠加色再设置给渲染组件
  • 半透明高亮的Alpha值可根据需求调整,取值范围0-255,数值越小透明效果越强,100-140区间的效果接近Excel的选中表现

完整修改后代码

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;

class EvenOddRenderer implements TableCellRenderer {

    public static final DefaultTableCellRenderer DEFAULT_RENDERER = new DefaultTableCellRenderer();
    // 半透明选中高亮色,Alpha值120可按需调整
    private static final Color SELECT_HIGHLIGHT = new Color(192, 192, 192, 120);

    /**
     * 按透明度混合上下两层颜色,返回完全不透明的最终混合色
     */
    private Color mixColor(Color baseColor, Color overlayColor) {
        if (baseColor == null) baseColor = Color.WHITE;
        float alphaRatio = overlayColor.getAlpha() / 255f;
        int red = (int) (overlayColor.getRed() * alphaRatio + baseColor.getRed() * (1 - alphaRatio));
        int green = (int) (overlayColor.getGreen() * alphaRatio + baseColor.getGreen() * (1 - alphaRatio));
        int blue = (int) (overlayColor.getBlue() * alphaRatio + baseColor.getBlue() * (1 - alphaRatio));
        return new Color(red, green, blue);
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
                                                   boolean isSelected, boolean hasFocus, int row, int column) {
        Component renderer = DEFAULT_RENDERER.getTableCellRendererComponent(table, value,
                isSelected, hasFocus, row, column);
        Color foreground = Color.red;
        Color background = Color.WHITE;

        // 先计算未选中状态下的自定义单元格背景
        if (column == 1 && row == 0) {
            background = Color.GREEN;
        } else if (column == 1 && row == 1) {
            background = Color.CYAN;
        } else if (column == 1 && row == 2) {
            background = Color.ORANGE;
        } else if (column == 2) {
            background = Color.YELLOW;
        }

        // 选中状态下叠加半透明高亮,而不是直接替换背景
        if (isSelected) {
            background = mixColor(background, SELECT_HIGHLIGHT);
        }

        renderer.setForeground(foreground);
        renderer.setBackground(background);
        return renderer;
    }
}

public class CellColorTransparency {
    public static void main(String args[]) {
        final Object rowData[][] = {
                {"1", "one", "I"},
                {"2", "two", "II"},
                {"3", "three", "III"}};
        final String columnNames[] = {"#", "English", "Roman"};

        final JTable table = new JTable(rowData, columnNames);
        JScrollPane scrollPane = new JScrollPane(table);
        table.setDefaultRenderer(Object.class, new EvenOddRenderer());

        JFrame frame = new JFrame("Color Test Table");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(scrollPane, BorderLayout.CENTER);
        frame.setSize(300, 150);
        frame.setVisible(true);
    }
}

运行上述代码即可实现选中时半透明叠加原有单元格背景色的效果,不会出现原有底色被完全覆盖的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:06:24