用于下载过程的Java Swing进度条

Edw*_*its 6 java swing frontend backend jprogressbar

我正在使用Java功能从互联网上下载文件.

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 :)
}
Run Code Online (Sandbox Code Playgroud)

我有我的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);
}
Run Code Online (Sandbox Code Playgroud)

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

所以,功能getLatestRelease()在于framework类中的包MyFramework.

Swing包括事件监听器在内的接口生成相关联的所有内容都在包中frontend.

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

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

Sim*_*slé 7

当你想在摇摆中做MVC时,我会想到这个SwingWorker课程.
SwingWorker带有一个名为"progress"的属性,你可以使用a来监听PropertyChangeListener.

可以使用其setProgress(int 0-100)方法从swingworker中触发进度事件.所以这里是用于在后台加载具有进度概念的文件(请注意,您需要知道文件的大小才能计算进度百分比).

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

解决方案1

正如他们所说的那样,如果你去了a ProgressMonitor并且你的后台任务是从a读取InputStream,你可以使用ProgressMonitorInputStream该类进行阅读和显示进度,而不必费心调用setProgress或者听"progress"属性.

解决方案2

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

注意:通过PropertyChangeListener非常重要,因为它将模型(任务)与视图(swing进度组件)分离,并遵守EDT使用规则.