Swing Event Pump Redux
Having blogged this hack some years ago (Event Pump DTs), today i actually used it.
The idea is to execute a long running task in the background, while blocking our app, seemingly on the EDT, while waiting for the task to complete. The hack involves using a zero-sized dialog. In this case, the EDT is not blocked from handling other events in the queue eg. as a response to user actions in the meantime, eg. repainting and whatever.
Actually the problem i had was that changes to the UI weren't being realised as expected in time before the task blocked the EDT from doing so. My task is an exec of a system process, which i invoke as follows.
int exitCode;
public int exec(final String command) {
doInBackground(new Runnable() {
public void run() {
exitCode = execImpl(command);
}
});
return exitCode;
}
public void doInBackground(final Runnable runnable) {
try {
if (!SwingUtilities.isEventDispatchThread()) {
runnable.run();
} else {
final JDialog dialog = new JDialog();
dialog.setModal(true);
dialog.setBounds(new Rectangle(0, 0, 0, 0));
dialog.setUndecorated(true);
final SwingWorker worker = new SwingWorker() {
@Override
protected Object doInBackground() throws Exception {
runnable.run();
return null;
}
protected void done() {
dialog.setVisible(false);
}
};
worker.execute();
dialog.setVisible(true);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
So after executing the background task, we make the (invisible) dialog visible, which blocks our app until the background task done() invokes setVisible(false) to dispose our zero-sized invisible dialog.
What's good about this is while our app is properly blocked (owing the modality of the dialog), the EDT is not improperly blocked.
- Printer-friendly version
- evanx's blog
- 1883 reads





