Swing/TableRowSorter の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/TableRowSorter へ行く。
- Swing/TableRowSorter の差分を削除
--- category: swing folder: TableRowSorter title: TableRowSorterでJTableのソート tags: [JTable, TableRowSorter, JTableHeader] author: aterai pubdate: 2007-02-12T18:36:03+09:00 description: JDK 6で導入されたTableRowSorterを利用してJTableの行を降順、昇順にソートします。 image: https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTUnbg2jyI/AAAAAAAAAmU/-7yjlGSjBmo/s800/TableRowSorter.png --- * 概要 [#summary] `JDK 6`で導入された`TableRowSorter`を利用して`JTable`の行を降順、昇順にソートします。 #download(https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTUnbg2jyI/AAAAAAAAAmU/-7yjlGSjBmo/s800/TableRowSorter.png) * サンプルコード [#sourcecode] #code(link){{ TableModel model = makeTestTableModel(); JTable table = new JTable(model); RowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model); table.setRowSorter(sorter); }} * 解説 [#explanation] `JDK 6`では`JTable`に`TableRowSorter`を設定することでカラムヘッダのクリックによる行ソートが行えます。 - 以下のように`JTable#autoCreateRowSorter(true)`メソッドを使用した場合も、`JTable`が自動的に`RowSorter`を作成してソートが可能になる #code{{ JTable table = new JTable(model); table.setAutoCreateRowSorter(true); }} ---- - `TableRowSorter`のデフォルトではヘッダクリックで(降順、昇順)とソートが切り替わり、`TableSorter.java`のように(降順、昇順、初期状態)ではなくなっている -- このページのサンプルでは`BorderLayout.SOUTH`に配置したボタンをクリックすると`DefaultRowSorter#setSortKeys(List)`に`null`を代入することで初期状態に戻るよう設定している - `SwingLabs`の`JXTable`のように「KBD{Shift}+ヘッダクリック」で初期状態に戻す -- [[TableRowSorterのSortKeysをクリアする>Swing/ClearSortingState]] - `TableSorter.java`のようにヘッダクリックで降順、昇順、初期状態とループ -- [[TableRowSorterのソートをヘッダクリックで昇順、降順、初期状態に変更>Swing/TriStateSorting]] ---- - %%第二キーを使ったソートは`TableRowSorter`版では存在しない?ため`TableSorter.java`を使う場合もまだあるかもしれない。%% - `TableRowSorter`でも`TableSorter.java`と同様に複数キーを使ったソートが可能 -- ページ下部にあるsyoさんのコメントを参照 - デフォルトではソートキーは`3`つでヘッダにマークが表示されるのは最新のソートキーのみだがクリックした順に保持される - デフォルトではソートキーは`3`つまでクリックした順に保持されるが、ヘッダにマークが表示されるのは最新のソートキーのみ -- 参考: [http://syo.cocolog-nifty.com/freely/2006/08/table_616d.html Tableの内容をソート] - [https://tips4java.wordpress.com/2010/08/29/multisort-table-header-cell-renderer/ Multisort Table Header Cell Renderer « Java Tips Weblog] -- 第二キー以下を薄く表示するサンプルがある - [[JTableの複数キーを使ったソートをヘッダに表示する>Swing/MultisortHeaderRenderer]] -- ソートキーの状態を文字列にして追加 ---- - `TableModel`に要素を追加した後で、`table.setRowSorter(sorter);`とすると、`IndexOutOfBoundsException`: `Invalid range`が、モデルへの追加、削除、編集中に別の行クリックなどで発生する -- 以下のサンプルの場合、`model.fireTableDataChanged()`メソッドを`table.setRowSorter(sorter)`の後で呼び出すと回避可能 - `TableModel`に要素を追加した後で`table.setRowSorter(sorter);`とすると、`IndexOutOfBoundsException`: `Invalid range`がモデルへの追加、削除、編集中に別の行クリックなどで発生する -- 以下のサンプルの場合`model.fireTableDataChanged()`メソッドを`table.setRowSorter(sorter)`の後で呼び出すと回避可能 #code{{ 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); } } }} - [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/RowSorter.html RowSorter (Java Platform SE 8)] > `RowSorter`の具象実装は、`TableModel`、`ListModel`などのモデルを参照する必要があります。`JTable`や`JList`などのビュークラスも、モデルを参照します。順序の依存性を回避するため、`RowSorter`実装がモデル上にリスナーをインストールしないようにしてください。モデルが変更されると、ビュークラスが`RowSorter`を呼び出します。例えば、`TableModel` `JTable` で行が更新された場合、`rowsUpdated`が呼び出されます。モデルが変更されると、ビューは、`modelStructureChanged`、`allRowsChanged`、`rowsInserted`、`rowsDeleted`、`rowsUpdated`のいずれかのメソッドを呼び出します。 * 参考リンク [#reference] - [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/table/TableRowSorter.html TableRowSorter (Java Platform SE 8)] - [https://docs.oracle.com/javase/tutorial/uiswing/components/table.html How to Use Tables] - [[TableSorterでJTableをソート>Swing/TableSorter]] - [[TableRowSorterのSortKeysをクリアする>Swing/ClearSortingState]] - [[TableRowSorterのソートをヘッダクリックで昇順、降順、初期状態に変更>Swing/TriStateSorting]] - [http://syo.cocolog-nifty.com/freely/2006/08/table_616d.html Tableの内容をソート] * コメント [#comment] #comment - `DefaultRowSorter#setMaxSortKeys(int)`で複数のキーを用いたソートも出来ているように思います(`b86`)。ただ、ヘッダー部分がわかりにくいですが。 -- &user(syo); &new{2006-08-03 (木) 11:12:55}; -- ご指摘ありがとうございます。なるほど、こちら([http://syo.cocolog-nifty.com/freely/2006/08/table_616d.html Tableの内容をソート])を使えばうまくいきそうですね。解説を修正しました。 -- &user(aterai); &new{2006-08-03 (木) 12:34:53}; - `renderer`がないので、基本的に数字は左揃え、文字列は右揃えで、中央揃えするにはどうすれば宜しいでしょうか? -- &user(パンダ); &new{2007-06-14 (木) 09:40:20}; --長いので[[JTableのセル文字揃え>Swing/CellTextAlignment]]に移動しました。 -- &user(aterai); &new{2007-06-14 (木) 13:19:36}; #comment