Getting Your Swing in a Spin

Job-seeking programmers who have ever had to sit a programmers’ aptitude test will probably dread this type of question, but here goes… What’s the difference between code sample (A) and code sample (B), below?

Code Sample (A):

public void actionPerformed(ActionEvent e)
{
  label.setText("...");
  label.setText(bean.getValue());
}

public void propertyChange(PropertyChangeEvent ev)
{
  label.setText((String)ev.getNewValue());
}

Code Sample (B):

public void actionPerformed(ActionEvent e)
{
  label.setText("...");
  label.setText(bean.getValue());
}

public void propertyChange(PropertyChangeEvent ev)
{
  label.setText((String)ev.getNewValue());
}

You’d be forgiven for saying that these code samples are identical. (Obviously, they are!) But the answer is that code sample (B) makes use of the open-source Spin library to take away the bulk of the threading issues that Swing programmers must face on a daily basis.

Swing uses a single update thread, called the Event Dispatch Thread (EDT). Dancing around the EDT is a seemingly eternal problem faced by Swing developers. Put simply, you’re not allowed to update the GUI in a different thread to the EDT; and non-GUI stuff generally shouldn’t take place in the EDT, as this will cause the GUI to become unresponsive.

To abide by these rules, programmers are obliged to deal with multi-threaded coding. But as soon as individual programmers start doing their own thing with threads, a project can quickly get tangled up with deadlocks, race conditions, and other ad-hoc multi-threaded nastiness. All that just to create a nice, responsive GUI!

Unless you make use of a library such as SwingWorker – or at least have a coherent and system-wide thread management policy in place – you tend to end up with repeated calls to SwingUtilities.invokeLater(), and SwingUtilities.isEventDispatchThread() to check whether or not you’re currently in the EDT.

SwingWorker removes some of the visual clutter from your EDT-dancing code, but it still forces the programmer to think probably a bit too hard about thread management: in other words, it’s still error-prone.

Another solution is the Foxtrot project, which introduced the Synchronous Model to take some of the complexity out of EDT-dancing, but which uses an API that’s still similar to SwingWorker.

Spin, meanwhile, makes use of Java’s powerful Dynamic Proxy capability. The result is code like that shown above, which – as long as you’re coding to Interfaces – just magically works.

In addition to its transparency, Spin also offers features above and beyond Foxtrot and SwingWorker: such as, transparent exception handling and asynchronous callbacks.

Spin can be downloaded here.

About the Author

Matt Stephens is a senior architect, programmer and project leader based in Central London. He co-wrote Agile Development with ICONIX Process, Extreme Programming Refactored, and Use Case Driven Object Modeling with UML - Theory and Practice.