---
category: swing
folder: ResizingColumnAndTable
title: JTableのリサイズで最後のTableColumnのみリサイズする
tags: [JTable, JTableHeader, TableColumn]
author: aterai
pubdate: 2014-05-26T00:01:15+09:00
description: JTableがリサイズされた場合、最後にあるTableColumnがその幅の変更を吸収するように設定します。
image: https://lh4.googleusercontent.com/-uhbVwRqsa2g/U4HyPhrI8PI/AAAAAAAACF8/OJXWaFVxavE/s800/ResizingColumnAndTable.png
---
* 概要 [#summary]
`JTable`がリサイズされた場合、最後にある`TableColumn`がその幅の変更を吸収するように設定します。主に[https://stackoverflow.com/questions/23201818/jtable-columns-doesnt-resize-probably-when-jframe-resize java - JTable columns doesnt resize probably when JFrame resize - Stack Overflow]の回答からソースを引用しています。

#download(https://lh4.googleusercontent.com/-uhbVwRqsa2g/U4HyPhrI8PI/AAAAAAAACF8/OJXWaFVxavE/s800/ResizingColumnAndTable.png)

* サンプルコード [#sourcecode]
#code(link){{
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();
  }
};
}}

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

- `table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);`を設定しても例えば親`JFrame`の幅が変更されて`JTableHeader`自体がリサイズされた場合、すべての`TableColumn`の幅が均等に変化してしまう
-- [https://bugs.openjdk.org/browse/JDK-8234071 [JDK-8234071] JTable.AUTO_RESIZE_LAST_COLUMN acts like AUTO_RESIZE_ALL_COLUMNS - Java Bug System]で修正されるかも?
- 列を入れ替えた場合でも表示上最後にある`TableColumn`がリサイズされる
- 以下のように`JTable#doLayout()`をオーバーライドではなく`JTable`または`JTableHeader`に`ComponentListener`を追加しても同様の動作になるが、リサイズ開始時に最後の`TableColumn`にも幅の変更が適用されてしまうため微妙に幅が変化してしまう場合がある(先に`JTable#doLayout()`が実行される)

#code{{
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);
    }
  }
});
}}

* 参考リンク [#reference]
- [https://stackoverflow.com/questions/23201818/jtable-columns-doesnt-resize-probably-when-jframe-resize java - JTable columns doesnt resize probably when JFrame resize - Stack Overflow]
- [https://stackoverflow.com/questions/16368343/jtable-resize-only-selected-column-when-container-size-changes java - JTable resize only selected column when container size changes - Stack Overflow]
- [https://bugs.openjdk.org/browse/JDK-8234071 [JDK-8234071] JTable.AUTO_RESIZE_LAST_COLUMN acts like AUTO_RESIZE_ALL_COLUMNS - Java Bug System]

* コメント [#comment]
#comment
#comment