Joe*_*nst 4 java multithreading javafx-8
当用户选择在另一个线程中启动阻止进程的菜单项时,我试图在JavaFX 8应用程序中提供反馈.在我的实际应用程序中,它是一个文件下载,但我通过示例使用最小代码创建了一个测试用例:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.MenuButton;
import javafx.scene.control.ToolBar;
import javafx.scene.control.MenuItem;
import javafx.stage.Stage;
public class BlockingThreadTestCase extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
MenuItem menuItem = new MenuItem("Start");
MenuButton menuButton = new MenuButton();
menuButton.setText("Async Process");
menuButton.getItems().addAll(menuItem);
menuItem.setOnAction(event -> {
menuButton.setText("Running...");
Platform.runLater(() -> {
try {
// Simulate a blocking process
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
menuButton.setText(menuButton.getText() + "Done!");
});
});
final ToolBar toolbar = new ToolBar(menuButton);
final Scene scene = new Scene(toolbar);
primaryStage.setScene(scene);
primaryStage.setWidth(150);
primaryStage.show();
}
}
Run Code Online (Sandbox Code Playgroud)
这是它应该如何工作:当您选择"开始"菜单项时,主菜单文本应立即更改为"正在运行...",然后它应附加"完成!" 在模拟我的文件下载的5秒睡眠之后.
什么是实际发生的情况是这两个文本更新烧成后的阻塞进程完成后,即使我使用Platform.runLater().我究竟做错了什么?
最简单的方法是使用a Task.Platform.runLater仅在需要从其他线程更新UI时才需要,因此在您的情况下不需要.如果你想在运行时跟踪后台任务的进度,您可以使用updateMessage,并updateProgress在任务的方法来安全地传递消息到UI线程,而不必担心通过EDT调度.您可以在https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm找到更多相关信息.
请参阅下面的最小工作示例.
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ToolBar;
import javafx.stage.Stage;
public class BlockingThreadTestCase extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
MenuItem menuItem = new MenuItem("Start");
MenuButton menuButton = new MenuButton();
menuButton.setText("Async Process");
menuButton.getItems().addAll(menuItem);
menuItem.setOnAction(event -> {
menuButton.setText("Running...");
Task task = new Task<Void>() {
@Override
public Void call() {
//SIMULATE A FILE DOWNLOAD
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
};
task.setOnSucceeded(taskFinishEvent -> menuButton.setText(menuButton.getText() + "Done!"));
new Thread(task).start();
});
final ToolBar toolbar = new ToolBar(menuButton);
final Scene scene = new Scene(toolbar);
primaryStage.setScene(scene);
primaryStage.setWidth(150);
primaryStage.show();
}
}
Run Code Online (Sandbox Code Playgroud)