Reputation: 641
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
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
InputStream
and do your own loop to copy the bytes, and on each loop iteration, update the progress barEither 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
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