TITLE:RowFilterでJTableの行をフィルタリング
Posted by aterai at 2007-09-03

RowFilterでJTableの行をフィルタリング

JDK 6 で導入されたTableRowSorterにRowFilterを設定して、行のフィルタリングを行います。
  • category: swing folder: RowFilter title: RowFilterでJTableの行をフィルタリング tags: [JTable, TableRowSorter, RowFilter] author: aterai pubdate: 2007-09-03T15:45:16+09:00 description: JDK 6で導入されたTableRowSorterにRowFilterを設定して、行のフィルタリングを行います。 image: https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTST-FvjRI/AAAAAAAAAik/ZbU9nuVVCiI/s800/RowFilter.png

概要

JDK 6で導入されたTableRowSorterRowFilterを設定して、行のフィルタリングを行います。
RowFilter.png

サンプルコード

#spanend
#spandel
final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
#spanend
#spandel
final Set<RowFilter<TableModel,Integer>> filters = new HashSet<RowFilter<TableModel,Integer>>(2);
#spanend
#spandel
final RowFilter<TableModel,Integer> filter1 = new RowFilter<TableModel,Integer>() {
#spanend
  @Override
  public boolean include(Entry<? extends TableModel, ? extends Integer> entry) {
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
#spanadd
TableRowSorter<? extends TableModel> sorter = new TableRowSorter<>(model);
#spanend
#spanadd
Collection<RowFilter<? super TestModel, ? super Integer>> filters = new HashSet<>(2);
#spanend
#spanadd
RowFilter<TableModel, Integer> filter1 = new RowFilter<TableModel, Integer>() {
#spanend
  @Override public boolean include(
      Entry<? extends TableModel, ? extends Integer> entry) {
    TableModel model = entry.getModel();
    Test t = model.getTest(entry.getIdentifier());
    return !t.getComment().trim().isEmpty();
  }
};
#spandel
final RowFilter<TableModel,Integer> filter2 = new RowFilter<TableModel,Integer>() {
#spanend
  @Override
  public boolean include(Entry<? extends TableModel, ? extends Integer> entry) {
#spanadd
RowFilter<TableModel, Integer> filter2 = new RowFilter<TableModel, Integer>() {
#spanend
  @Override public boolean include(
      Entry<? extends TableModel, ? extends Integer> entry) {
    return entry.getIdentifier() % 2 == 0;
  }
};
sorter.setRowFilter(RowFilter.andFilter(filters));
//sorter.setRowFilter(filter1);

解説

上記のサンプルは、以下のような複数の行フィルタを、and条件でJTableに適用することができます。
  • コメントが空でない行のみ表示
  • 行番号が偶数の場合のみ表示
    • 行番号はソートされている場合でも、元のモデルのインデックスで判断する

解説

上記のサンプルは、以下のような複数の行フィルタをand条件でJTableに適用しています。

参考リンク

コメント

  • (1.6.0_02) modelに要素を追加する前にtable.setRowSorter(sorter);しておかないと、IndexOutOfBoundsException: Invalid range が、モデルへの追加、削除、編集中に別の行クリックなどで発生する? -- aterai
  • メモ:Swing - TableRowSorter && IndexOutOfBound DefaultTableModelと相性が悪いのかも。 -- aterai
    #spanend
    #spandel
    import java.awt.*;
    #spanend
    #spandel
    import java.awt.event.*;
    #spanend
    #spandel
    import javax.swing.*;
    #spanend
    #spandel
    import javax.swing.table.*;
    #spanend
    #spandel
    public class RowSorterTest extends JPanel{
    #spanend
      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
        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);
      }
    #spandel
    }
    #spanend
    #spandel
    
  • メモ: TableRowSorterばっかりみてて、RowSorter (Java Platform SE 6)見てなかった。上の件は、以下と関係ありそう? -- aterai
    • RowSorter の具象実装は、TableModel、ListModel などのモデルを参照する必要があります。JTable や JList などのビュークラスも、モデルを参照します。順序の依存性を回避するため、RowSorter 実装がモデル上にリスナーをインストールしないようにしてください。モデルが変更されると、ビュークラスが RowSorter を呼び出します。たとえば、TableModel JTable で行が更新された場合、 rowsUpdated が呼び出されます。モデルが変更されると、ビューは、 modelStructureChanged、allRowsChanged、rowsInserted、rowsDeleted、rowsUpdated のいずれかのメソッドを呼び出します。

参考リンク

コメント