JavaFX中的线程:不在FX应用程序线程

时间:2018-03-18 00:16:03

标签: multithreading javafx

我想学习如何在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();

    }
}

1 个答案:

答案 0 :(得分:1)

找到从应用程序线程以外的线程更新GUI的代码,然后将其放入runLater()。

Platform.runLater(new Runnable() {
    @Override
    public void run() {
        //update application thread
    }
});