在我的GUI中,我有一個PDF文件創建操作。該操作可能需要10-15秒才能完成。當我開始操作時,我附加了一個監聽器。監聽器更改光標並禁用GUI,直到操作完成。
我也想添加一個進度條,這樣用戶就會知道它什麼時候會完成。ProgressMonitorDialog - 觀看活動線程以更新顯示器
創建一個方法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();
上面的代碼創建的進度。問題在於,進度條指標即將結束之前,操作就會結束。
問題:這是因爲在創建新線程的方法中,指標是根據新線程而不是操作線程更新的?
問題:是否可以創建一個觀察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...
}
它似乎將與線程和更新就像上面的代碼相同的問題。
問:所以,現在我想我可以再補充或更新進度,以我現有的監聽
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
但我開始看到進度條必須具有某種測量的正確顯示的指標。
如果指標剛好來回顯示,操作結束時顯示器會關閉,我會很高興。
我已經添加了ProgressMonitordialog的代碼。我創建了一個處理try和創建Dialog的方法。我添加了YourThread類。我應該在偵聽器的startOperation方法中調用progressbar方法嗎?我也明白工作量是衡量進度的方式。但我沒有平均的時間來完成操作。它可能需要5秒到20秒。所以我不確定如何處理工作量 - 但我更喜歡這個對話,並感謝您的幫助。 – jkteater
@jkteater我用一些示例代碼編輯了我的答案,以處理未知的工作負載。至於代碼的位置。在聽衆中這樣做應該沒問題。 – Baz
請參閱上面的編輯 – jkteater