Reputation: 449
I have a long operation that cannot be moved from the SWT UI thread. I know, it's gross, but that's how it is. I would like to display a progress bar of some sort for said long operation. I have tinkered around with org.eclipse.jface.dialogs.ProgressMonitorDialog. I'm not giving it an IRunnableWithProgress because, like I said, the long op is in the UI thread. And thus, we have something like...
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();
This works, but obviously does not update smoothly and at times is laggy to moving and clicking cancel. I thought maybe I could manually update the UI in this instance by creating a thread containing the requisite...
while(!shell.isDisposed()) {
if(!display.readAndDispatch()) {
display.sleep();
}
}
...in the run method, but much to my chagrin I bumped into...
Exception in thread "Thread-16" org.eclipse.swt.SWTException: Invalid thread access
Turns out you can't do that in just any old thread, those calls have to originate in the UI thread. Back to square one.
Does anyone know if I can trick the system? Like make my little thread appear to be the UI thread? Or just any other suggestions would be cool.
Thanks, jb
Upvotes: 0
Views: 3682
Reputation: 170733
The only way to have a responsive UI is to call Display.readAndDispatch()
in the UI thread, period. Normally, RCP takes care of it for you, or the main
method of your application, but if you are running something on the UI thread, they can't, so you have to.
Note that there can only be one UI thread, so if you could "make my little thread appear to be the UI thread" your original long-running task would not be running in the UI thread after all.
Upvotes: 2