在UI线程中执行长操作时的SWT进度对话框?

时间:2014-08-07 21:32:33

标签: java multithreading eclipse-plugin swt ui-thread

我有一个很长的操作,无法从SWT UI线程移动。我知道,这很糟糕,但那是怎么回事。我想为长时间操作显示某种进度条。我用org.eclipse.jface.dialogs.ProgressMonitorDialog修改了一下。我没有给它一个IRunnableWithProgress,因为就像我说的那样,长操作在UI线程中。因此,我们有类似......

Shell shell = new Shell();
ProgressMonitorDialog progressDialog = new ProgressMonitorDialog(shell);
progressDialog.open();
IProgressMonitor progressMonitor = progressDialog.getProgressMonitor();
int workLoad = 10;
progressMonitor.beginTask(message, workLoad);
for(int i = 0; i < workLoad; ++i) {
    progressMonitor.worked(1);
    progressMonitor.subTask("Subtask " + (i+1) + " of "+ workLoad + "...");
    if(progressMonitor.isCanceled()) {
        break;
    }
    // Do some work.
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
progressMonitor.done();
progressDialog.close();

这样可行,但显然不能顺利更新,有时候移动和点击取消有点滞后。我想也许我可以通过创建包含必需的...

的线程来手动更新此实例中的UI
while(!shell.isDisposed()) {
    if(!display.readAndDispatch()) {
        display.sleep();
    }
}

...在run方法中,但令我懊恼的是我遇到了......

Exception in thread "Thread-16" org.eclipse.swt.SWTException: Invalid thread access

事实证明,您无法在任何旧线程中执行此操作,这些调用必须来自UI线程。回到原点。

有谁知道我是否可以欺骗系统?就像make我的小线程似乎是UI线程?或者只是其他任何建议都会很酷。

谢谢, JB

1 个答案:

答案 0 :(得分:2)

拥有自适应UI的唯一方法是在UI线程中调用Display.readAndDispatch()。通常情况下,RCP会为您或您的应用程序的main方法处理它,但如果您在UI线程上运行某些东西,它们就不能,所以您必须这样做。

请注意,只能有一个UI线程,所以如果你可以让我的小线程看起来像是UI线程&#34;你原来长期运行的任务毕竟在UI线程中运行。