java - JavaFX Concurrency - Label 和 TextArea 之间的不同行为
问题描述
我对 JavaFX 和并发性很陌生。目前我正在努力更好地掌握它。
我了解 JavaFX 节点不是线程安全的,需要从应用程序 (UI) 线程进行更新。
在以下示例中,我使用该javafx.application
runLater
方法更新标签,否则我将抛出异常。但另一方面,我可以从后台任务中更新 TextArea:
textArea.appendText(status+"\n");
你能帮我理解在这种情况下 Label 和 TextArea 之间的区别,以及为什么一个不能在 BG 任务中更新而另一个可以吗?
package test;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class FxConcurrencyExample1 extends Application
{
// Create the TextArea
TextArea textArea = new TextArea();
// Create the Label
Label statusLabel = new Label("Not Started...");
// Create the Buttons
Button startButton = new Button("Start");
Button exitButton = new Button("Exit");
public static void main(String[] args)
{
Application.launch(args);
}
@Override
public void start(final Stage stage)
{
// Create the Event-Handlers for the Buttons
startButton.setOnAction(new EventHandler <ActionEvent>()
{
public void handle(ActionEvent event)
{
startTask();
}
});
exitButton.setOnAction(new EventHandler <ActionEvent>()
{
public void handle(ActionEvent event)
{
stage.close();
}
});
// Create the ButtonBox
HBox buttonBox = new HBox(5, startButton, exitButton);
// Create the VBox
VBox root = new VBox(10, statusLabel, buttonBox, textArea);
// Set the Style-properties of the VBox
root.setStyle("-fx-padding: 10;" +
"-fx-border-style: solid inside;" +
"-fx-border-width: 2;" +
"-fx-border-insets: 5;" +
"-fx-border-radius: 5;" +
"-fx-border-color: blue;");
// Create the Scene
Scene scene = new Scene(root,400,300);
// Add the scene to the Stage
stage.setScene(scene);
// Set the title of the Stage
stage.setTitle("A simple Concurrency Example");
// Display the Stage
stage.show();
}
public void startTask()
{
// Create a Runnable
Runnable task = new Runnable()
{
public void run()
{
runTask();
}
};
// Run the task in a background thread
Thread backgroundThread = new Thread(task);
// Terminate the running thread if the application exits
backgroundThread.setDaemon(true);
// Start the thread
backgroundThread.start();
}
public void runTask()
{
for(int i = 1; i <= 10; i++)
{
try
{
String status = "Processing " + i + " of " + 10;
System.out.println(status);
// Update the Label on the JavaFx Application Thread
Platform.runLater(new Runnable()
{
@Override
public void run()
{
statusLabel.setText(status);
}
});
textArea.appendText(status+"\n");
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
谢谢保罗
解决方案
推荐阅读
- c++ - 我在我的 C++ 代码警告中遇到错误:控制到达非 void 函数的结尾 [-Wreturn-type]
- geoip - 如何再次将 GeoLite CSV 文件编译到 MMDB 中?
- c++ - 如何在 C++ 中重载运算符 + 以便能够写入 c_str = "smth" + c_str;
- javascript - 当我将元素推入数组时,第一个元素被删除并替换为最近的元素
- java - 为什么 Hibernate with Specification 在第一个得到所有被询问的内容时会进行两个查询?
- python - 通过python在mongodb上查询创建json
- python - PyTorch Python && C++ 来自共享模型的不一致结果
- javascript - Chrome 扩展:将图像添加到 DOM
- matrix - Rust 2D 子窗口迭代器
- docker - Hyperledger Fabric 错误:签名集不满足策略