---
category: swing
folder: StandingsTablesComparator
title: JTableの行を複数条件でソートする
tags: [JTable, TableRowSorter, Comparator]
author: aterai
pubdate: 2023-10-09T09:27:32+09:00
description: JTableの列に複数のソートキーを使用するComparatorを設定して複合ソートを実行します。
image: https://drive.google.com/uc?id=1LcVXjsezO1iupUupSIZ29iykap7BqIrj
hreflang:
    href: https://java-swing-tips.blogspot.com/2023/10/sort-jtable-rows-with-multiple.html
    lang: en
---
* 概要 [#summary]
`JTable`の列に複数のソートキーを使用する`Comparator`を設定して複合ソートを実行します。

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

* サンプルコード [#sourcecode]
#code(link){{
RowSorter<? extends TableModel> sorter = table.getRowSorter();
if (sorter instanceof TableRowSorter) {
  TableRowSorter<? extends TableModel> rs
      = (TableRowSorter<? extends TableModel>) sorter;
  rs.setComparator(0, Comparator.comparing(RowData::getPosition));
  rs.setComparator(1, Comparator.comparing(RowData::getTeam));
  rs.setComparator(2, Comparator.comparing(RowData::getMatches));
  rs.setComparator(3, Comparator.comparing(RowData::getWins));
  rs.setComparator(4, Comparator.comparing(RowData::getDraws));
  rs.setComparator(5, Comparator.comparing(RowData::getLosses));
  rs.setComparator(6, Comparator.comparing(RowData::getGoalsFor));
  rs.setComparator(7, Comparator.comparing(RowData::getGoalsAgainst));
  rs.setComparator(8, Comparator.comparing(RowData::getGoalDifference));
  rs.setComparator(9, Comparator.comparing(RowData::getPoints)
      .thenComparing(RowData::getGoalDifference));
}
add(new JScrollPane(table));
}}

* 解説 [#explanation]
- [[JTableの水平罫線を描画する位置とその色をソート条件に応じて変更する>Swing/StandingsTables]]に以下のような修正を追加して同様の列表示が可能な順位表を作成
-- 実際の順位やチーム名、勝ち点、得失点ではなく、これらをまとめた`RowData`を以下のように列数分コピーして`DefaultTableModel`を作成するよう変更
--- `DefaultTableModel#addRow(Collections.nCopies(10, new RowData(1, "Team", 33, 20, 7, 6, 57, 27)).toArray());`
-- `DefaultTableModel#getColumnClass(int column)`をオーバーライドして全セルの`Class<?>`が`RowData.class`となるよう設定
-- `JTable#setDefaultRenderer(RowData.class, ...)`で各列には`RowData`ではなく`RowData`から取得した順位やチーム名、勝ち点を表示するセルレンダラーを設定
- `TableRowSorter#setComparator(int column, Comparator<?> comparator)`で`RowData`ではなく列に対応した順位などを`RowData`から取得してソートする`Comparator`を作成して設定
-- たとえば`9`列目の勝ち点用の`Comparator`はソートキー`RowData::getPoints`で比較し、さらに勝ち点が等しい場合は得失点差`RowData::getGoalDifference`で比較するよう設定している

* 参考リンク [#reference]
- [[JTableでファイルとディレクトリを別々にソート>Swing/FileDirectoryComparator]]
- [[JTableの水平罫線を描画する位置とその色をソート条件に応じて変更する>Swing/StandingsTables]]
- [[JTableの複数キーを使ったソートをヘッダに表示する>Swing/MultisortHeaderRenderer]]

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