Skip to main content

Swing Event Pump Redux

Posted by evanx on December 21, 2009 at 2:04 AM PST

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.

Related Topics >>