«

»

Jan 21

Print this Post

Java stupidity

Warning: what follows is a rant about a very minor technical point of the Java programming language. Click through only if you really want to.

So one of my tasks at work recently has been to write a tool to test the communication protocol used by one of our instruments. There is a function that updates one part of the GUI which can be called both as a result of user interaction and as a result of a new message being received over the comms.

People who know Java will probably have guessed where this is going.

Each incoming connection, for technical reasons, runs in its own thread. However, Java’s Swing GUI routines are generally not thread safe; all code that updates the GUI and isn’t explicitly described as thread-safe in the API docs has to be run from a single “Event Dispatcher” thread. Code that needs to update the GUI from outside this thread needs to be called by wrapping it in a Runnable and scheduling the Event Dispatcher thread to run it by passing it to either SwingUtilities.invokeLater() or SwingUtilities.invokeAndWait(). The behaviour if you don’t do it this way is unspecified, so even if it works 90% of the time, the other 10% it could do anything, up to and including make monkeys fly out of your nose.

Now, the easiest way to deal with this would be to simply do the wrapping in the non-GUI code that calls the function. However, I’m trying to keep the Swing-related stuff outside the GUI classes to a bare minimum, in case the Powers That Be suddenly dictate that it needs to be re-written to use a GUI toolkit other than Swing (it could very well happen). Unconditionally invokeLater()-ing it inside the function doesn’t work, because annoyingly calling invokeLater() from inside the event dispatcher thread causes a different error.

So what I’m left with is something like:

public void updateGui() {
    if ( SwingUtilities.isEventDispatchThread() ) {
        updateGuiImpl();
    } else {
        try {
            SwingUtilities.invokeAndWait( new Runnable() {
                public void run () {
                    updateGuiImpl();
                }
            });
        } catch (Exception ex) { }
    }
}

private void updateGuiImpl() {
    // actual GUI code goes here
}

It works, but every aesthetic bone in by body is screaming that it’s ugly. There’s gotta be a better way of doing it.

Permanent link to this article: http://www.goldeneyes.org.uk/braindump/2010/01/java-stupidity/

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

This blog is kept spam free by WP-SpamFree.