我希望学习如何在JavaFX中使用线程。例如,有两个进程,每100毫秒更改标签上的文本,并且每100毫秒更新屏幕上的信息。
但是,在这种情况下它不起作用。IDEA会写:
“Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4”
我已经阅读了许多有同样问题的示例,但他们的任何解决方案都没有起作用。
我应该怎么做?
谢谢。
sample.fxml
但是,在这种情况下它不起作用。IDEA会写:
“Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; 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();
}
}
Platform.runLater
。或者,由于您已经在使用任务,可以通过使用updateMessage
更新message
属性而不是text
属性,并将text
属性绑定到message
属性:在启动线程之前,调用方法call
:/* firstStatus.setText(i+"");*/ updateMessage(Integer.toString(i));``firstStatus.textProperty().bind(task.messageProperty());
- fabian