• 追加された行はこの色です。
  • 削除された行はこの色です。
#navi(../)
*JTableのソート [#jc31212f]
>編集者:[[Terai Atsuhiro>terai]]~
作成日:2004-01-05~
更新日:&lastmod;

#contents
**概要 [#c7b7a824]
JTableのヘッダカラムをクリックすることで、行表示を降順、昇順にソートします。

以下のサンプルは、tameさんの[[SortableTableExample>http://www.physci.org/codes/display.jsp?fl=%2Fcodes%2Ftame%2Ftame%2Fexamples%2FSortableTableExample.java]]を参考にして作成しています。

http://terai.xrea.jp/swing/sortabletable/screenshot.png

**サンプルコード [#y7f29510]
 class SortableTableModel extends DefaultTableModel{
   public SortableTableModel(String[] str, int row) {
     super(str, row);
   }
   public void sortByColumn(int column, boolean isAscent) {
     Collections.sort(getDataVector(), new ColumnComparator(column, isAscent));
     fireTableDataChanged();
   }
 }
 class ColumnComparator implements Comparator{
   final protected int index;
   final protected boolean ascending;
   public ColumnComparator(int index, boolean ascending) {
     this.index = index;
     this.ascending = ascending;
   }
   public int compare(Object one, Object two) {
     if(one instanceof Vector && two instanceof Vector) {
       Object oOne = ((Vector)one).elementAt(index);
       Object oTwo = ((Vector)two).elementAt(index);
       if(oOne==null && oTwo==null) {
         return 0;
       }else if(oOne==null) {
         return ascending ? -1 :  1;
       }else if(oTwo==null) {
         return ascending ?  1 : -1;
       }else if(oOne instanceof Comparable && oTwo instanceof Comparable) {
         Comparable cOne = (Comparable)oOne;
         Comparable cTwo = (Comparable)oTwo;
         return ascending ? cOne.compareTo(cTwo) : cTwo.compareTo(cOne);
       }
     }
     return 1;
   }
   public int compare(Number o1, Number o2) {
     double n1 = o1.doubleValue();
     double n2 = o2.doubleValue();
     if(n1 < n2) {
       return -1;
     }else if(n1 > n2) {
       return 1;
     }else{
       return 0;
     }
   }
 }

-[[サンプルを起動>http://terai.xrea.jp/swing/sortabletable/sample.jnlp]]
-[[jarファイル>http://terai.xrea.jp/swing/sortabletable/sample.jar]]
-[[ソース>http://terai.xrea.jp/swing/sortabletable/src.zip]]
**解説 [#j738ec00]
上記のサンプルでは、カラムヘッダをクリックすることでソートできます。右クリックからポップアップメニューで、行を追加、削除したり、セルをダブルクリックして中身を色々編集するなどしてソートを試してみてください。

複数の列をキーにしてソートしたい場合や、ヘッダがボタンになるのがいやな場合は、[[TableSorterでJTableをソート>Swing/TableSorter]]を参照してください。
**参考リンク [#f1d425ba]
-%%[[Swing Examples>http://www2.gol.com/users/tame/swing/examples/SwingExamples.html]]%%
-[[SortableTableExample>http://www.physci.org/codes/display.jsp?fl=%2Fcodes%2Ftame%2Ftame%2Fexamples%2FSortableTableExample.java]]
-[[TableSorterDemo>http://java.sun.com/docs/books/tutorial/uiswing/components/example-1dot4/index.html#TableSorterDemo]]

**コメント [#n7689273]
-非常に参考になりました。すぐに実装に使わせていただきます。 -- [[akio]] &new{2005-01-12 18:11:14 (水)};
-カラムをドラッグして移動したとき、矢印が残ってしまうようです。%%元からだったかデグレードしたのかちょっと不明です。%% 元からのようです。 -- [[terai]] &new{2005-02-25 19:55:01 (金)};
-一応修正できたかな?%%確認中。%% 確認済み。 -- [[terai]] &new{2005-02-25 20:30:57 (金)};
-修正できたかな?%%確認中。%% 確認済み。 -- [[terai]] &new{2005-02-25 20:30:57 (金)};
-Swing初心者の為このサイトのソースを参考に勉強させて頂いています。 -- [[ao]] &new{2005-03-11 14:37:03 (金)};
-行を削除した後にソートを降順ソート、昇順ソート、初期状態と3回ソートを行うと削除した行が元に戻ってしまうようです。 TestModel.javaのremoveRowにlist.remove(index);を追加したらうまくいきましたが、本当にこれでよいのでしょうか?-- [[ao]] &new{2005-03-11 14:40:10 (金)};
-%%いいと思います。バグなので修正しておきますm(_ _m)。%% あ、ダメみたいです。以下のように行番号をキーにして削除しないとソート中は別の行を削除してしまいます。 -- [[terai]] &new{2005-03-11 19:13:45 (金)};
 public void removeRow(int index) {
   Integer num = (Integer)getValueAt(index, 0);
   Test test = (Test)list.elementAt(num.intValue()-1);
   list.removeElement(test);
   super.removeRow(index);
 }
-初期状態に戻すのを止めたほうがいいかもしれません(エクスプローラも初期状態に戻したりしないし)。わざわざVectorでlistを別に持つ必要も、キーとして番号の列を作る必要もなくなります。 -- [[terai]] &new{2005-03-11 19:23:16 (金)};
-こちらのサンプルでは初期状態に戻すのを止めてみました。初期状態戻し有りにしたい場合は、[[TableSorterでJTableをソート>Swing/TableSorter]]の方を参考にしてみてください。 -- [[terai]] &new{2005-03-11 21:08:34 (金)};

#comment