首页 > 解决方案 > 通过多线程增加JavaFX中ProgressBar的进度

问题描述

我正在创建一个 JavaFX 应用程序,它将通过网络发送多个文件,并且我希望有一个发送字节数的进度条。我已经有了即将发送的文件的总大小,但是,我不知道如何增加进度条。

问题是,我同时发送文件,所以我不能只在我的下载类中设置进度,因为它会被另一个威胁覆盖。

这是我的下载类的样子:

        iStream = socket.getInputStream();
        bufferSize = socket.getReceiveBufferSize();
        fos = new FileOutputStream(file);
        bos = new BufferedOutputStream(fos);
        byte[] bytes = new byte[bufferSize];
        int count;
        while ((count = is.read(bytes)) >= 0) {
            bos.write(bytes, 0, count);
        }
        bos.close();
        is.close();

我正在通过以下方式执行课程:

List<Callable<String>> downloadTasks = new ArrayList<>();
Callable<String> download = new Download(new File(path), portnumber);
downloadTasks.add(download);
es.invokeAll(downloadTasks);

long totalSize在两个类中都有变量中的总字节数。

你能帮我了解如何实现字节进度条吗?谢谢

标签: javajavafxdownloadprogress-bar

解决方案


您只能从单个线程更新进度条:FX 应用程序线程。所以线程问题没有实际意义。您可以只增加一个表示下载字节总数的属性,并安排仅从该线程更新它。

所以像:

public class UploadProgressMonitor {

    private final long totalBytes ;
    private long downloadedBytes ;
    private final ReadOnlyDoubleWrapper progress = new ReadOnlyDoubleWrapper() ;

    public UploadProgressMonitor(long totalBytes) {
         this.totalBytes = totalBytes ;
    }

    private void doIncrement(long bytes) {
        downloadedBytes += bytes ;
        progress.set(1.0 * downloadedBytes / totalBytes);
    }

    public void increment(long bytes) {
        if (Platform.isFxApplicationThread()) {
            doIncrement(bytes);
        } else {
            Platform.runLater(() -> doIncrement(bytes));
        }
    }

    public ReadOnlyDoubleProperty progressProperty() {
        return progress.getReadOnlyProperty() ;
    }

    public final double getProgress() {
        return progressProperty().get();
    }
}

现在您可以执行以下操作:

long totalBytes = ... ;
UploadProgressMonitor monitor = new UploadProgressMonitor(totalBytes);
progressBar.progressProperty().bind(monitor.progressProperty());

如果你给每个任务一个参考UploadProgressMonitor它只需要做:

    int count;
    while ((count = is.read(bytes)) >= 0) {
        bos.write(bytes, 0, count);
        monitor.increment(count);
    }

推荐阅读