Code
class TextAreaCellRenderer extends JTextArea implements TableCellRenderer {
private final List< List< Integer > > rowAndCellHeightList = new ArrayList<>();
@Override public void updateUI() {
super.updateUI();
setLineWrap(true);
setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
setName("Table.cellRenderer");
}
@Override public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
setFont(table.getFont());
setText(Objects.toString(value, ""));
adjustRowHeight(table, row, column);
return this;
}
/**
* Calculate the new preferred height for a given row, and sets the height on the table.
* http://blog.botunge.dk/post/2009/10/09/JTable-multiline-cell-renderer.aspx
*/
private void adjustRowHeight(JTable table, int row, int column) {
// The trick to get this to work properly is to set the width of the column to the
// textarea. The reason for this is that getPreferredSize(), without a width tries
// to place all the text in one line. By setting the size with the with of the column,
// getPreferredSize() returnes the proper height which the row should have in
// order to make room for the text.
// int cWidth = table.getTableHeader().getColumnModel().getColumn(column).getWidth();
// int cWidth = table.getCellRect(row, column, false).width; //Ignore IntercellSpacing
// setSize(new Dimension(cWidth, 1000));
setBounds(table.getCellRect(row, column, false));
// doLayout();
int preferredHeight = getPreferredSize().height;
while (rowAndCellHeightList.size() <= row) {
rowAndCellHeightList.add(new ArrayList<>(column));
}
List cellHeightList = rowAndCellHeightList.get(row);
while (cellHeightList.size() <= column) {
cellHeightList.add(0);
}
cellHeightList.set(column, preferredHeight);
int max = cellHeightList.stream().max(Integer::compare).get();
if (table.getRowHeight(row) != max) {
table.setRowHeight(row, max);
}
}
// ...
References