• category: swing folder: TableCellProgressBar title: JTableのセルにJProgressBarを表示 tags: [JTable, JProgressBar, TableCellRenderer, SwingWorker] author: aterai pubdate: 2007-10-01T16:23:32+09:00 description: JTableのセルにJProgressBarを使用して進捗を表示します。 image: https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTUYeEtfWI/AAAAAAAAAl8/47mUyOKeiQY/s800/TableCellProgressBar.png hreflang:
       href: http://java-swing-tips.blogspot.com/2008/03/jprogressbar-in-jtable-cell.html
       lang: en

概要

JTableのセルにJProgressBarを使用して進捗を表示します。

サンプルコード

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));
  }
  @Override 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;
  }
}
View in GitHub: Java, Kotlin
private final Executor executor = Executors.newCachedThreadPool();
//...
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(List<Integer> chunks) {
    for (Integer value: chunks) {
      model.setValueAt(value, rowNumber, 2);
    }
    //model.fireTableCellUpdated(rowNumber, 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);
executor.execute(worker); //1.6.0_18
//worker.execute(); //1.6.0_21

解説

上記のサンプルでは、addボタンをクリックすると、SwingWorkerを使用したダミータスクが起動し、その進捗状況が2列目セル内のJProgressBarで表示されます。

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


  • このサンプルでは、行番号をキーにしているため、例えばモデルから行を削除するときに実行中のタスクが手前の行などに存在する場合はエラーが発生する

public abstract class SwingWorker<T, V> implements RunnableFuture<T> {
  /**
   * number of worker threads.
   */
  private static final int MAX_WORKER_THREADS = 10;

参考リンク

コメント