6

我正在使用 Java 函数从 Internet 下载文件。

public void getLatestRelease()
{
    try
    {
        // Function called
        long startTime = System.currentTimeMillis();

        // Open connection
        System.out.println("Connecting...");
        URL url = new URL(latestReleaseUrl);
        url.openConnection();

        // Download routine
        InputStream reader = url.openStream();
        FileOutputStream writer = new FileOutputStream("release.zip");

        byte[] buffer = new byte[153600];
        int totalBytesRead = 0;
        int bytesRead = 0;

        while ((bytesRead = reader.read(buffer)) > 0)
        {
            writer.write(buffer, 0, bytesRead);
            buffer = new byte[153600];
            totalBytesRead += bytesRead;
        }

        // Download finished
        long endTime = System.currentTimeMillis();

        // Output download information
        System.out.println("Done.");
        System.out.println((new Integer(totalBytesRead).toString()) + " bytes read.");
        System.out.println("It took " + (new Long(endTime - startTime).toString()) + " milliseconds.");

        // Close input and output streams
        writer.close();
        reader.close();
    }

    // Here I catch MalformedURLException and IOException :)
}

我的 . 中有一个JProgressBar组件JPanel,它应该可以可视化下载进度:

private static void createProgressBar(JPanel panel)
{
    JProgressBar progressBar = new JProgressBar(0, 100);
    progressBar.setValue(0);
    progressBar.setStringPainted(true);
    panel.add(progressBar, BorderLayout.SOUTH);
}

我想将呈现给用户的“后端”功能与“前端”视图分开,类似于 Web 应用程序中的 MVC。

因此,函数位于classgetLatestRelease()中的包中。frameworkMyFramework

Swing接口生成相关的所有内容,包括事件侦听器,都在 package 中frontend

在主Controller类中,我创建了一个实例MyFramework和一个实例ApplicationFrontend,它是frontend包的主类。

问题是如何progressBar根据下载进度更新值?

4

1 回答 1

7

当你想在 Swing 中做 MVC 时,SwingWorker就会想到这个类。
SwingWorker 带有一个名为“progress”的属性,您可以使用PropertyChangeListener.

可以使用 swingworker 的setProgress(int 0-100)方法触发进度事件。因此,这里用于在后台加载带有进度概念的文件(请注意,您需要了解文件的大小才能计算进度百分比)。

显示进度可以使用两个选项来完成:aJProgressBar用于完全控制,或者 aProgressMonitor显示几乎自我管理的弹出窗口,其中包含进度条。请参阅 教程以查看差异。

解决方案 1

正如他们所说,如果您选择 aProgressMonitor并且您的后台任务正在从 a 读取InputStream,您可以使用ProgressMonitorInputStream该类来执行读取和显示进度,而无需打扰调用 setProgress 或收听“progress”属性。

解决方案 2

如果您想手动执行此操作,请创建调用 setProgress 的 SwingWorker 加载任务,根据需要实例化 ProgressMonitor(或 JProgressBar),在您的 SwingWorker 上注册 PropertyChangeListener 以检查“进度”更改并更新监视器/栏因此。

注意:通过 PropertyChangeListener 很重要,因为它将模型(任务)与视图(摇摆进度组件)解耦并遵守 EDT 使用规则。

于 2012-08-14T08:45:10.640 回答