如何通过TableCellRenderer为JTable单元格特定字符设置前景色?
实现JTable单元格内部分文本变色(数字高亮)
完全可以实现,你需要自定义TableCellRenderer,借助富文本渲染来给指定字符(这里是数字)单独设置颜色,而非给整个单元格文本统一设色。下面提供两种实用方案:
方案一:基于HTML的简易实现
JTable的默认渲染组件是JLabel,而JLabel支持解析HTML文本。我们可以把单元格内容转换成带样式的HTML字符串,让数字部分显示为蓝色。
代码示例
import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; import java.awt.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class HighlightNumberRenderer extends DefaultTableCellRenderer { // 匹配数字的正则表达式 private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+)"); @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if (value != null) { String originalText = value.toString(); Matcher matcher = NUMBER_PATTERN.matcher(originalText); // 把所有数字替换成带蓝色样式的HTML标签 String htmlText = matcher.replaceAll("<span style='color:blue;'>$1</span>"); // 包裹成完整的HTML结构 setText("<html>" + htmlText + "</html>"); } // 处理选中状态的背景色,保持和默认Renderer一致 if (isSelected) { setBackground(table.getSelectionBackground()); setForeground(table.getSelectionForeground()); } else { setBackground(table.getBackground()); // 非选中状态下,普通文本用黑色 setForeground(Color.BLACK); } return this; } }
使用方式
给目标列设置这个渲染器:
// 假设你的JTable是table,要设置的是第2列(索引从0开始) table.getColumnModel().getColumn(1).setCellRenderer(new HighlightNumberRenderer());
方案二:基于StyledDocument的灵活实现
如果需要更复杂的文本样式(比如不同字号、字体),可以用JTextPane作为渲染组件,通过StyledDocument精准控制每个字符的样式。
代码示例
import javax.swing.*; import javax.swing.table.TableCellRenderer; import javax.swing.text.*; import java.awt.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class StyledNumberRenderer extends JTextPane implements TableCellRenderer { private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+)"); private final Style defaultStyle; private final Style numberStyle; public StyledNumberRenderer() { setOpaque(true); StyledDocument doc = getStyledDocument(); // 普通文本样式:黑色 defaultStyle = doc.addStyle("default", null); StyleConstants.setForeground(defaultStyle, Color.BLACK); // 数字样式:蓝色 numberStyle = doc.addStyle("number", null); StyleConstants.setForeground(numberStyle, Color.BLUE); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // 设置背景色,匹配选中状态 if (isSelected) { setBackground(table.getSelectionBackground()); } else { setBackground(table.getBackground()); } StyledDocument doc = getStyledDocument(); try { doc.remove(0, doc.getLength()); if (value != null) { String text = value.toString(); Matcher matcher = NUMBER_PATTERN.matcher(text); int lastEnd = 0; // 逐个匹配数字,分段添加不同样式的文本 while (matcher.find()) { // 添加数字之前的普通文本 doc.insertString(doc.getLength(), text.substring(lastEnd, matcher.start()), defaultStyle); // 添加数字文本(蓝色) doc.insertString(doc.getLength(), matcher.group(), numberStyle); lastEnd = matcher.end(); } // 添加最后一段普通文本 if (lastEnd < text.length()) { doc.insertString(doc.getLength(), text.substring(lastEnd), defaultStyle); } } } catch (BadLocationException e) { e.printStackTrace(); } return this; } }
使用方式
同样给目标列设置渲染器:
table.getColumnModel().getColumn(1).setCellRenderer(new StyledNumberRenderer());
注意事项
- 方案一实现简单,适合大多数场景;方案二更灵活,适合需要多种复杂样式的情况。
- 如果表格数据量极大,HTML渲染可能会有轻微的性能损耗,此时StyledDocument方案更优。
- 两种方案都保持了JTable默认的选中、聚焦等状态的样式一致性,不会破坏原有表格的交互体验。
内容的提问来源于stack exchange,提问作者charly
相关产品推荐
相关产品推荐

