Swing/TableCellProgressBar のバックアップの現在との差分(No.16)
TITLE:JTableのセルにJProgressBarを表示
Posted by aterai at 2007-10-01
JTableのセルにJProgressBarを表示
JTableのセルにJProgressBarを使用して進捗を表示します。-
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:
hreflang:
href: https://java-swing-tips.blogspot.com/2008/03/jprogressbar-in-jtable-cell.html lang: en
概要
JTable
のセルにJProgressBar
を使用して進捗を表示します。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
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));
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;
#spanadd
#spanend
@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) {
if (i < 0) {
text = "Canceled";
}else if(i<100) {
} else if (i < 100) {
b.setValue(i);
return b;
}
super.getTableCellRendererComponent(table, text, isSelected, hasFocus, row, column);
super.getTableCellRendererComponent(
table, text, isSelected, hasFocus, row, column);
return this;
}
}
#spandel
#spanend
#spanadd
#spanend
private final Executor executor = Executors.newCachedThreadPool();
#spandel
//...
#spanend
#spandel
final int rowNumber = model.getRowCount();
#spanend
#spanadd
// ...
#spanend
#spanadd
int rowNumber = model.getRowCount();
#spanend
SwingWorker<Integer, Integer> worker = new SwingWorker<Integer, Integer>() {
private int sleepDummy = new Random().nextInt(100) + 1;
private int rndSleep = new Random().nextInt(100) + 1;
private int lengthOfTask = 120;
@Override
protected Integer doInBackground() {
@Override protected Integer doInBackground() {
int current = 0;
while(current<lengthOfTask && !isCancelled()) {
while (current < lengthOfTask && !isCancelled()) {
current++;
try {
Thread.sleep(sleepDummy);
}catch(InterruptedException ie) {
Thread.sleep(rndSleep);
} catch (InterruptedException ie) {
publish(-1);
break;
}
publish(100 * current / lengthOfTask);
}
return sleepDummy*lengthOfTask;
return rndSleep * lengthOfTask;
}
@Override
protected void process(java.util.List<Integer> chunks) {
for(Integer value : chunks) {
#spanadd
#spanend
@Override protected void process(List<Integer> chunks) {
for (Integer value: chunks) {
model.setValueAt(value, rowNumber, 2);
}
//model.fireTableCellUpdated(rowNumber, 2);
// model.fireTableCellUpdated(rowNumber, 2);
}
@Override
protected void done() {
#spanadd
#spanend
@Override protected void done() {
String text = null;
int i = -1;
if(isCancelled()) {
if (isCancelled()) {
text = "Canceled";
}else{
try{
} else {
try {
i = get();
text = "Done";
}catch(Exception ignore) {
} catch (Exception ignore) {
ignore.printStackTrace();
text = ignore.getMessage();
}
}
System.out.println(rowNumber +":"+text+"("+i+"ms)");
System.out.println(rowNumber + ":" + text + "(" + i + "ms)");
}
};
model.addTest(new Test("example", 0), worker);
#spandel
executor.execute(worker); //1.6.0_18
#spanend
#spandel
//worker.execute(); //1.6.0_21
#spanend
#spanadd
executor.execute(worker); // 1.6.0_18
#spanend
#spanadd
// worker.execute(); //1.6.0_21
#spanend
解説
上記のサンプルでは、addボタンをクリックすると、JDK 6のSwingWorkerを使用したダミータスクが起動して、進捗状況がCell内のJProgressBarで表示されます。解説
上記のサンプルでは、add
ボタンをクリックするとSwingWorker
を使用したランダムな仮タスクが起動し、その進捗状況が2
列目セル内のJProgressBar
で表示されます。
ProgressRendererは、JProgressBarを一つ持ち、ダミータスクが動いている間は、そのJProgressBarに値を設定して描画用のコンポーネントとして返し、タスクが終了(またはキャンセル)されたらJLabel(自分自身、DefaultTableCellRenderer)に文字列を設定して返すようになっています。
- - このサンプルでは、行番号をキーにしているため、例えばモデルから行を削除するときに実行中のタスクが手前の行などにあった場合はエラーが発生してしまいます。このため、実際には削除は行わず、フィルタを使って非表示にしています(参考: RowFilterでJTableの行をフィルタリング)。
- -
- メモ
-
ProgressRenderer
はJProgressBar
を一つ持ち、仮タスクが動いている間はそのJProgressBar
に値を設定して描画用のコンポーネントとして返す - タスクが終了(またはキャンセル)されたら
JLabel
(自分自身、DefaultTableCellRenderer
)に文字列を設定して返す - このサンプルでは、行番号をキーにしているため、例えばモデルから行を削除するときに実行中のタスクが手前の行などに存在する場合はエラーが発生する
- これを回避するため、実際には行の削除を実行せず、フィルタを使って行を非表示に設定する
- 参考: RowFilterでJTableの行をフィルタリング
-
SwingWorker
スレッドの同時実行上限は10
で固定- Swing - Maximum number of SwingWorker objects in a Swing app?
public abstract class SwingWorker<T, V> implements RunnableFuture<T> { /** * number of worker threads. */ private static final int MAX_WORKER_THREADS = 10;
- Swing - Maximum number of SwingWorker objects in a Swing app?
参考リンク
参考リンク
- SwingWorkerを使った処理の中断と進捗状況表示
- TableCellRendererに進捗文字列を設定したJProgressBarを使用する
- SwingWorkerを一スレッドずつ順番に実行する
コメント
-
Windows + Java 1.7.0-ea-b24 での動作がおかしいみたいです。 -- aterai - メモ: Bug 87 - Icedtea 1.7.0 and SwingWorker problem -- aterai
- JDK 1.6.0_18での修正: Bug ID: 6799345 JFC demos threw exception in the Java Console when applets are closed -- aterai
- 代わりに、Executors.newCachedThreadPool().execute(worker);のようにしているけど、これでいいのだろうか? 実行中にアプリケーションを終了する場合は、ExecutorService#shutdown()などを呼んだほうがよさそうだけど、このサンプルでは、WindowConstants.EXIT_ON_CLOSEでVMごと落としているので、関係ない? -- aterai
- 正常に動かなくなっているImprove Application Performance With SwingWorker in Java SE 6のサンプルがどう修正されるか、様子見。 -- aterai
- メモ: Bug ID: 6826514 SwingWorker: done() called before doInBackground() returns, when cancelled -- aterai
- メモ: Bug ID: 6880336 SwingWorker deadlocks due one thread in the swingworker-pool -- aterai
- 修正されたようです。Java SE 6 Update 21 Bug Fixes -- aterai
コメント
-
Windows
+Java 1.7.0-ea-b24
での動作がおかしいみたいです。 -- aterai - メモ: Bug 87 - Icedtea 1.7.0 and SwingWorker problem -- aterai
-
JDK 1.6.0_18
での修正: [JDK-6799345] JFC demos threw exception in the Java Console when applets are closed - Java Bug System -- aterai- 代わりに、
Executors.newCachedThreadPool().execute(worker);
のようにしているけど、これでいいのだろうか? 実行中にアプリケーションを終了する場合は、ExecutorService#shutdown()
などを呼んだほうがよさそうだけど、このサンプルでは、WindowConstants.EXIT_ON_CLOSE
でVM
ごと落としているので、関係ない? -- aterai - 正常に動かなくなっているImprove Application Performance With SwingWorker in Java SE 6などのサンプルがどう修正されるか、様子見。 -- aterai
- メモ: [JDK-6880336] SwingWorker deadlocks due one thread in the swingworker-pool - Java Bug System -- aterai
- 修正されたようです。Java SE 6 Update 21 Bug Fixes -- aterai
- 代わりに、
- メモ: [JDK-6826514] SwingWorker: done() called before doInBackground() returns, when cancelled - Java Bug System -- aterai