Search code examples
javauser-interfaceswt

Java SWT: wrapping syncExec and asyncExec to clean up code


I have a Java Application using SWT as the toolkit, and I'm getting tired of all the ugly boiler plate code it takes to update a GUI element.

Just to set a disabled button to be enabled I have to go through something like this:

shell.getDisplay().asyncExec(new Runnable() {
    public void run() {
        buttonOk.setEnabled(true);
    }
});

I prefer keeping my source code as flat as I possibly can, but I need a whopping 3 indentation levels just to do something simple.

Is there some way I can wrap it? I would like a class like:

public class UIUpdater {
    public static void updateUI(Shell shell, *function_ptr*) {
        shell.getDisplay().asyncExec(new Runnable() {
           public void run() {
              //Execute function_ptr
           }
        });
    }
}

And can be used like so:

UIUpdater.updateUI(shell, buttonOk.setEnabled(true));

Something like this would be great for hiding that horrible mess SWT seems to think is necessary to do anything.

As I understand it, Java cannot do functions pointers. But Java 7 will have something called Closures which should be what I want. But in the meantime is there anything at all I can do to pass a function pointer or callback to another function to be executed?

As an aside, I'm starting to think it'd be worth the effort to redo this application in Swing, and I don't have to put up with this ugly crap and non-cross-platformyness of SWT.


Solution

  • I had a similar problem in my SWT code.

    I wrote a base class that had nothing but asyncExec and syncExec methods. I had a method for every GUI method I wanted to call.

    My non-GUI thread class extended the base class.

    So in the non-GUI thread class, I'd have a call like setEnabled(shell, true)

    In the base class, I'd define a public void setEnabled(Shell shell, boolean flag) method that would include the code in your first example.