TITLE:JTableの行を全削除
#navi(../)
#tags(JTable, DefaultTableModel)
RIGHT:Posted by &author(aterai); at 2005-04-11
*JTableの行を全削除 [#j3b5fd74]
``JTable``の行を一括で全削除します。

-&jnlp;
-&jar;
-&zip;

//#screenshot
#ref(http://lh5.ggpht.com/_9Z4BYR88imo/TQTJISEHcVI/AAAAAAAAAT4/syR1Ucd5n5o/s800/ClearTable.png)

**サンプルコード [#i0d5d0ba]
#code(link){{
button.addActionListener(new AbstractAction("clear") {
  @Override public void actionPerformed(ActionEvent e) {
    DefaultTableModel model = (DefaultTableModel)table.getModel();
    //ArrayIndexOutOfBoundsException:  0 >= 0
    //Bug ID: JDK-6967479 JTable sorter fires even if the model is empty
    //http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6967479
    table.setRowSorter(null);
    table.getTableHeader().repaint();
    model.setRowCount(0);
  }
});
}}

**解説 [#q9ec8847]
モデルが``DefaultTableModel``を継承しているなら、``setRowCount(0)``ですべての行を削除することができます。この場合、モデルを作り直している訳ではないので、カラムの幅などは削除する前と同じ値を保っています。

``DefaultTableModel``を継承していない場合は、モデルに以下の要領(詳細は``DefaultTableModel.java``のソースを参照)で行を全削除するメソッドを実装します。

#code{{
public void clear() {
  //以下のdataVectorは実装に合わせて変更する
  int size = dataVector.size();
  dataVector.clear();
  fireTableRowsDeleted(0, size-1);
  //fireTableDataChanged();
}
}}

----
``JTable#setAutoCreateColumnsFromModel(false)``としておけば、``TableModel``を入れ替えても、上記の方法と同じように既存の列はクリアされません。

#code{{
//((DefaultTableModel)table.getModel()).setRowCount(0);
table.setAutoCreateColumnsFromModel(false);
table.setModel(new DefaultTableModel());
}}

----
コメントにある[http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6967479 Bug ID: JDK-6967479 JTable sorter fires even if the model is empty]のバグに一時的に対応するため、``JTable``が空の場合は、ソートしないように行の追加削除も以下のように修正しています。

#code{{
private class TestCreateAction extends AbstractAction{
  public TestCreateAction(String label, Icon icon) {
    super(label,icon);
  }
  @Override public void actionPerformed(ActionEvent evt) {
    if(model.getRowCount()==0) {
      //table.setRowSorter(new TableRowSorter<TableModel>(model));
      table.setRowSorter(sorter);
      model.fireTableDataChanged();
    }
    model.addRow(new Object[] {"", model.getRowCount(), false});
    Rectangle r = table.getCellRect(model.getRowCount()-1, 0, true);
    table.scrollRectToVisible(r);
  }
}

private class DeleteAction extends AbstractAction{
  public DeleteAction(String label, Icon icon) {
    super(label,icon);
  }
  @Override public void actionPerformed(ActionEvent evt) {
    int[] selection = table.getSelectedRows();
    if(selection==null || selection.length<=0) return;
    for(int i=selection.length-1;i>=0;i--) {
      model.removeRow(table.convertRowIndexToModel(selection[i]));
    }
    if(model.getRowCount()==0) {
      table.setRowSorter(null);
      table.getTableHeader().repaint();
    }
  }
}
}}

**参考リンク [#sa1a2655]
- [[JTableの行を追加、削除>Swing/AddRow]]
- [[JTableのセルにJButtonを追加して行削除>Swing/DeleteButtonInCell]]

**コメント [#h696ae90]
- ソートした状態で「remove all rows」を押すと例外が発生しますよ -- [[tohrisugari]] &new{2013-07-23 (火) 08:51:30};
//- ソートした状態で「remove all rows」を押すと例外が発生しますよ -- [[tohrisugari]] &new{2013-07-23 (火) 09:08:48};
-- ご指摘ありがとうございます。確かに``ArrayIndexOutOfBoundsException: 0 >= 0``が発生していますね。以前は正常だったはずと思って調べてみたら、[http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6967479 Bug ID: JDK-6967479 JTable sorter fires even if the model is empty]が原因のようです。``6u10,6u20``で発生?して、%%``8``で修正される予定?みたいなので、しばらくは別の方法を使用するように修正し%% 何時修正されるか分からないので回避方法を考えてみようと思います。 -- [[aterai]] &new{2013-07-23 (火) 10:47:23};
-- ``model.setRowCount(0);``の前に、``table.setRowSorter(null);``とソートを不可にする修正などを追加しました。 -- [[aterai]] &new{2013-07-23 (火) 14:44:15};

#comment