Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I read a SwingWorker's result *without* busy wait?

I'm writing an application that executes its file menu actions using SwingWorker. Every called method returns a boolean value that tells, whether the operation was successfully executed or not.

At the moment I'm using busy waiting for the result, like this:

public boolean executeOperation() {
    final SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
        @Override
        protected Boolean doInBackground() throws Exception {
            // ..

            if (aborted) {
                return false;
            }

            // ..

            return true;
        }
    };

    worker.execute();

    // busy wait
    while (!worker.isDone())
        ;

    try {
        return worker.get().booleanValue();
    } catch (Exception e) {
        // handle exceptions ..
        return false;
    }
}

Is there a less polling-intense way of solving this?

Using worker.get() directly wouldn't work, as it blocks the EDT, waiting for the task to finish - meaning even the dialogs I open from within the SwingWorker wouldn't get painted.

EDIT: If possible, I would like to avoid that the method (or the worker) to communicate their result asynchronously. I'm implementing several short methods (file -> open, new, close, save, save as, exit) that rely on each other (i. e. when the trying to exit, exit calls close, close might call save, save might call save as). Solving this asynchronously seems to make the code much more complicated.

like image 657
riwi Avatar asked Sep 08 '11 08:09

riwi


1 Answers

The point of the SwingWorker is precisely to launch some task in the background and don't block the EDT. Either you want something synchronous, and the EDT will be blocked whatever you try, or you want something asynchronous, and the background task should update its status using the publish method of the SwingWorker.

You could display a blocking modal dialog with a progress bar while the task is running, and hide it once the task completes.

The alternative is to block for some time, hoping the task will be quick to finish, and then backup to an asynchronous way of doing. This can be done using the get method taking a timeout as argument.

like image 171
JB Nizet Avatar answered Sep 22 '22 11:09

JB Nizet