私のGUIには、PDFファイルの作成操作があります。操作が完了するまでに最大10〜15秒かかる場合があります。操作を開始するときに、リスナーをアタッチします。操作が完了するまで、リスナーはカーソルを変更してGUIを無効にします。
また、プログレスバーを追加したいので、ユーザーはプログレスバーがいつ完了するかを知ることができます。
メソッドstartProgressBar()を作成し、操作メソッドの最初から呼び出しました。
下記参照:
private void startSavePdfOperation() {
startProgressBar();
saveOp = new AplotSaveOperation(appReg.getString("aplot.message.SAVETOPDF"), "PDF", session);
saveOp.addOperationListener(new MyOperationListener(this) {
startProgressBarメソッド-以下を参照してください。
public void startProgressBar() {
Shell shell = new Shell(getShell());
shell.setSize(260, 120);
final ProgressBar bar = new ProgressBar(shell, SWT.SMOOTH);
bar.setBounds (20, 20, 200, 20);
shell.open();
final int maximum = bar.getMaximum();
new Thread(new Runnable() {
public void run() {
for (final int[] i = new int[1]; i[0] <= maximum; i[0]++) {
try {Thread.sleep (100);} catch (Throwable th) {}
if (Display.getDefault().isDisposed()) return;
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (bar.isDisposed ()) return;
bar.setSelection(i[0]);
}
});
}
}
}).start();
上記のコードはProgressBarを作成しました。問題は、プログレスバーインジケーターが終了に近づくかなり前に操作が終了することです。
質問:これは、メソッドで新しいスレッドを作成していて、インジケーターが操作スレッドではなく新しいスレッドに従って更新されているためですか?
質問:GUIスレッドを監視し、それに応じてプログレスバーを更新する新しいスレッドを作成することは可能ですか?
IRunnableWithProgressでProgressMonitorDialogを使用することを提案する記事を読んでください。
ProgressMonitorDialogを使用したメソッドstartProgressBar-以下を参照してください。
public void startProgressBar() {
ProgressMonitorDialog dialog = new ProgressMonitorDialog(getShell());
try {
dialog.run(true, true, new IRunnableWithProgress(){
public void run(IProgressMonitor monitor) {
monitor.beginTask("Some nice progress message here ...", 100);
** getThread(); **
monitor.done();
}
});
}
catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void getThread() {
new Thread etc.. etc...
}
上記のコードと同じように、スレッド化と更新で問題が発生するようです。
質問:現在、ProgressBarを既存のリスナーに追加または更新するだけでよいと考えています。
OperationListenerコード-以下を参照してください。
public abstract class MyOperationListener implements InterfaceAIFOperationListener {
AplotCreatePDFDialog w = null;
public MyOperationListener(AplotCreatePDFDialog win) {
w = win;
}
public void startOperation(String startMessage) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
w.getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_WAIT));
w.recursiveSetEnabled(getShell(), getShell().getEnabled());
w.getShell().setEnabled(!getShell().getEnabled());
}
});
}
public void endOperation() {
try {
endOperationImpl();
}
finally {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
w.getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_ARROW));
w.recursiveSetEnabled(getShell(), true);
w.getShell().setEnabled(!getShell().getEnabled());
w.close();
}
});
}
}
abstract protected void endOperationImpl();
} // end class MyOperationListener
あなたがこれで私に与えることができるどんな助けにも感謝します。
編集
バズ、以下のあなたの答えはまさに質問が尋ねたものです、それで答えてくれてありがとう。
しかし、私がやろうとしていることは不可能だと思い始めています。操作を開始するときにプログレスバーインジケーターを開始し、操作を終了するときにインジケーターを終了してモニターを閉じる必要がありました。
リスナーを使用してプログレスバーを追加する方法があるのではないかと思いました。次のようなもの。
public void startOperation(String startMessage) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
->monitor.beginTask("Creating PDF File(s)", IProgressMonitor.UNKNOWN);<-
w.getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_WAIT));
w.recursiveSetEnabled(getShell(), getShell().getEnabled());
w.getShell().setEnabled(!getShell().getEnabled());
}
});
}
public void endOperation() {
try {
->monitor.worked(1);<-
endOperationImpl();
}
finally {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
w.getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_ARROW));
w.recursiveSetEnabled(getShell(), true);
w.getShell().setEnabled(!getShell().getEnabled());
->monitor.done();<-
w.close();
}
});
}
}
abstract protected void endOperationImpl();
}//クラスMyOperationListenerを終了します
しかし、インジケーターを正しく表示するには、ProgressBarに何らかの測定が必要であることがわかり始めています。
インジケーターが前後に動き、操作終了時にモニターが閉じてくれたら嬉しいです。