I\'ve been struggling with the usability problem of SwingWorker eating any exceptions thrown in the background task, for example, described on this SO thread. That thread gives
The wrapper seems to works as expected. However, its implementation will never call done()
if exception occurs. This is not suitable for many cases. It's probably simpler to call get()
in done()
. This will throw whatever exception that happened in doInBackground()
.
Not sure how your example is structured, but it did not work in the application without EDT. So wrapping worker execution in SwingUtilities.invokeLater
did help, ie:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SpecialDataHelper().execute();
}
});
The following example does print the exception stack trace:
public class Tester {
static class SpecialDataHelper extends SimpleSwingWorker {
public SpecialDataHelper () {
}
public Void doInBackground() throws Exception {
throw new Exception("test");
}
protected void done() {
}
}
public static void main(String[] args) {
try{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SpecialDataHelper().execute();
}
});
} catch(Exception ex){
ex.printStackTrace();
}
}
}
Also consider this simple example that demonstrates how to get the exceptions that occurred in doInBackground()
without using the wrapper. The wrapper is just a helper in case you forget to call get()
.
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class Tester {
static class Worker extends SwingWorker {
@Override
protected Void doInBackground() throws Exception {
throw new Exception("test");
}
@Override
protected void done() {
try {
get();
JOptionPane.showMessageDialog(null, "Operation completed");
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Operation failed");
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Worker().execute();
}
});
}
}