簡體   English   中英

JavaFX刷新方法中的進度條

[英]JavaFX refresh Progress Bar within a method

我的UI中有一個javafx Progressbar然后我有一個for循環。 在for循環的每次迭代中都會發生這種情況:

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

在整個循環之后,會發生這種情況:

progress.setProgress(100);

我現在已經認識到UI控件只在方法完成后刷新,所以進度條不會更新直到結束,而不是imidatly設置為100。

那么有可能以某種方式強制UI更新,即使該方法沒有完成完成? 或者我怎么能這樣做?

如果你在你的循環中做了很長時間並且不應該在JavaFX應用程序線程上執行(它可能會執行或者你可能沒有這個問題),那么你應該在一個Task中運行循環,一個不同的線程,在循環進行時更新任務的進度,並將進度條的值綁定到任務的進度。

進展

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);
    }
}

如果任務調用只執行單個作業的方法,並且不希望一次又一次地調用它,該怎么辦?

然后刪除循環並在作業進行時通過作業內的多個調用調用updateProgress。 該循環僅出於演示目的而出現在此示例中,因為這是原始問題的具體問題。

例如,假設您的工作有3個階段:從數據庫中獲取,執行計算並累積結果。 每個階段分別占總時間的30%,60%和10%,然后你可以在任務的call()體內執行類似的操作:

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);

來自Java Doc的報價:

ProgressIndicator的實際進度。 進度的負值表示進度是不確定的。 0到1之間的正值表示進度百分比,其中0表示0%,1表示100%。 任何大於1的值都被解釋為100%。

這意味着簡單來說,你必須將值除以100,或者只是將值增加0.05而不是0.5。

快樂的編碼,
Kalasch

我的朋友告訴我使用它的例子。 你可以這樣做:

Platform.runLater(new Runnable() {
            @Override public void run() {
                bar.setProgress(counter/1000000.0);
            }
        });

刷新進度條位於其他Thread中

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM