概要

JTableがリサイズされた場合、最後にあるTableColumnがその幅の変更を吸収するように設定します。主にjava - JTable columns doesnt resize probably when JFrame resize - Stack Overflowの回答からソースを引用しています。

サンプルコード

private final JTable table = new JTable(100, 3) {
  @Override public void doLayout() {
    Optional.ofNullable(getTableHeader()).ifPresent(h -> {
      if (Objects.isNull(h.getResizingColumn())
          && getAutoResizeMode() == AUTO_RESIZE_LAST_COLUMN) {
        TableColumnModel tcm = getColumnModel();
        h.setResizingColumn(tcm.getColumn(tcm.getColumnCount() - 1));
      }
    });
    super.doLayout();
  }
};
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、JFrameに連動してJTableJTableHeaderがリサイズされた場合、最後のTableColumnが幅の変更をすべて吸収するようにJTable#doLayout()のオーバーライドやJTableHeader.setResizingColumn(...)の設定を行なっています。

  • table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);を設定しても例えば親JFrameの幅が変更されてJTableHeader自体がリサイズされた場合、すべてのTableColumnの幅が均等に変化してしまう
  • 列を入れ替えた場合でも表示上最後にあるTableColumnがリサイズされる
  • 以下のようにJTable#doLayout()をオーバーライドではなくJTableまたはJTableHeaderComponentListenerを追加しても同様の動作になるが、リサイズ開始時に最後のTableColumnにも幅の変更が適用されてしまうため微妙に幅が変化してしまう場合がある(先にJTable#doLayout()が実行される)
JTable table2 = new JTable(100, 3);
table2.getTableHeader().addComponentListener(new ComponentAdapter() {
  @Override public void componentResized(ComponentEvent e) {
    JTableHeader tableHeader = (JTableHeader) e.getComponent();
    if (tableHeader == null) {
      return;
    }
    if (check.isSelected()) {
      TableColumnModel tcm = tableHeader.getTable().getColumnModel();
      int lastColumn = tcm.getColumnCount() - 1;
      tableHeader.setResizingColumn(tcm.getColumn(lastColumn));
    } else {
      tableHeader.setResizingColumn(null);
    }
  }
});

参考リンク

コメント