FXML,替代用途:使用 ObservableList<>

FXML, Alternate Uses: Using ObservableList<>

与此线程 一样,我正在构建一个使用 FXML 将对象直接加载到内存中的应用程序。

我已成功设置对象,其中可以轻松设置特定属性,如 hostNametypeNamemoto,例如但是,在 FXML 中,您有列表——例如 JavaFX UI 元素的子节点保存在 ObservableList 中。我在 FXML 中使用 features (ObservableList) 属性 时遇到问题。它给出了 UnsupportedOperationException: cannot determine type for property 的错误。为什么它不能将元素添加到列表中,如果它可以用于 BorderPane.

等其他对象

因为 ObservableList 没有 public 具体类型,所以您必须使用 FXCollections 工厂方法来获取实例。幸运的是,FXML 被设计用来处理这样的情况:通过使用 fx:factory 属性。您可以在 Introduction to FXML | JavaFX 10.

中了解有关不同 fx: 选项的更多信息

一个例子。

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.collections.FXCollections?>

<FXCollections fx:factory="observableArrayList" xmlns="http://javafx.com/javafx/10.0.2"
            xmlns:fx="http://javafx.com/fxml/1">

    <!-- your children elements -->

</FXCollections>

元素的类型将是fx:factory声明的工厂方法返回的类型。在这种情况下,ObservableList(由 ArrayList 支持)。


如果您有一个 class 定义的 ObservableList 字段(例如 features)和适当的 getter 您应该可以这样做:

<YourObject>
    <features>
        <!-- your feature elements -->
    </features>
</YourObject>

但是,我无法让它工作。当我尝试它时,只有第一个元素被添加到 ObservableList 中,我不知道为什么(也许是一个错误)。

我设法解决了这个问题:

<fx:define>
    <ArrayList fx:id="tempList">
        <!--- your feature elements -->
    </ArrayList>
</fx:define>

<YourObject>
    <features>
        <fx:reference source="tempList"/>
    </features>
</YourObject>

出于某种原因,我在使用 DefaultProperty 注释时也遇到了问题。它一直告诉我 "doesn't have a default property"... 但确实如此!

除了 "workaround" 之外,您可以像其他任何 属性 一样简单地将其 "set" 和 ObservableList。或者您可以(可能)将 FXML 注释与 fx:id.

结合使用