在我的 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 线程并相应地更新进度条?
阅读建议将 ProgressMonitorDialog 与 IRunnableWithProgress 一起使用的文章。
使用 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 添加或更新到我现有的 Listener
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
感谢您对此提供的任何帮助。
编辑
Baz,您在下面的回答正是问题所要求的,所以感谢您的回答。
但是我开始认为我想做的事情是不可能的。当我的操作开始时,我希望进度条指示器开始,当我的操作结束时,我希望指示器在最后并且监视器会关闭。
我认为可能有一种方法可以使用我的侦听器来添加进度条。类似于以下内容。
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 必须进行某种测量才能正确显示指标。
如果指示器只是来回走动并且显示器会在操作结束时关闭,我会很高兴。