TableCellRendererに進捗文字列を設定したJProgressBarを使用する
Total: 4849
, Today: 1
, Yesterday: 1
Posted by aterai at
Last-modified:
概要
JTable
のTableCellRenderer
として、進捗文字列を表示するJProgressBar
を設定します。
Screenshot
Advertisement
サンプルコード
class Task extends SwingWorker<Integer, ProgressValue> {
private final int lengthOfTask;
private final int randomSleep = 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(randomSleep);
} catch (InterruptedException ie) {
break;
}
publish(new ProgressValue(lengthOfTask, current));
}
return randomSleep * 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 progress = new JProgressBar();
private final JPanel renderer = new JPanel(new BorderLayout());
@Override public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
Component c;
renderer.removeAll();
progress.setValue(0);
if (value instanceof ProgressValue) {
ProgressValue pv = (ProgressValue) value;
Integer current = pv.getProgress();
Integer lengthOfTask = pv.getLengthOfTask();
if (current < 0) {
c = super.getTableCellRendererComponent(
table, "Canceled", isSelected, hasFocus, row, column);
} else if (current < lengthOfTask) {
progress.setValue(current * 100 / lengthOfTask);
progress.setStringPainted(true);
progress.setString(String.format("%d/%d", current, lengthOfTask));
renderer.add(progress);
c = renderer;
} else {
c = super.getTableCellRendererComponent(
table, "Done", isSelected, hasFocus, row, column);
}
} else {
c = super.getTableCellRendererComponent(
table, "Waiting...", isSelected, hasFocus, row, column);
}
return c;
}
@Override public void updateUI() {
super.updateUI();
setOpaque(true);
if (Objects.nonNull(renderer)) {
SwingUtilities.updateComponentTreeUI(renderer);
}
}
}
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)
で設定