javafx - 使用 fx :id as CSS id in FXML

标签 javafx javafx-8

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

这可以通过一个小测试来演示 - 三个按钮,第一个带有 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? 似乎没有涵盖此问题, Javadoc 为 Node.getId()或我能找到的任何其他地方。

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

是否可以使用这种方法,或者我是否对可能在以后的版本中改变的未记录行为建立假设?或者它是否记录在我失踪的地方?

最佳答案

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

Assigning an fx:id value to an element creates a variable in the document's namespace that can later be referred to by variable dereference attributes ...

Additionally, if the object's type defines an "id" property, this value will also be passed to the objects setId() method.


它应该以“如果对象定义了 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);
                }
            }
            ...
        }
我认为建立在这种行为上是可以的。

关于javafx - 使用 fx :id as CSS id in FXML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29405658/

相关文章:

webview - 在页面加载之前在 JavaFX WebView 中注入(inject)桥接代码?

java - 为什么 SortedList.add() 抛出 UnsupportedOperationException?

javafx-8 - JavaFX 虚拟键盘不显示

java - 如何在 JavaFX 中混合 StackedBarChart 和 LineChart?

java - 在 tabpane 中的选项卡之间切换

java - 无法播放音频: Loading library gstreamer-lite from resource failed

javascript - JavaFX : Set default printer for WebEngine/Webview

java - 使用注解时的 NullPointerException 行为

java - 单击 ListView 中的项目启动动画

java - 在 Ubuntu 20 上安装 openJDK+openJFX 8