To execute code on the UI thread, Runnables
are posted to the Display
class via two methods, syncExec()
and asyncExec()
. The syncExec()
method runs the code synchronously (that is, the caller blocks until the code has been run), while the asyncExec()
method runs the code asynchronously (that is, the caller continues while the code is run in the background).
The Display
class is SWT's handle to a monitor (so a runtime may have more than one Display
object, and each may have its own resolution). To get hold of an instance, call either Display.getCurrent()
or Display.getDefault()
. However, it's much better to get a Display
class from an associated view or widget. In this case, the Canvas
has an associated Display
.
TickTock
thread inside the createPartControl()
method of the ClockView
class.run()
method, replace the call to clock.redraw()
with:clock.getDisplay().asyncExec(new Runnable() { public void run() { if(clock != null && !clock.isDisposed()) clock.redraw(); } });
This time, the event will execute as expected. One thread, TickTock
, is running in the background, and every second it posts a Runnable
to the UI thread, which then runs asynchronously. This example could have used syncExec()
, and the difference would not have been noticeable; but in general, using asyncExec()
is to be preferred unless there is a specific reason to need the synchronous blocking behavior.
The thread is in a while loop and is guarded with a call to clock.isDisposed()
. Each SWT widget is non-disposed when it is initially created, and then subsequently disposed with a call to dispose()
. Once a widget is disposed, any native operating system resources are returned and any further operations will throw an exception. In this example, the Canvas
is disposed when the view is closed, which in turn disposes the components contained therein. As a result, when the view is closed, the Thread
automatically ceases its loop. (The Thread
can also be aborted by interrupting it during its 1 second sleep pauses.)
Note that the test for whether the widget is not null
or disposed is done in the Runnable
as well. Although the widget isn't disposed when it is added to the event queue, it might be when the event is processed some time later.