Google Tag Manager

2017/06/29

Automatically adjust the height of JTable's row

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