Jeremy
Jeremy

Reputation: 641

Java - How to use JProgressBar with SwingWorker

I am creating a Java application with a downloader. My problem is, the progress bar is not working. I want my progress bar to show the download progress but failed. Here is some part of my code. The progressbar just stuck at 0%...

Download.class

public void startDownload()
{
    ExecutorService executor = Executors.newSingleThreadExecutor();
    FutureTask<Void> verDownloader = new FutureTask<Void>(vd);
    FutureTask<Void> launcher = new FutureTask<Void>(dd);
    executor.execute(verDownloader);
    executor.execute(launcher);
    executor.shutdown();
} 

VersionDownloader.class

public class VersionDownloader implements Callable<Void>, PropertyChangeListener
{
    @Override
    public Void call() throws Exception
    {
                    done = false;
                    final SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>()
                    {
                        @Override
                        protected Void doInBackground() throws Exception
                        {
                            try
                            {
                                URL fileURL = new URL(url);
                                org.apache.commons.io.FileUtils.copyURLToFile(fileURL, path);
                            }
                            catch(Exception e)
                            {

                            }
                            return null;
                        }

                        @Override
                        public void done()
                        {
                            done = true;

                            try
                            {
                                Thread.sleep(1000);
                            }
                            catch (InterruptedException e)
                            {
                                e.printStackTrace();
                            }
                        }

                    };
                    worker.execute();
                    worker.addPropertyChangeListener(this);
                    worker.get();
                }
            }
        }
        catch(Exception e)
        {

        }
        return null;
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt)
    {
        if(!done)
        {
            int progress_a = progress;
            //launcher.frame.progress is a JProgressBar
            launcher.frame.progress.setValue(progress_a);
        }
    }


}

Is that any code wrong?

Upvotes: 0

Views: 1246

Answers (2)

Tim Boudreau
Tim Boudreau

Reputation: 1781

This sort of thing is less trivial than it sounds. copyURLToFile() is going to block until the copy is completed, so that will only give you two events - 0% and 100%.

If you want to show progress while you do the download, there is one prerequisite: You must know the file length before the download starts (so you can compute percentages). You could get that - maybe - by issuing an HTTP HEAD request before starting the copy - but whether the Content-Length field is there in the response depends on the server - for chunked encoding, you don't get this information (though you might be able to force some servers to tell you by issuing an HTTP 1.0 request). Failing that, you could cheat and pick an arbitrary number of bytes.

Once you have the length or an approximation, you can either

  • Run a timer and periodically check the number of bytes downloaded so far, and compare that with the size, OR
  • Open the URL as an InputStream and do your own loop to copy the bytes, and on each loop iteration, update the progress bar

Either way, make sure you use EventQueue.invokeLater() to update the progress bar's value property or you may have deadlock issues - it is not safe to modify Swing components from any thread but the event thread.

Upvotes: 2

camickr
camickr

Reputation: 324078

Read the section from the Swing tutorial on How to Use Progress Bars for a working example that uses a SwingWorker.

Start with something that works and make changes for your particular requirement. If you still have problems then post a SSCCE that demonstrates the problem.

Upvotes: 1

Related Questions