1
votes

Using JavaFX and Scene Builder, I am trying to access the text inside a Label from the controller.

I initialized a label as follows in the controller:

@FXML
private Label label1;

The following code is in the fxml file:

<Label fx:id="lable1" onMouseClicked="#handleLabel" text="Label 1" />

I have bound the label to this function in the controller using scene builder:

private void handleLabel(MouseEvent event) { 
// get text from label n
}

My idea was to call something like label1.getText(). But for that I need to get the fx:id of the label, and since I will many labels, I cannot hardcode all the id cases individually.

Better way for Getting id of the clicked Object in JavaFX controller I have found this, but I do not think the this answer works for me because initializing the label and setting an id does not seem to cope with @FXML. Also, it has not been answered whether it is possible to access the fx:id of a component.

Any other way for how to access the Label object's methods like getText() are also welcome.

1
((Label)event.getSource()).getText()? (Even if you could get the fx:id , which you can't, how would you use that to call getText()??) - James_D
The idea was to do label1.getText(). Since the fx:id is label1, I thought I could use the name of the id .getText(). But your way works, too. But the answer is you cannot access fx:id but have to find a way around it. Thanks! - sandboxj
But you wouldn't have label1 (which is an object reference): you would have a String variable containing the text "label1", which is not the same thing at all. What would you do then? - James_D
Note that your sample code has a typo, instead of fx:id="lable1" you should have fx:id="label1". Perhaps this typo or possible confusion with CSS id has lead you to create an XY problem. - jewelsea
You say you "will many labels, I cannot hardcode all the id cases individually", so perhaps your solution might be instead to create the labels in code via a loop and place them in an ObservableList rather than having the labels defined in FXML. FXML fx:ids are are hardcoded by their nature. - jewelsea

1 Answers

5
votes

It's not at all clear what you would do with the fx:id if you could get it. It is just the name of the variable that references the Label, so it is not part of the Label itself. Even if you did get the name, which presumably would be a string, what would you do then?

You can get a reference to the source of the event with event.getSource(), and assuming you have only registered this method as a handler for Labels, you can then downcast it to a Label:

private void handleLabel(MouseEvent event) { 
    Label label = (Label) event.getSource();
    String labelText = label.getText();
    System.out.println("Mouse click on label: "+labelText);
}

Generally, I find it much better to have a different handler for each control, instead of using a single handler that checks the source of the event like this. Obviously if you are using FXML, this gets very repetitive (but using FXML for a large number of controls is repetitive already). It might be better to do this in Java instead of FXML (or at least the part of the UI that has all these labels). Then you can register a different handler for each one without repeating the code:

VBox lotsOfLabels = new VBox();
for (int i = 1 ; i <= 100; i++) {
    Label label = new Label("Label "+i);
    lotsOfLabels.getChildren().add(label);
    label.setOnMouseClicked(e -> {
        System.out.println("Mouse click on "+label.getText());
        // etc...
    });
}

If you compare that code to the FXML for creating 100 labels (without even dealing with event handlers at all), it's pretty clear that using Java for a UI like this is quite a bit simpler than using FXML. And of course you could create a subclass of VBox that did the same thing, and simply reference that class from the FXML file if you wanted the rest in FXML.