---
category: swing
folder: RestoreTableColumnOrder
title: JTableのTableColumnの表示順を初期状態に戻す
tags: [JTable, JTableHeader, TableColumn, TableColumnModel]
author: aterai
pubdate: 2016-10-03T00:51:19+09:00
description: JTableのTableColumnの表示順が入れ替えられていた場合、それを初期状態(モデル順)に戻します。
image: https://drive.google.com/uc?id=1uR48L0Uvm0mBLPOYXx8IR1VJYp0KVzuiAQ
---
* 概要 [#summary]
`JTable`の`TableColumn`の表示順が入れ替えられていた場合、それを初期状態(モデル順)に戻します。

#download(https://drive.google.com/uc?id=1uR48L0Uvm0mBLPOYXx8IR1VJYp0KVzuiAQ)

* サンプルコード [#sourcecode]
#code(link){{
TableColumnModel m = table.getColumnModel();
if (m instanceof SortableTableColumnModel) {
    ((SortableTableColumnModel) m).restoreColumnOrder();
}
// ...
class SortableTableColumnModel extends DefaultTableColumnModel {
  public void restoreColumnOrder() {
    Collections.sort(
        tableColumns,
        Comparator.comparingInt(TableColumn::getModelIndex));
    fireColumnMoved(new TableColumnModelEvent(this, 0, tableColumns.size()));
  }
}
}}

* 解説 [#explanation]
上記のサンプルでは、`DefaultTableColumnModel`の`protected Vector<TableColumn> tableColumns`を`TableColumn`のモデル・インデックス(`TableColumn#getModelIndex()`メソッドで取得可能)で直接ソートすることで入れ替え前の初期状態を復元しています。

- `tableColumns`メソッドは`protected`なので、ソートは`DefaultTableColumnModel`を継承するクラス内で実行する
-- `JTable#createDefaultColumnModel()`をオーバーライドしてこの`TableColumnModel`を使用する
-- ソート後`fireColumnMoved(...)`で`TableColumn`の移動を通知し、再描画を実行する必要がある
- 直接`tableColumns`をソートするのではなく、以下のように`TableColumnModel#moveColumn(...)`メソッドなどを使用してソートする方法もある
- 直接`tableColumns`をソートするのではなく、以下のように[https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/table/TableColumnModel.html#moveColumn-int-int- TableColumnModel#moveColumn(int, int)]メソッドなどを使用してソートする方法もある

#code{{
public static void sortTableColumn(TableColumnModel model) {
  // selection sort
  int n = model.getColumnCount();
  for (int i = 0; i < n - 1; i++) {
    TableColumn c = (TableColumn) model.getColumn(i);
    for (int j = i + 1; j < n; j++) {
      TableColumn p = (TableColumn) model.getColumn(j);
      if (c.getModelIndex() - p.getModelIndex() > 0) {
        model.moveColumn(j, i);
        i -= 1;
        break;
      }
    }
  }
}
}}

* 参考リンク [#reference]
- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/event/TableColumnModelEvent.html TableColumnModelEvent (Java Platform SE 8)]
- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/table/TableColumnModel.html#moveColumn-int-int- TableColumnModel#moveColumn(int, int) (Java Platform SE 8)]

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