Gurman Eduard
Gurman Eduard

Reputation: 73

How to use javaFX Task in my case - Not duplicate

I know there are answers for my questions but I did not understand the problem in my code.

Why I get :

java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4

I'm trying to add text from a Task to a Text flow using a method in the controller class, for some reason the program fails on .getChildren() method .

Call for Spliter in the controller class:

btnSplit.setOnMouseClicked(new EventHandler<Event>() {
            @Override
            public void handle(Event event) {
                Thread split = new Thread(new Spliter(custToSplit, Controller.this));
                split.setDaemon(true);
                split.start();

            }
        });

class Spliter constractor :

public Spliter(File f, Controller c){
        this.c = c;
        this.cust = f;

    }
c.updateHebFlow("Dir created: "+ newDir.getAbsolutePath() , INFO_TEXT);

Part of the Controller class :

@FXML
    private TextFlow hebFlow;
@Override
    public void initialize(URL location, ResourceBundle resources) {
assert hebFlow != null : "fx:id=\"hebFlow\" was not injected: check your FXML file 'MainXml.fxml'.";

    public void updateHebFlow(String text,String type){
        normalText = new Text();
        errorText = new Text();
        errorText.setFill(Color.RED);
        infoText = new Text();
        infoText.setFill(Color.BLUE);
        switch(type){
        case(ERROR_TEXT) :
            errorText.setText(text);
            hebFlow.getChildren().addAll(new Text("/n"), errorText);
            break;
        case(INFO_TEXT) :
            infoText.setText(text);
            hebFlow.getChildren().addAll(new Text("/n"), infoText);
            break;
        case(NORMAL_TEXT) :
            normalText.setText(text);
            hebFlow.getChildren().addAll(new Text("/n"), normalText);
            break;
        }
    }   
}

Call for updateHebFlow in Spliter class:

try{
c.updateHebFlow("Script by TulTul", INFO_TEXT);
}catch (Exception e){
            e.printStackTrace();
        }

From what I understand I cant change the UI from other class other then the controller so Ive made a method in the controller class that will make the changes and call it in the Task class, why I'm getting this exception? If this is wrong what is the wright way ?

Upvotes: 0

Views: 91

Answers (1)

Nikos Paraskevopoulos
Nikos Paraskevopoulos

Reputation: 40298

From what I understand I cant change the UI from other class other then the controller

Actually the correct statement is: "You cannot change the UI from any thread other than the JavaFX UI thread". So, the solution is to use Platform.runLater() from the Splitter as:

// Java 8
Platform.runLater(() -> {
    c.updateHebFlow("Script by TulTul", INFO_TEXT);
});

// Java 7
Platform.runLater(new Runnable() {
    public void run() {
        c.updateHebFlow("Script by TulTul", INFO_TEXT);
    }
});

Platform.runLater() is guaranteed to run the blocks in the JavaFX UI thread and in call order.

Upvotes: 1

Related Questions