【问题标题】:Using fx:id as CSS id in FXML在 FXML 中使用 fx:id 作为 CSS id
【发布时间】:2015-04-02 05:34:31
【问题描述】:

似乎在 FXML 中,如果您不指定 ID (CSS),则默认使用 fx:id 值。我之前的理解是这两者是完全不相交的,ID for CSS and only CSS。 fx:id 用于控制器中的@FXML 绑定。

这可以通过一个小测试来演示 - 三个按钮,第一个带有 ID,第二个带有 FX:ID,第三个带有两种类型的 ID。

<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>

使用 Node.lookup(cssSelector) 允许通过 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 也允许通过 fx:ID 进行选择

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

现有问题What's the difference between fx:id and id: in JavaFX?Node.getId() 的 Javadoc 或我能找到的任何其他问题似乎都没有涵盖这一点。

这个功能非常有用,因为我们只需要指定一个 fx:id 即可用于控制器、CSS 和使用 test-FX 的单元测试。

是否可以使用这种方法,或者我是否对未记录的行为进行假设,这些行为可能会在以后的版本中发生变化?或者它是否记录在我遗漏的地方?

【问题讨论】:

    标签: javafx javafx-8


    【解决方案1】:

    IMO 部分记录在 Introduction to FXML :: Variable Resolution 中。但乍一看并不那么明显:

    将 fx:id 值分配给元素会在 文档的命名空间,以后可以被变量引用 取消引用属性...

    此外,如果对象的类型定义 一个“id”属性,这个值也将被传递给对象 setId() 方法。

    它应该用“如果对象定义了 idProperty 并且尚未设置......”来完成。基于相关源代码在FXMLLoader 的第 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);
                    }
                }
                ...
            }
    

    我认为建立在这种行为上是可以的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-11
      • 2014-07-04
      相关资源
      最近更新 更多