getTableCellRendererComponent设置背景为何全列生效及强转疑问
问题原理解答
问题一:背景色作用到所有列的原因
- Swing的JTable默认采用渲染器组件复用机制:为了优化性能,不会为每个单元格单独创建渲染组件,整列甚至全表都会共用同一个渲染器实例(也就是你代码中myRenderer返回的JLabel实例),每次渲染单元格仅修改该实例的属性,不会创建新对象。
- 你的代码仅对
row==0&&column==0和row==1&&column==0两种场景设置了背景色,其他单元格渲染时没有主动将背景色重置为默认值,上一次渲染留下的背景色会被复用,导致所有未单独设置色值的单元格都沿用了之前的配置。 - 如果你将该自定义渲染器设置给了表格的所有列,复用范围会覆盖全表所有单元格,串色现象会更明显。
问题二:去掉强转后仍显示firstColor的原因
DefaultTableCellRenderer本身是JLabel的子类,你从super.getTableCellRendererComponent拿到的label实例本质就是DefaultTableCellRenderer对象,JLabel本身已经公开了setBackground方法,强转成DefaultTableCellRenderer调用setBackground和直接用label调用该方法,执行逻辑完全一致,强转属于多余操作,不会产生任何效果差异。- 去掉强转后仍显示firstColor的核心原因是你没有执行
setBackground(secondColor)调用:渲染完(0,0)单元格后,公用的label实例已经被设置为firstColor,接下来渲染(1,0)单元格时,仅设置了文本和对齐方式,没有修改背景色,实例自带的firstColor就会被沿用,所以显示firstColor。 - 如果你在第二个if里主动调用
setBackground(secondColor),不管是否加强转,都会覆盖之前的firstColor,自然就能显示不同的颜色。
修复方案
可以在执行自定义逻辑前先重置渲染器的默认状态,避免状态复用导致的串色:
@Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // 先重置默认背景色 if (isSelected) { label.setBackground(table.getSelectionBackground()); } else { label.setBackground(table.getBackground()); } // 再执行自定义渲染逻辑 String tableName = table.getName(); displayData(row, column, label, value, tableName); return label; }
内容的提问来源于stack exchange,提问作者Kenny
相关产品推荐
相关产品推荐

