Nifty255
Nifty255

Reputation: 427

Java App SWT: Update UI on thread finished

I am trying to port a .NET app over into java and need an asynchronous downloader that increments a progress bar once a download (or asynchronous task) completes, similar to .NET's WebClient and its DownloadFileCompleted event. The app will be waiting for the downloads to complete, but I don't want the UI to lock up over the course of the downloads with "Not Responding". The problem lies in the inability of the download thread to directly increment the progress bar, since it was created in the main thread. I was thinking, since this is a SWT app (which has an os message pump loop), that I could somehow pump a message from the download thread and let the main thread pick it up. Is this possible? Is there another way?

Upvotes: 1

Views: 853

Answers (2)

Alessandro Atria
Alessandro Atria

Reputation: 96

try to use Display.asyncExec to update progress bar value from download thread.

Display.getCurrent().asyncExec(new Runnable() {         
        @Override
        public void run() {
        // update progress bar value here
        }

});

I'm not sure to have understood, but maybe something like this can run:

class Downloader {
    public static void downloadAsync(Object object, String url, final ProgressBar progressBar ){
            // download thread
        new Thread(new Runnable() {
            @Override
            public void run() {
                // start download here
                // while download progresses
                Display.getDefault().asyncExec(new Runnable() {
                    @Override
                    public void run() {
                        progressBar.setSelection(<your progress value>);
                    }
                });
            }
        });
    }
}

Upvotes: 2

Waqas Ilyas
Waqas Ilyas

Reputation: 3241

If you can use JFace, you can use the ProgressMonitorDialog:

ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell);
dialog.run(true, true, new IRunnableWithProgress() {
    public void run(IProgressMonitor monitor) throws InterruptedException {
        // This is a forked thread and updates only monitor, monitor is responsible for updating UI

        monitor.beginTask("Downloading...", totalBytes);

        // Loop to download bytes
        ...
        monitor.worked(1);
        ...

        // Completed
        monitor.done();
    }
});

If you don't want to use JFace then you can look at the implementation of this class to see how you can replicate similar implementation to update a ProgressBar control. Generally you can use Display#async(IRunnable) to post runnables that access UI. If you know the progress control in your download thread you can use this to update the UI.

Upvotes: 3

Related Questions