JavaFX 任务未更新进度条

问题描述 投票:0回答:1

我的软件有一个按钮,里面有一个很重的onAction ActionEvent。 我正在尝试使用自定义任务更新此 ActionEvent 内的进度栏。 但进度条仅在 ActionEvent 完全结束后才会更新。

由于我的软件是一个大型项目(~8000行),我会尝试尽可能地总结代码:

这是我的自定义任务:

public class VolumeProgressTask extends Task<Double> {

@Setter private Volume volume;

@Override
protected Double call() {
    double actualProgress = this.volume.getWindow().getLeftArea().getSeriesTab().getActualProgress();
    double progress = 0;
    double newProgress;
    double newActualProgress = 0;
    do {
        newProgress = this.volume.getReader().getProgress();
        if (newProgress != progress) {
            progress = newProgress;
            newActualProgress = actualProgress + (progress * this.volume.getLayers().size());
            updateProgress(newActualProgress, this.volume.getWindow().getLeftArea().getSeriesTab().getMaxProgress());
            double percent = newActualProgress / this.volume.getWindow().getLeftArea().getSeriesTab().getMaxProgress();
            System.out.println("percent: " + percent + " ,actual progress: " + this.volume.getWindow().getLeftArea().getSeriesTab().getProgressBar().getProgress());
        }
    } while (newProgress < 1);
    this.volume.getWindow().getLeftArea().getSeriesTab().setActualProgress(newActualProgress);
    return newActualProgress;
    }
}

我已经确保控制台在任务中打印正确的百分比。

此任务在软件开始时在名为“窗口”的对象内启动。 ProgressBar 绑定也在这里完成

@Getter @Setter private VolumeProgressTask volumeProgressTask = new VolumeProgressTask();
this.leftArea.getSeriesTab().getProgressBar().progressProperty().bind(this.volumeProgressTask.progressProperty());

这是我所说的按钮触发的ActionEvent:

EventHandler<ActionEvent> openFolderClickAction = (event) -> {
        try {
            String dicomSeriesFolderPath = LocalLoaderUtils.selectFolder(this.window.getStage());
            new Volume(dicomSeriesFolderPath, this.window);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    };

Volume 类的相关部分:

this.window.getVolumeProgressTask().setVolume(this);
Thread progressTaskThread = new Thread(this.window.getVolumeProgressTask());
progressTaskThread.setDaemon(true);
progressTaskThread.start();
progressTaskThread.join();

最后是包含 ProgressBar 的 SeriesTab 类:

@Getter private final ProgressBar progressBar = new ProgressBar();
@Getter @Setter private double actualProgress;
@Getter @Setter private double maxProgress;

我消耗了大量示例、教程视频和 stackOverflow 问题,但没有成功。感谢您阅读本文。

javafx task
1个回答
0
投票

这是一个最小的可重现示例:

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.stage.Stage;
import lombok.Getter;

@Getter
public class MRE extends Application {

    private ProgressBar progressBar;
    private Button btn;

    private double count = 0;
    private final long max = 1000000;

    public static void main (String[] args) {
        Application.launch();
    }

    @Override
    public void start (Stage primaryStage) {
        Stage stage = new Stage();
        Group group = new Group();
        Scene scene = new Scene(group);

        stage.initOwner(primaryStage);
        stage.setWidth(120);
        stage.setHeight(120);
        stage.setTitle("minimal reproducible example");
        stage.setScene(scene);
        stage.show();

        this.btn = new Button();
        this.btn.setPrefHeight(25);
        this.btn.setPrefWidth(100);
        this.btn.setTranslateX(10);
        this.btn.setTranslateY(10);
        this.btn.setOnAction(event -> {
            btnAction(this);
            this.count = 0;
        });
        this.btn.setText("run actionEvent");
        group.getChildren().add(this.btn);

        this.progressBar = new ProgressBar();
        this.progressBar.setTranslateX(10);
        this.progressBar.setTranslateY(45);
        this.progressBar.setPrefHeight(25);
        this.progressBar.setPrefWidth(100);
        group.getChildren().add(this.progressBar);

    }

    public void btnAction (MRE MREObj) {
        TestTask task = new TestTask(this);
        MREObj.getProgressBar().progressProperty().bind(task.progressProperty());
        Thread taskThread = new Thread(task);
        taskThread.setDaemon(true);
        taskThread.start();
        for (int i = 1; i <= this.max; i++) {
            System.out.println("hi");
            this.count++;
        }
    }

}

class TestTask extends Task<Void> {

    private final MRE MREObj;

    public TestTask (MRE MREObj) {
        this.MREObj = MREObj;
    }

    @Override
    protected Void call () {
        double actualProgress = 0;
        double newProgress;
        do {
            newProgress = this.MREObj.getCount();
            if (newProgress != actualProgress) {
                actualProgress = newProgress;
                updateProgress(actualProgress, this.MREObj.getMax());
                System.out.println("progress: " + (actualProgress/this.MREObj.getMax()));
            }
        } while(this.MREObj.getCount() < this.MREObj.getMax());
        updateProgress(this.MREObj.getMax(), this.MREObj.getMax());
        return null;
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.