• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTableのセルにJProgressBarを表示
#navi(../)
*JTableのセルにJProgressBarを表示 [#p482fe63]
>編集者:[[Terai Atsuhiro>terai]]~
作成日:2007-10-01~
更新日:&lastmod;

#contents

**概要 [#tffb3b5b]
JTableのセルにJProgressBarを使用して進捗を表示します。

#screenshot

**サンプルコード [#tfa792a2]
#code{{
class ProgressRenderer extends DefaultTableCellRenderer {
  private final JProgressBar b = new JProgressBar(0, 100);
  public ProgressRenderer() {
    super();
    setOpaque(true);
    b.setBorder(BorderFactory.createEmptyBorder(1,1,1,1));
  }
  public Component getTableCellRendererComponent(JTable table, Object value,
                                               boolean isSelected, boolean hasFocus,
                                               int row, int column) {
    Integer i = (Integer)value;
    String text = "Done";
    if(i<0) {
      text = "Canceled";
    }else if(i<100) {
      b.setValue(i);
      return b;
    }
    super.getTableCellRendererComponent(table, text, isSelected, hasFocus, row, column);
    return this;
  }
}
}}
#code{{
final int rowNumber = model.getRowCount();
SwingWorker<Integer, Integer> worker = new SwingWorker<Integer, Integer>() {
  private int sleepDummy = new Random().nextInt(100) + 1;
  private int lengthOfTask = 120;
  @Override
  protected Integer doInBackground() {
    int current = 0;
    while(current<lengthOfTask && !isCancelled()) {
      current++;
      try {
        Thread.sleep(sleepDummy);
      }catch(InterruptedException ie) {
        publish(-1);
        break;
      }
      publish(100 * current / lengthOfTask);
    }
    return sleepDummy*lengthOfTask;
  }
  @Override
  protected void process(java.util.List<Integer> chunks) {
    for(Integer value : chunks) {
      model.setValueAt(value, rowNumber, 2);
    }
    table.repaint();
    //model.fireTableCellUpdated(key, 2);
  }
  @Override
  protected void done() {
    String text = null;
    int i = -1;
    if(isCancelled()) {
      text = "Canceled";
    }else{
      try{
        i = get();
        text = "Done";
      }catch(Exception ignore) {
        ignore.printStackTrace();
        text = ignore.getMessage();
      }
    }
    System.out.println(rowNumber +":"+text+"("+i+"ms)");
  }
};
model.addTest(new Test("example", 0), worker);
worker.execute();
}}
-&jnlp;
-&jar;
-&zip;

**解説 [#nf3d3b9b]
上記のサンプルでは、addボタンをクリックすると、JDK 6のSwingWorkerを使用したダミータスクが起動して、進捗状況がCell内のJProgressBarで表示されます。

ProgressRendererは、JProgressBarを一つ持ち、ダミータスクが動いている間は、そのJProgressBarに値を設定して描画用のコンポーネントとして返し、タスクが終了(またはキャンセル)されたらJLabel(自分自身、DefaultTableCellRenderer)に文字列を設定して返すようになっています。

このサンプルでは、行番号をキーにしているため、例えばモデルから行を削除するときに実行中のタスクが手前の行などにあった場合はエラーが発生してしまいます。このため、実際には削除は行わず、フィルタを使って非表示にしています(参考: [[RowFilterでJTableの行をフィルタリング>Swing/RowFilter]])。

**参考リンク [#mad68939]
-[[SwingWorkerを使った処理の中断と進捗状況表示>Swing/SwingWorker]]

**コメント [#m73864ef]
#comment