ProgressIndicatorは、長い時間の掛かるような作業をするときに、 ユーザにその作業の進捗度合いを表示したり、作業が進行中だということを明示するために使用 します。
ProgressIndicatorは、仕事の開始、仕事の消化、 仕事の終了の3つを知らせることで操作します。 それぞれ beginTask(int)、 worked(double)、 done()メソッドで操作することができます。 バーの量は、worked(double)メソッドを呼び出す度に増加していきます。
import org.eclipse.jface.dialogs.ProgressIndicator;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
public class ProgressIndicatorDemonstrate extends ApplicationWindow {
ProgressIndicator prIndicator;
private ProgressIndicatorDemonstrate() {
super(null);
}
protected Control createContents(Composite parent) {
/* ウィンドウにタイトル表示 */
parent.getShell().setText("ProgressIndicatorSample");
/* ウィジェットを配置するパネル */
Composite composite = new Composite(parent, SWT.NONE);
/* 仕事を開始するボタン
* prIndicator.beginTask(int)とprIndicator.worked(double)を呼び出し、
* バーを増加させていく。*/
Button startButton = new Button(composite, SWT.PUSH);
startButton.setText("start progress");
startButton.setBounds(5, 5, 100, 30);
startButton.addSelectionListener(new StartButtonListener());
/* ProgressIndicatorをリセットするボタン
* 視覚的にはprIndicatorをリセットしているように見えるが、
* prIndicator.done()を行っており、
* 仕事が終了したことを伝えている。*/
Button resetButton = new Button(composite, SWT.PUSH);
resetButton.setText("reset progress");
resetButton.setBounds(110, 5, 100, 30);
resetButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
prIndicator.done();
}
});
/* ProgressIndicatorの作成 */
prIndicator = new ProgressIndicator(composite);
prIndicator.setBounds(5, 50, 400, 30);
composite.pack();
parent.pack();
return parent;
}
/**
* startButtonに登録される。
*/
private class StartButtonListener extends SelectionAdapter {
public void widgetSelected(SelectionEvent e) {
Display.getCurrent().asyncExec(new ProgressRunnable());
}
}
/**
* StartButtonListenerから実行される。
*/
private class ProgressRunnable implements Runnable {
public void run() {
prIndicator.beginTask(100);
for (int i=0 ; i<100 ; i++) {
prIndicator.worked(1);
}
}
}
public static void main(String[] args) {
Window w = new ProgressIndicatorDemonstrate();
w.setBlockOnOpen(true);
w.open();
Display.getCurrent().dispose();
}
}
start processボタンを押すと処理が始まり、reset progressボタンを押すと処理が終了します。
時間の掛かる処理というのは、一般的に、別スレッドで行うというのがセオリーですが、 SWTのWidget操作は、単一スレッドからしか行えない設計になっています。 なので、サンプルプログラムでは、スレッドを作成する代わりに、Display#asyncExec(Runnable) メソッドを呼び出しています。 このメソッドは、スレッドは立てずに、Displayクラスの管理のもと、 指定されたRunnableインスタンスの処理を平行して進めてくれます。
また、処理の開始でbeginTask(int)メソッドの代わりにbeginAnimatedTask()メソッドを使用すると、 仕事の進捗をworked(boudle)メソッドで知らせる必要がありません。 仕事が終わったら、ただdone()メソッドを呼ぶだけで済みます。 ソースの可読性の向上や、処理時間が算出できない処理の表現に有効です。