0

我正在使用下载器创建 Java 应用程序。我的问题是,进度条不起作用。我希望我的进度条显示下载进度但失败了。这是我的代码的一部分。进度条一直停留在 0%...

下载.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();
} 

版本下载器类

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);
        }
    }


}

那有什么代码错了吗?

4

2 回答 2

2

这种事情并不像听起来那么简单。 copyURLToFile()将阻塞直到复制完成,所以只会给你两个事件 - 0% 和 100%。

如果您想在下载时显示进度,有一个先决条件:您必须在下载开始前知道文件长度(以便计算百分比)。您可以通过HEAD在开始复制之前发出 HTTP 请求来获得它 - 但该Content-Length字段是否存在于响应中取决于服务器 - 对于分块编码,您不会获得此信息(尽管您可能能够强制一些服务器通过发出 HTTP 1.0 请求来告诉您)。否则,您可以作弊并选择任意数量的字节。

一旦你有了长度或近似值,你可以

  • 运行计时器并定期检查到目前为止下载的字节数,并将其与大小进行比较,或者
  • 打开 URLInputStream并执行您自己的循环以复制字节,并在每次循环迭代时更新进度条

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

于 2013-10-14T18:46:15.003 回答
1

阅读 Swing 教程中有关如何使用进度条的部分,以获取使用 SwingWorker 的工作示例。

从可行的东西开始,然后根据您的特定要求进行更改。如果您仍然有问题,请发布一个SSCCE演示问题的帖子。

于 2013-10-14T18:36:40.983 回答