Using fx: id as CSS id in FXML

It seems that in FXML, if you did not specify an ID (CSS), then the value fx: id is used by default. My previous understanding was that they were completely disjoint, ID for CSS and only CSS. fx: id for @FXML bindings in the controller.

This can be demonstrated by a small test - three buttons, first with an identifier, the second with FX: ID, the third with both types of identifiers.

<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> <children> <Button id="cssid0" mnemonicParsing="false" text="Button" /> <Button fx:id="fxid1" mnemonicParsing="false" text="Button" /> <Button id="cssid2" fx:id="fxid2" mnemonicParsing="false" text="Button" /> </children> </VBox> 

Using Node.lookup (cssSelector) allows you to select by fx: id

 @Override public void start(Stage stage) throws Exception { FXMLLoader loader = new FXMLLoader(getClass().getResource("/foo.fxml")); Parent p = loader.load(); System.out.println(p.lookup("#cssid0")); // => Button[id=cssid0, styleClass=button]'Button' System.out.println(p.lookup("#fxid1")); // => Button[id=fxid1, styleClass=button]'Button' System.out.println(p.lookup("#fxid2")); // => null (if there is a CSS ID it takes precedent) System.out.println(p.lookup("#cssid2")); // Button[id=cssid2, styleClass=button]'Button' stage.setScene(new Scene(p, 200, 200)); stage.getScene().getStylesheets().add("/foo.css"); stage.show(); } 

CSS also allows you to select using fx: ID

 #cssid0 { -fx-color: red; } #fxid1 { -fx-color: green; } #cssid2 { -fx-color: blue; } 

This is not like the existing question . What is the difference between fx: id and id: in JavaFX? , Javadoc for Node.getId () or anywhere else that I could find.

This function is really useful, because we need to specify only one identifier fx: id, which can be used for controllers, CSS and unit testing using test-FX.

Can this approach be used, or am I making assumptions about undocumented behavior that may change in a later release? Or is it documented somewhere I'm missing?

+6
source share
1 answer

IMO is partially registered in Introduction to FXML :: Variable Resolution . But at first glance this is not so obvious:

Assigning the element fx: id to the element creates a variable in the document namespace, which can later refer to the variable dereferencing attributes ...

In addition, if the object type defines the id property, this value will also be passed to setId () objects.

It must be filled "if the object defines idProperty and has not been installed already ...". Based on the source code, there is an FXMLLoader in a line of about 708:

  // Add the value to the namespace if (fx_id != null) { namespace.put(fx_id, value); // If the value defines an ID property, set it IDProperty idProperty = value.getClass().getAnnotation(IDProperty.class); if (idProperty != null) { Map<String, Object> properties = getProperties(); // set fx:id property value to Node.id only if Node.id was not // already set when processing start element attributes if (properties.get(idProperty.value()) == null) { properties.put(idProperty.value(), fx_id); } } ... } 

I think this is normal.

+3
source

Source: https://habr.com/ru/post/984599/


All Articles