-1

How do I change the text of a JavaFX label only via the ID? A simplified version of the code is shown below.

For context, we have a grid (GridPane) of labels (it's a sudoku game), the labels are numbered from Label_0_0, ..., to Label_8_8 (indicating the location in the grid). We are going over the label grid in a nested for loop and are trying to set different numbers at different lables/grid-boxes using the ID at the current coordinates of the for loop. (For simplicity, I omitted the for loop etc. in the code example.)

I've searched the entire internet for answers and haven't figured it out yet, any help is highly appreciated :)

String labelID = "ID_1";
int index = 5;

Label currentlySelectedLabel = (Label) ???; // sth like xx.getElementByID, if that existed
currentlySelectedLabel.setText(Integer.toString(index));

Some reference to the labels in the FXML:

...
            <Label fx:id="Label_8_6" alignment="CENTER" onMouseClicked="#MyFrstLabelClicked" onMouseMoved="#OnMouseMovedOnLabel" prefHeight="44.0" prefWidth="46.0" text="0" GridPane.columnIndex="6" GridPane.rowIndex="8" />
            <Label fx:id="Label_8_7" alignment="CENTER" onMouseClicked="#MyFrstLabelClicked" onMouseMoved="#OnMouseMovedOnLabel" prefHeight="44.0" prefWidth="46.0" text="0" GridPane.columnIndex="7" GridPane.rowIndex="8" />
            <Label fx:id="Label_8_8" alignment="CENTER" onMouseClicked="#MyFrstLabelClicked" onMouseMoved="#OnMouseMovedOnLabel" prefHeight="44.0" prefWidth="46.0" text="0" GridPane.columnIndex="8" GridPane.rowIndex="8" />
            </children>
        </GridPane>
    </center>
</BorderPane>
J_R
  • 23
  • 4

1 Answers1

2

Preferred approach: use a reference not a lookup

A preferred approach would be to store a reference to the nodes and use the stored reference. That way you don't lose all of the goodness of strong typing, compile-time checks, and IDE intelligent editing assistance.

For an example of a preferred approach see:

Additionally, more substantial projects may benefit from a MVC approach so that updates made to the model are automatically reflected in the nodes (and vice-versa):

Performing a lookup

You can find a node by CSS ID via a node lookup call on a node or a node lookup call on a scene.

For example:

Label lookedupLabel = (Label) scene.lookup("#myId");

The call takes a CSS selector to find a matching node.

Finds this Node, or the first sub-node, based on the given CSS selector. If this node is a Parent, then this function will traverse down into the branch until it finds a match. If more than one sub-node matches the specified selector, this function returns the first of them.

This approach assumes that an ID has already been set on the node by calling setId:

node.setId("myId");

Or in FXML when the node is defined you can set an fx:id attribute:

fx:id="myId"

or an id attribute:

id="myId"

Either will work, but only setting the fx:id is usually more convenient as it will also set the corresponding @FXML reference value in the controller, in addition to the CSS id.

Generating a layout pass

For the lookup to function, you may need to perform a layout pass, by calling:

parentNode.applyCss();
parentNode.layout();

Perform a layout pass before a CSS lookup if:

  1. you have modified the scene graph in the current pulse, OR
  2. you are trying to find a node that will dynamically be created by the skin of a control, OR
  3. you want to find the dimensions of a node you look up.

If the layout pass is not performed, the looked-up node might not be found or may report the incorrect attribute values.

For more information on layout passes see:

jewelsea
  • 150,031
  • 14
  • 366
  • 406