1

我正在尝试将 .NET 应用程序移植到 java 中,并且需要一个异步下载器,它在下载(或异步任务)完成后增加进度条,类似于 .NET 的 WebClient 及其 DownloadFileCompleted 事件。该应用程序将等待下载完成,但我不希望用户界面在下载过程中以“无响应”锁定。问题在于下载线程无法直接增加进度条,因为它是在主线程中创建的。我在想,因为这是一个 SWT 应用程序(它有一个 os 消息泵循环),我可以以某种方式从下载线程中泵出一条消息并让主线程来接收它。这可能吗?还有其他方法吗?

4

2 回答 2

3

如果可以使用 JFace,则可以使用ProgressMonitorDialog

ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell);
dialog.run(true, true, new IRunnableWithProgress() {
    public void run(IProgressMonitor monitor) throws InterruptedException {
        // This is a forked thread and updates only monitor, monitor is responsible for updating UI

        monitor.beginTask("Downloading...", totalBytes);

        // Loop to download bytes
        ...
        monitor.worked(1);
        ...

        // Completed
        monitor.done();
    }
});

如果您不想使用 JFace,那么您可以查看此类的实现,以了解如何复制类似的实现来更新ProgressBar控件。通常,您可以使用Display#async(IRunnable)发布访问 UI 的可运行文件。如果您知道下载线程中的进度控件,则可以使用它来更新 UI。

于 2012-11-22T17:25:46.353 回答
2

尝试使用 Display.asyncExec 从下载线程更新进度条值。

Display.getCurrent().asyncExec(new Runnable() {         
        @Override
        public void run() {
        // update progress bar value here
        }

});

我不确定是否理解,但也许这样的事情可以运行:

class Downloader {
    public static void downloadAsync(Object object, String url, final ProgressBar progressBar ){
            // download thread
        new Thread(new Runnable() {
            @Override
            public void run() {
                // start download here
                // while download progresses
                Display.getDefault().asyncExec(new Runnable() {
                    @Override
                    public void run() {
                        progressBar.setSelection(<your progress value>);
                    }
                });
            }
        });
    }
}
于 2012-11-22T17:29:09.820 回答