如何设置JTable列右对齐且使过长内容从左侧截断
右对齐列内容左侧截断实现方案
实现效果为文本超出显示宽度时从左侧截断、前缀加省略号,同时保持整体右对齐,优先展示右侧关键内容。
- 核心实现逻辑为自定义支持左侧截断的JLabel组件,重写绘制逻辑,根据组件可用宽度动态裁剪文本:
import javax.swing.*; import java.awt.*; public class LeftTruncatedRightAlignedLabel extends JLabel { private static final String ELLIPSIS = "..."; public LeftTruncatedRightAlignedLabel() { // 默认设置右对齐 setHorizontalAlignment(SwingConstants.RIGHT); } @Override protected void paintComponent(Graphics g) { String rawText = getText(); if (rawText == null || rawText.isEmpty()) { super.paintComponent(g); return; } FontMetrics fontMetrics = g.getFontMetrics(); Insets insets = getInsets(); int availableWidth = getWidth() - insets.left - insets.right; int fullTextWidth = fontMetrics.stringWidth(rawText); // 文本未超出宽度直接绘制 if (fullTextWidth <= availableWidth) { super.paintComponent(g); return; } // 计算省略号占位宽度,倒推可保留的右侧文本长度 int ellipsisWidth = fontMetrics.stringWidth(ELLIPSIS); int remainTextWidth = availableWidth - ellipsisWidth; int textLength = rawText.length(); int keepCharNum = 0; int currentWidth = 0; for (int i = textLength - 1; i >= 0; i--) { int charWidth = fontMetrics.charWidth(rawText.charAt(i)); if (currentWidth + charWidth > remainTextWidth) { break; } currentWidth += charWidth; keepCharNum++; } // 临时替换文本为截断后内容完成绘制 String truncatedText = ELLIPSIS + rawText.substring(textLength - keepCharNum); setText(truncatedText); super.paintComponent(g); // 还原原始文本不影响组件属性 setText(rawText); } }
- 如果需要在JTable的右对齐列中使用该效果,将自定义组件注册为对应列的单元格渲染器即可:
// targetColumnIndex替换为实际要设置的列下标 table.getColumnModel().getColumn(targetColumnIndex).setCellRenderer(new DefaultTableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { LeftTruncatedRightAlignedLabel renderLabel = new LeftTruncatedRightAlignedLabel(); renderLabel.setText(value != null ? value.toString() : ""); // 适配表格选中态样式 renderLabel.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground()); renderLabel.setForeground(isSelected ? table.getSelectionForeground() : table.getForeground()); renderLabel.setOpaque(true); return renderLabel; } });
以上实现已适配不同字体、字号的宽度计算,不会出现截断长度与实际显示不匹配的问题,省略号固定展示在左侧截断位置,右侧关键内容完整可见,全程保持右对齐的布局要求。
内容的提问来源于stack exchange,提问作者Reto Höhener
相关产品推荐
相关产品推荐

