gpt4 book ai didi

JavaFX 更新进度条并等待线程完成

转载 作者:行者123 更新时间:2023-12-01 22:47:23 29 4
gpt4 key购买 nike

我正在尝试更新 Java FX 中的进度条。我的第一个问题是窗口说“没有响应”而不是实际更新。它只是卡住了,然后任务完成后,进度条就满了。所以我发现我必须使用多线程并这样实现。

overallList.clear();
progressbar.setprogress(0);

for(Object obj : list) {
class ThreadProgress implements Runnable { // inner class
public void run() {
thisList = scrape(obj);
overallList.add(thisList);
progressbar.setProgress(progressbar.getProgress() + (double)1/size);
}
}

Thread current = new Thread(new ThreadProgress());
current.start();
}

textAreaConsole.setText("Total number of things:" + overallList.size());

但现在的问题是最后一行打印“事物总数:0”,因为在机器运行最后一行之前线程实际上并未完成执行。然后我找到了多种方法来解决这个问题,特别是使用 join() 或 ExecutorService。我像这样实现了 join() 。

overallList.clear();
progressbar.setprogress(0);
List<Thread> threads = new ArrayList<Thread>();

for(Object obj : list) {
class ThreadProgress implements Runnable { // inner class
public void run() {
thisList = scrape(obj);
overallList.add(thisList);
progressbar.setProgress(progressbar.getProgress() + (double)1/size);
}
}

Thread current = new Thread(new ThreadProgress());
current.start();
threads.add(current);
}

for(Thread thread : threads) thread.join(); // with a try-catch loop

textAreaConsole.setText("Total number of things:" + overallList.size());

但这让我回到了最初的问题,窗口再次显示“没有响应”。 ExecutorService 也发生了同样的事情。我现在不知道该怎么办。

最佳答案

请参阅下面的示例应用程序。它提供了一个简单的 ProgressBarLabel 来演示如何使用后台 Task 的进度更新 UI。

代码也有注释。

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ProgressBarExample extends Application {

// Create our ProgressBar
private ProgressBar progressBar = new ProgressBar(0.0);

// Create a label to show current progress %
private Label lblProgress = new Label();

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

@Override
public void start(Stage primaryStage) {

// Simple interface
VBox root = new VBox(5);
root.setPadding(new Insets(10));
root.setAlignment(Pos.CENTER);

// Button to start the background task
Button button = new Button("Start");
button.setOnAction(event -> startProcess());

// Add our controls to the scene
root.getChildren().addAll(
progressBar,
new HBox(5) {{
setAlignment(Pos.CENTER);
getChildren().addAll(
new Label("Current Step:"),
lblProgress
);
}},
button
);

// Here we will

// Show the Stage
primaryStage.setWidth(300);
primaryStage.setHeight(300);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}

private void startProcess() {

// Create a background Task
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {

// Set the total number of steps in our process
int steps = 1000;

// Simulate a long running task
for (int i = 0; i < steps; i++) {

Thread.sleep(10); // Pause briefly

// Update our progress and message properties
updateProgress(i, steps);
updateMessage(String.valueOf(i));
}
return null;
}
};

// This method allows us to handle any Exceptions thrown by the task
task.setOnFailed(wse -> {
wse.getSource().getException().printStackTrace();
});

// If the task completed successfully, perform other updates here
task.setOnSucceeded(wse -> {
System.out.println("Done!");
});

// Before starting our task, we need to bind our UI values to the properties on the task
progressBar.progressProperty().bind(task.progressProperty());
lblProgress.textProperty().bind(task.messageProperty());

// Now, start the task on a background thread
new Thread(task).start();
}
}

Edit: Added the setOnFailed() and setOnSucceeded() methods.

关于JavaFX 更新进度条并等待线程完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58468628/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com