JavaFX刷新方法中的进度条 [英] JavaFX refresh Progress Bar within a method

查看:604
本文介绍了JavaFX刷新方法中的进度条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的UI中有一个javafx Progressbar然后我有一个for循环。
在for循环的每次迭代中都会发生这种情况:

I have a javafx Progressbar in my UI and then I have a for loop. In every iteration of the for loop this happens:

progressVal += 5.0;
progress.setProgress(progressVal);

在整个循环之后,会发生这种情况:

And after the whole loop, this happens:

progress.setProgress(100);

我现在已经认识到UI控件只在方法完成后刷新,所以进度条不会更新直到结束,而不是imidiatly设置为100。

I now have recognized that the UI controls are only refreshed after the method has finished, so the progress bar wont update until the end and than would be set to 100 imidiatly.

所以有可能以某种方式强制UI更新,即使该方法没有完全完成?或者我怎么能这样做?

So is it possible so somehow force the UI update, even when the method isn`t finished completly? Or how else could I do this?

推荐答案

如果你在循环中做的事需要很长时间而且不应该执行JavaFX应用程序线程(它可能会或你可能没有这个问题),那么你应该在任务,在不同的线程上,随着循环的进展更新任务的进度,并将进度条的值绑定到任务的进度。

If what you do in your loop takes a long time and should not be executed on the JavaFX application thread, (which it probably does or you probably wouldn't have this question), then you should probably run the loop in a Task, on a different thread, updating the task's progress as the loop progresses and binding the progress bar's value to the task's progress.

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class ProgressFeedback extends Application {
    private static final double EPSILON = 0.0000005;
    @Override
    public void start(Stage stage) throws Exception {
        final Task<Void> task = new Task<Void>() {
            final int N_ITERATIONS = 100;

            @Override
            protected Void call() throws Exception {
                for (int i = 0; i < N_ITERATIONS; i++) {
                    updateProgress(i + 1, N_ITERATIONS);
                    // sleep is used to simulate doing some work which takes some time....
                    Thread.sleep(10);
                }

                return null;
            }
        };

        final ProgressBar progress = new ProgressBar();
        progress.progressProperty().bind(
                task.progressProperty()
        );
        // color the bar green when the work is complete.
        progress.progressProperty().addListener(observable -> {
            if (progress.getProgress() >= 1 - EPSILON) {
                progress.setStyle("-fx-accent: forestgreen;");
            }
        });

        // layout the app
        final StackPane layout = new StackPane(progress);
        layout.setPadding(new Insets(10));
        stage.setScene(new Scene(layout));
        stage.show();

        final Thread thread = new Thread(task, "task-thread");
        thread.setDaemon(true);
        thread.start();
    }

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




如果任务怎么办?调用只执行单个作业的方法,并且不希望它一次又一次地被调用?

what if the task makes call to a method that does only a single job , and do not want it to be called again and again?

然后在作业进行时,通过作业内的多次调用删除循环并调用updateProgress。该循环仅出于演示目的而出现在此示例中,因为这是原始问题的具体要求。

Then remove the loop and invoke updateProgress through multiple calls within the job as the job progresses. The loop is only present in this sample for demonstration purposes and because this is what the original question specifically asked about.

例如,假设您的工作有3个阶段:取自数据库,执行计算并累积结果。每个阶段分别占总时间的30%,60%和10%,那么你可以在任务的 call()主体内做类似的事情:

For example lets say your job has 3 stages: fetch from database, perform calculation and accumulate results. Each stage taking an estimated 30 percent, 60 percent and 10 percent of total time respectively, then you can do something like this within the call() body of your task:

updateProgress(0, 1.0);
Data data = db.fetchData(query);
updateProgress(0.3, 1.0);
ProcessedData processed = calculator.process(data);
updateProgress(0.9, 1.0);
Result result = accumulator.reduce(processed);
updateProgress(1.0, 1.0);

这篇关于JavaFX刷新方法中的进度条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆