TableRowSorterでJTableのソート
Total: 42496, Today: 1, Yesterday: 3
Posted by aterai at
Last-modified:
Summary
JDK 6で導入されたTableRowSorterを利用してJTableの行を降順、昇順にソートします。
Screenshot

Advertisement
Source Code Examples
TableModel model = makeTestTableModel();
JTable table = new JTable(model);
RowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
table.setRowSorter(sorter);
View in GitHub: Java, KotlinDescription
JDK 6ではJTableにTableRowSorterを設定することでカラムヘッダのクリックによる行ソートが行えます。
- 以下のように
JTable#autoCreateRowSorter(true)メソッドを使用した場合も、JTableが自動的にRowSorterを作成してソートが可能になるJTable table = new JTable(model); table.setAutoCreateRowSorter(true);
TableRowSorterのデフォルトではヘッダクリックで(降順、昇順)とソートが切り替わり、TableSorter.javaのように(降順、昇順、初期状態)ではなくなっている- このページのサンプルでは
BorderLayout.SOUTHに配置したボタンをクリックするとDefaultRowSorter#setSortKeys(List)にnullを代入することで初期状態に戻るよう設定している
- このページのサンプルでは
SwingLabsのJXTableのように「Shift+ヘッダクリック」で初期状態に戻すTableSorter.javaのようにヘッダクリックで降順、昇順、初期状態とループ
第二キーを使ったソートはTableRowSorter版では存在しない?ためTableSorter.javaを使う場合もまだあるかもしれない。TableRowSorterでもTableSorter.javaと同様に複数キーを使ったソートが可能- ページ下部にあるsyoさんのコメントを参照
- デフォルトではソートキーは
3つまでクリックした順に保持されるが、ヘッダにマークが表示されるのは最新のソートキーのみ- 参考: Tableの内容をソート
- Multisort Table Header Cell Renderer « Java Tips Weblog
- 第二キー以下を薄く表示するサンプルがある
- JTableの複数キーを使ったソートをヘッダに表示する
- ソートキーの状態を文字列にして追加
TableModelに要素を追加した後でtable.setRowSorter(sorter);とすると、IndexOutOfBoundsException:Invalid rangeがモデルへの追加、削除、編集中に別の行クリックなどで発生する- 以下のサンプルの場合
model.fireTableDataChanged()メソッドをtable.setRowSorter(sorter)の後で呼び出すと回避可能
- 以下のサンプルの場合
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class RowSorterTest extends JPanel {
public RowSorterTest() {
super(new BorderLayout());
final DefaultTableModel model = new DefaultTableModel(null, new String[] {"A", "B", "C"});
JTable table = new JTable(model);
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
// table.setRowSorter(sorter); // OK
model.addRow(new String[] {"aa", "bb", "cc"});
model.addRow(new String[] {"dd", "ee", "ff"});
table.setRowSorter(sorter); // IndexOutOfBoundsException: Invalid range
// model.fireTableDataChanged(); // <----
add(new JButton(new AbstractAction("model.addRow(...); -> IndexOutOfBoundsException") {
@Override public void actionPerformed(ActionEvent e) {
model.addRow(new String[] {"gg", "hh", "ii"});
}
}), BorderLayout.SOUTH);
add(new JScrollPane(table));
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() { createAndShowGUI(); }
});
}
public static void createAndShowGUI() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().add(new RowSorterTest());
frame.setSize(320, 240);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
- RowSorter (Java Platform SE 8)
RowSorterの具象実装は、TableModel、ListModelなどのモデルを参照する必要があります。JTableやJListなどのビュークラスも、モデルを参照します。順序の依存性を回避するため、RowSorter実装がモデル上にリスナーをインストールしないようにしてください。モデルが変更されると、ビュークラスがRowSorterを呼び出します。例えば、TableModelJTableで行が更新された場合、rowsUpdatedが呼び出されます。モデルが変更されると、ビューは、modelStructureChanged、allRowsChanged、rowsInserted、rowsDeleted、rowsUpdatedのいずれかのメソッドを呼び出します。
Reference
- TableRowSorter (Java Platform SE 8)
- How to Use Tables
- TableSorterでJTableをソート
- TableRowSorterのSortKeysをクリアする
- TableRowSorterのソートをヘッダクリックで昇順、降順、初期状態に変更
- Tableの内容をソート