Swing tip : A better SwingWorker without exception swallowing
When we develop Swing applications, SwingWorker are very helpful. But there is a big disadvantage using this class. if you don't call get() in the done method, you will lose all the exceptions that the computation in the doInBackground() has thrown. And you action can stop and you will never see why. In 95% of my actions using SwingWorker, the doInBackground() return nothing.
Jonathan Giles has presented on his blog a good solution to solve this exception swallowing. In my side, I've often something to do in the EDT before the doInBackground() run, so I've made the changes on the code presented by Jonathan and it gave me that simple class that I found better than the SwingWorker :
public abstract class BetterSwingWorker { private final SwingWorker<Void, Void> worker = new SimpleSwingWorker(); public void execute() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { before(); } }); worker.execute(); } protected void before() { //Nothing by default } protected abstract void doInBackground() throws Exception; protected abstract void done(); private class SimpleSwingWorker extends SwingWorker<Void, Void> { @Override protected Void doInBackground() throws Exception { BetterSwingWorker.this.doInBackground(); return null; } @Override protected void done() { try { get(); } catch (final InterruptedException ex) { throw new RuntimeException(ex); } catch (final ExecutionException ex) { throw new RuntimeException(ex.getCause()); } BetterSwingWorker.this.done(); } } }
You can use it as the default SwingWorker. You must implement the doInBackground() and done() methods and you can, only if you want, override the before() method that is invoked in the EDT at the start of the process. And then, you can execute your SwingWorker using execute().
I hope this little class can be useful to somebody.
Source for the non-swallowing swingworker.
Comments
Comments powered by Disqus