• category: swing folder: StringPaintedCellProgressBar title: TableCellRendererに進捗文字列を設定したJProgressBarを使用する tags: [JTable, JProgressBar, SwingWorker, TableCellRenderer] author: aterai pubdate: 2014-03-24T00:27:55+09:00 description: JTableのTableCellRendererとして、進捗文字列を表示するJProgressBarを設定します。 image: https://lh4.googleusercontent.com/-XSMYQI-BTU8/Uy67ZR-E4TI/AAAAAAAACCE/2zdsU6o7iA0/s800/StringPaintedCellProgressBar.png hreflang:
       href: http://java-swing-tips.blogspot.com/2014/05/jprogressbar-in-jtable-cell-render.html
       lang: en

概要

JTableTableCellRendererとして、進捗文字列を表示するJProgressBarを設定します。

サンプルコード

class Task extends SwingWorker<Integer, ProgressValue> {
  private final int lengthOfTask;
  private final int sleepDummy = new Random().nextInt(100) + 1;
  public Task(int lengthOfTask) {
    super();
    this.lengthOfTask = lengthOfTask;
  }
  @Override protected Integer doInBackground() {
    int current = 0;
    while (current < lengthOfTask && !isCancelled()) {
      current++;
      try {
        Thread.sleep(sleepDummy);
      } catch (InterruptedException ie) {
        break;
      }
      publish(new ProgressValue(lengthOfTask, current));
    }
    return sleepDummy * lengthOfTask;
  }
}

class ProgressValue {
  private final Integer progress;
  private final Integer lengthOfTask;
  public ProgressValue(Integer lengthOfTask, Integer progress) {
    this.progress = progress;
    this.lengthOfTask = lengthOfTask;
  }
  public Integer getProgress() {
    return progress;
  }
  public Integer getLengthOfTask() {
    return lengthOfTask;
  }
}

class ProgressRenderer extends DefaultTableCellRenderer {
  private final JProgressBar b = new JProgressBar();
  private final JPanel p = new JPanel(new BorderLayout());
  public ProgressRenderer() {
    super();
    setOpaque(true);
    b.setStringPainted(true);
    p.add(b);
  }
  @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected, boolean hasFocus,
      int row, int column) {
    String text = "Done";
    if (value instanceof ProgressValue) {
      ProgressValue pv = (ProgressValue) value;
      Integer current = pv.getProgress();
      Integer lengthOfTask = pv.getLengthOfTask();
      if (current < 0) {
        text = "Canceled";
      } else if (current < lengthOfTask) {
        b.setMaximum(lengthOfTask);
        b.setValue(current);
        b.setString(String.format("%d/%d", current, lengthOfTask));
        return p;
      }
    }
    super.getTableCellRendererComponent(
        table, text, isSelected, hasFocus, row, column);
    return this;
  }
  @Override public void updateUI() {
    super.updateUI();
    if (p != null) {
      SwingUtilities.updateComponentTreeUI(p);
    }
  }
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、2列目のTableCellRendererとして、JProgressBar#setStringPainted(true)と進捗文字列を表示するように設定したJProgressBarを使用しています。

  • 進捗状況文字列は「現在値/最大値」の形式で表示するため、この2つの値を保持するProgressValueオブジェクトを作成してSwingWorker#publish(...)メソッドでJTableのモデルに設定
  • TableCellRendererはモデルから取得したProgressValueオブジェクトから、以下の3つの値をJProgressBarに設定し、セルの描画用コンポーネントとして使用
    • JProgressBar#setMaximum(int)(最大値は、各行ごとにランダムなので)で最大値を設定
    • JProgressBar#setValue(int)で現在値を設定
    • 上記の値から生成した進捗状況文字列をJProgressBar#setString(String)で設定

参考リンク

コメント