There are several issues when using a JTextArea as rendering component (and most if not all of them already explained in several QA's on this site). Trying to sum them up:
Adjust individual row height to the size requirements of the rendering component
Basically, the way to go is to loop through the cells as needed, then
- configure its renderer with the data
- ask the rendering component for its preferred size
- set the table row height to the pref height
The updateRowHeight method in the OP's edited question is just fine.
JTextArea's calculation of its preferredSize
to get a reasonable sizing hint for one dimension, it needs to be "seeded" with some reasonable size in the other dimension. That is if we want the height it needs a width, and that must be done in each call. In the context of a table, a reasonable width is the current column width:
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
... // configure visuals
setText((String) value);
setSize(table.getColumnModel().getColumn(column).getWidth(),
Short.MAX_VALUE);
return this;
}// getTableCellRendererComponent
Dynamic adjustment of the height
The row height it fully determined in some steady state of the table/column/model. So you set it (call updateRowHeight) once after the initialization is completed and whenever any of the state it depends on is changed.
// TableModelListener
@Override
public void tableChanged(TableModelEvent e) {
updateRowHeights();
}
// TableColumnModelListener
@Override
public void columnMarginChanged(ChangeEvent e) {
updateRowHeights();
}
Note
As a general rule, all parameters in the getXXRendererComponent are strictly read-only, implementations must not change any state of the caller. Updating the rowHeight from within the renderer is wrong.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…