简体   繁体   English

Java-如何在SwingWorker中使用JProgressBar

[英]Java - How to use JProgressBar with SwingWorker

I am creating a Java application with a downloader. 我正在使用下载器创建Java应用程序。 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%... 进度栏仅停留在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 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? 那是任何代码错误吗?

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%. copyURLToFile()将阻塞直到复制完成为止,因此只会给您两个事件-0%和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). 您可能会获得-可能-通过在开始复制之前发出HTTP HEAD请求-但响应中是否存在Content-Length字段取决于服务器-对于分块编码,您不会获得此信息(尽管您可能能够通过发出HTTP 1.0请求来强制某些服务器告知您)。 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 打开URL作为InputStream并进行自己的循环以复制字节,并在每次循环迭代中更新进度条

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. 无论哪种方式,请确保使用EventQueue.invokeLater()更新进度条的value属性,否则您可能会遇到死锁问题-从事件线程之外的任何线程修改Swing组件都是不安全的。

Read the section from the Swing tutorial on How to Use Progress Bars for a working example that uses a SwingWorker. 阅读Swing教程中有关如何使用进度条的部分, 获取使用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. 如果仍然有问题,请发布一个SSCCE来演示问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM