GUIKIT PACKAGE TUTORIAL

Threads

By default, any interface definition executes within a single thread, and since currently definitions execute at runtime as Java components, this means that execution occurs in the single Java AWT event dispatch thread.

In most cases, complete user interface dialogs or tools can run within a single Java thread, make synchronous requests to the Wolfram Language, and never require any explicit threading code to handle how requests are processed. Also note that since the Wolfram Language kernel is not multithreaded, the only reason for attempting a multithreaded interface definition is to allow user interface updates to occur while a long calculation may be proceeding in the Wolfram Language.

Consider, for example, the following definition.

Click for copyable input
Click for copyable input

Take a screen shot of what this definition renders.

Click for copyable input

If you try running this example and pressing the button, you will not actually see the label's text update at all. Why is this? The reason is that the button's bind event is executing in the default single AWT thread, and while it is executing (during its action call), the user interface is busy while all the attempts at setting the label's text are occurring from the Script code. The user interface thread is busy evaluating the button action call and is not receptive to any other requests to update the label's text and repaint the window. If you want to see the user interface update while a possibly long Wolfram Language calculation is going on, you would need to have the BindEvent code execute in a new thread asynchronously, so that the user interface event dispatching thread is not busy and can take requests for updating other user interface widgets. However, there is an important subsequent requirement that needs to be satisfied. User interface widgets cannot be updated from calls in any other threads but the AWT event dispatching thread, so requests for updating widgets, such as through SetPropertyValue, must be made and queued for execution on the AWT event dispatching thread.

GUIKit attempts to simplify issues related to spawning execution in new separate threads and also makes sure certain executions happen on the AWT event dispatch thread when this is required. Many of the execution functions in GUIKit, such as BindEvent, SetPropertyValue, and InvokeMethod, take two options: InvokeThread -> "Name", which chooses which thread a snippet of code will execute in, and InvokeWait -> Automatic | True | False, which determines whether the thread that initiates this new request, possibly in a different thread, will wait for the response from this new request to finish before continuing, or whether it ignores any response and immediately continues with its execution.

InvokeThread currently accepts the following three values: (the default), , or . The choice of makes no attempt to create a new thread to execute the request in and operates within the same current active thread. will create a new thread and execute the code within this new thread. requests that the code execute within the AWT event dispatching thread. The default value for InvokeWait is Automatic and the default behavior is based on the value of InvokeThread, if an explicit setting of InvokeWait is not included. The following table summarizes the default automatic behavior of InvokeWait.

Current Thread
Default Behavior of InvokeWait
Notes
currentanyTrueexecution occurs on the current thread synchronously waiting for the result of the code before continuing
newanyFalseexecution is occurring in a new thread and by default the code will not wait for a response before continuing
DispatchDispatchTrueif you request the Dispatch thread, and you are currently running in the Dispatch thread, the response will be returned synchronously
Dispatchnot DispatchFalseif you are not already in the Dispatch thread, asynchronously have the execution queued to occur on the Dispatch thread as soon as possible without waiting for the response

Using the InvokeThread option and the default behavior of InvokeWait, you can now thread the execution of the Wolfram Language calculation using a new thread on the BindEvent and update the user interface in the event dispatch thread when calling SetPropertyValue.

Click for copyable input

Notice also the desire to disable the button while the execution is threaded since the Wolfram Language cannot evaluate requests from multiple threads, and allowing another request can lead to unpredictable results in the kernel evaluation sequences.

For a more detailed description of issues related to using Java user interfaces in a multithreaded environment, see Sun's Java documentation.