3

I want to change the text of a Label with the controller from another class. I have made a method in the FXMLDocumentController, which sets the text to the label:

public void setLabelText(String text)
{
  lbZeit.setText(text);
}

Now I want to change this text from another class like my SerialHandlerClass. First, I need the controller, am I right? So I did this:

FXMLLoader loader = new FXMLLoader(FXMLDocumentController.class.getResource("FXMLDocument.fxml"));
loader.load();
controller = (FXMLDocumentController) loader.getController();

Now I run the "setLabelText" method....

controller.setLabelText("asd");

... and nothing happens...

It's very funny, because when I add System.out.println(text); to the "setLabelText(String text)" method, the program writes the correct text to the console.

But, why?

Sorry for my bad english, it's not my native language :)

Thanks, Julian

Uluk Biy
  • 48,655
  • 13
  • 146
  • 153
Stjubit
  • 57
  • 1
  • 8
  • Where does lbZeit come from? Do you (correctly) inject it using @FXML? Do you (incorrectly) assign it a value using lbZeit = new Label()? Is lbZeit null? Do you have an fx:id="lbZeit" (not id="lbZeit") in your FXML? – jewelsea Feb 15 '15 at 22:48
  • Thanks for your answer! I have made all these steps and if i execute the function in the same class as the "setLablText" method, it all works perfect! Could it be, that i have to update the UI from the other class? – Stjubit Feb 16 '15 at 10:16
  • No, you do not have to update the UI from another class. There is not enough information to solve your problem. Please edit your question to include the answers to the questions I asked - including an [mcve](http://stackoverflow.com/help/mcve) is enough. – jewelsea Feb 17 '15 at 18:08
  • possible duplicate of [Changing the text of a label from a different class in JavaFX](http://stackoverflow.com/questions/30308065/changing-the-text-of-a-label-from-a-different-class-in-javafx) – bummi May 18 '15 at 17:40

1 Answers1

3

You are not updating the label because you are creating another instance of FXMLDocumentController when you use the FXMLoader.

You should set the controller instance, that contains the label, as a parameter to the other Class.

Below you have the code that could solve your need. Here I set the Controller instance to the Connector class, so you can call the setLabelText method from the other class:

public class Connector {
    public static void Connecting(FXMLDocumentController controller) {
        try {
            System.out.println("Connector.Connecting(): Called");
            controller.setLabelText("Bye World");
        } catch (IOException ex) {
            Logger.getLogger(Connector.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}


public class FXMLDocumentController implements Initializable {

    @FXML
    private Label label;

    @FXML
    private void handleButtonAction(ActionEvent event) {
        System.out.println("FXMLDocumentController.#handleButtonAction");
        label.setText("Hello World!");
        Connector.Connecting(this);
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }    

    public void setLabelText(String text)
    {
        System.out.println("FXMLDocumentController.setLabelText(): Called");
        label.setText(text);
    }

}

Note:

If your routine is going to take longer to execute whatever it needs to, you might want to use a Task, so you don't freeze your UI. To update the Label, you have to bind the text property and then update the Text value using the updateMessage() method.

public class FXMLDocumentController implements Initializable {

    @FXML
    private Label label;

    @FXML
    private void handleButtonAction(ActionEvent event) {
        System.out.println("FXMLDocumentController.#handleButtonAction");
        label.setText("Hello World!");

        Task<Boolean> connectorTask = new ConnectorTask();
        label.textProperty().bind(connectorTask.messageProperty());
        connectorTask.setOnSucceeded(e -> {
            // this is going to be called if the task ends up without error
            label.textProperty().unbind();
        });
        new Thread(connectorTask).start();
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }    

    //public void setLabelText(String text)
    //{
    //    System.out.println("FXMLDocumentController.setLabelText(): Called");
    //    label.setText(text);
    //}


    public class ConnectorTask extends Task<Boolean> {

        @Override
        protected Boolean call() throws Exception {
            // ... do whatever you need here

            // then you call this method to update the TextProperty from the Label that was bound.
            updateMessage("Bye World");

            return Boolean.TRUE;
        }
    }

}

NOTE:

There is a possible duplicate question for this, please see my answer for this question here!

Community
  • 1
  • 1
henriqueor
  • 849
  • 1
  • 17
  • 38
  • Hi henriqueor, thanks for the edit, indeed it might be useful to flag duplicates if you find them. – bummi May 18 '15 at 21:33