SWT and multithreading

I must admit that I have always hated Swing and AWT. It took me several weeks to (fully?) understand all the events stuff. Regarding the GUI, I was a VB guy, and that means dragging and dropping visual components. In the early days it was slow, very slow. I remember running a Swing application remotely in a HPUX server using a X server like a bad nightmare. So I dropped rich clients in Java and embraced server side development with Servlets and JSPs.

When I saw Eclipse and SWT for the first time, I thought ‘this guys have the killer rich client libraries for Java’. I threw away Netbeans and became an Eclipse believer. And SWT was like my ‘pending’ issue in my ‘favourites technologies to study’ list. Finally, I had the oportunity to use SWT in pure research project, just for fun. The learning curve for a Java guy with experience in Swing or AWT is almost non-existant…except for the multithreading.

SWT is not thread safe. Swing guys can say now: ‘Ok, Swing is not thread safe either, but who cares’. If you want to use SWT in a multithreaded environment, you should care… Because SWT enforces good thread safe code. Otherwise you will get a ‘org.eclipse.swt.SWTException: Invalid thread access’.
I found this through the hard way. My application has a Table widget, and it is updated based on the events triggered by our network API in the Opengate platform. When the Opengate event was triggered, I got the SWTException.

Basically, we have to make the SWT thread to manage all the User Interface events. The ‘Display’ class has a method called ‘asyncExec’ that enqueues a piece of code in the SWT thread events dispatcher. It works as follows:

public void refresh() { Display display = shell_.getDisplay(); if (!(display==null || display.isDisposed())) { display.asyncExec(new Runnable () { public void run() { Table t = shell_.getTable(); t.removeAll(); Iterator i = table_.values().iterator(); while (i.hasNext()) { String[] rowData = (String[]) i.next(); (new TableItem(t, SWT.NONE)).setText(rowData); } } }); } }

This piece of code refresh the content of a table stored in an instance of HashMap. ‘shell_’ is the reference to the SWT Shell where the table is contained. The method ‘getTable’ returns a reference to the table itself. ‘table_’ is the HashMap that contains the values of the table. I have used a HashMap because I need to keep a reference to the row of the table easily. The core functionality is inside the ‘asyncExec’ method, which needs an object of the Runnable class. Then the ‘run’ method must implement the code that must be thread safe.

SWT is single threaded, so it means that long running processes invoked from the events of the widgets can halt the execution of the application for a long period of time. The ‘asyncExec’ method can be used to execute long running processes.