我想学习如何在JavaFX中使用Threads。例如,2个进程,每100毫秒应更改标签上的文本,并且每隔100毫秒更新一次屏幕上的信息。
但在这种情况下它不起作用。 IDEA写道:
线程“Thread-4”中的异常java.lang.IllegalStateException:不在FX应用程序线程上; currentThread = Thread-4
我已经阅读了许多具有相同问题的示例,但他们的任何解决方案都无效。
我该怎么做?
感谢。
sample.fxml
...
<Button fx:id="startBut" layoutX="100.0" layoutY="50.0" mnemonicParsing="false" onAction="#testingOfThread" prefHeight="25.0" prefWidth="65.0" text="Export" />
<Label fx:id="firstStatus" layoutX="100.0" layoutY="100" text="Status" />
<Label fx:id="secondStatus" layoutX="100.0" layoutY="150" text="Status" />
...
Main.java
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Sample");
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
//Take control to Controller
public void initializeController(){
FXMLLoader loader = new FXMLLoader();
Controller controller = loader.getController();
controller.setMain(this);
}
public static void main(String[] args) {
launch(args);
}
}
Controller.java
package sample;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.scene.control.*;
public class Controller {
@FXML
private Label firstStatus;
@FXML
private Label secondStatus;
@FXML
public Button startBut;
//Link to MainApp
private Main Main;
//Constructor
public Controller(){
}
//Link for himself
public void setMain(Main main){
this.Main = main;
}
@FXML
private void testingOfThread(){
Task<Void> task = new Task<Void>() {
@Override public Void call() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.interrupted();
break;
}
System.out.println(i + 1);
firstStatus.setText(i+"");
}
return null;
}
};
Thread th = new Thread(task);
th.setDaemon(true);
th.start();
Task<Void> task2 = new Task<Void>() {
@Override public Void call() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.interrupted();
break;
}
System.out.println(i + 1);
secondStatus.setText(i+"");
}
return null;
}
};
Thread th2 = new Thread(task2);
th2.start();
}
}
答案 0 :(得分:1)
找到从应用程序线程以外的线程更新GUI的代码,然后将其放入runLater()。
Platform.runLater(new Runnable() {
@Override
public void run() {
//update application thread
}
});