默认情况下,
JTable
会截断对于带有省略号的单元格来说太长的字符串。
我只想剪辑,就像在 macOS 的控制台应用程序中一样。
我已经看到了一个以前的答案,它允许通过覆盖
LabelUI
用其他东西替换省略号,但我不确定(1)如何使用DefaultTableCellRenderer
来实现这个以及(2)我想要这个应用程序是跨平台的,所以我不认为我可以覆盖像MetalUI
这样的特定类并期望它能够工作。
一个想法可能是将默认安装的渲染器放在
JScrollPane
中。这背后的原因是您不需要自定义 JTable
附带的渲染器(因此这听起来很有希望实现可移植性)。 JScrollPane
还确保默认渲染器(JLabel
)永远不会获得比其首选尺寸更小的尺寸(即没有文本剪辑)。您只需隐藏JScrollPane
的滚动条即可。
示例代码:
import java.awt.Component;
import java.awt.Font;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
public class TableCellTrunc {
public static class ScrollDecoratorRenderer implements TableCellRenderer {
private final TableCellRenderer decorated;
private final JScrollPane pane;
public ScrollDecoratorRenderer(final TableCellRenderer decorated) {
this.decorated = Objects.requireNonNull(decorated);
pane = new JScrollPane();
pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
pane.setBorder(BorderFactory.createEmptyBorder());
}
@Override
public Component getTableCellRendererComponent(final JTable table,
final Object value,
final boolean isSelected,
final boolean hasFocus,
final int row,
final int column) {
pane.setViewportView(decorated.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column));
return pane;
}
}
private static Font enlargeFont(final Font font) {
return font.deriveFont(font.getSize2D() * 1.2f);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(() -> {
/*try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException exception) {
System.err.println("Failed to set system L&F.");
}*/
// Create data to fill the table:
final int columnsCount = 3, rowsCount = 5;
final String textExtension = " - huge but necessary text";
final DefaultTableModel model = new DefaultTableModel();
for (int columnIndex = 0; columnIndex < columnsCount; ++columnIndex)
model.addColumn("Column " + columnIndex + textExtension);
for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
final List<String> row = new ArrayList<>(columnsCount);
for (int columnIndex = 0; columnIndex < columnsCount; ++columnIndex)
row.add("Column " + columnIndex + " - Row " + rowIndex + textExtension);
model.addRow(row.toArray());
}
final JTable table = new JTable(model);
final JTableHeader header = table.getTableHeader();
// Apply custom renderer to header and/or table:
header.setDefaultRenderer(new ScrollDecoratorRenderer(header.getDefaultRenderer()));
table.setDefaultRenderer(Object.class, new ScrollDecoratorRenderer(table.getDefaultRenderer(Object.class)));
// Enlarge font size for demonstration (optional):
header.setFont(enlargeFont(header.getFont()));
table.setFont(enlargeFont(table.getFont()));
table.setRowHeight(header.getPreferredSize().height); // Simple way to accomodate larger font (only applicable in this case, and not intended as a general purpose solution).
// Truncate bottom empty space of table (optional):
table.setPreferredScrollableViewportSize(table.getPreferredSize());
// Show result:
final JFrame frame = new JFrame("Table cell trunc");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
您也可以在标头中应用完全相同的原则(如示例代码所示)。这也针对 Windows 10 系统 L&F 进行了测试,显示出类似的行为。
但它有一些小限制,到目前为止我未能缓解:
header.setFont(enlargeFont(header.getFont()));
table.setFont(enlargeFont(table.getFont()));
那么你还需要以下一项:
table.setRowHeight(header.getPreferredSize().height);
因为否则,对于默认的表格大小和字体,相对于单元格的底部(即每个单元格的文本似乎与单元格的底部稍微更对齐),可以在每个单元格的顶部观察到稍大的边距。 这个方法似乎需要一些调整,但它们又似乎与边界的小问题有关。