引用 Java FXML 中定义的集合
Referencing a Collection defined in Java FXML
我有以下 Java 代码:
@DefaultProperty("strings")
public class CustomControl extends HBox {
ChoiceBox<String> choiceBox = new ChoiceBox();
public ObservableList<String> getStrings() {
return choiceBox.getItems();
}
}
以及以下 FXML 代码:
<CustomControl>
<String fx:value="value1" />
<String fx:value="value2" />
</CustomControl>
这工作正常,但如果我用以下 FXML 代码替换 FXML 代码,它就不起作用:
<fx:define>
<FXCollections fx:factory="observableArrayList" fx:id="collection">
<String fx:value="value1" />
<String fx:value="value2" />
</FXCollections>
</fx:define>
...
<CustomControl>
<fx:reference source="collection" />
</CustomControl>
当我运行这个时,我得到以下类型的错误:
Unable to coerce [value1, value2] to class String.
我理解错误(它认为我想将整个字符串列表放入 "strings" bean 的第一个元素,而实际上我想要将列表中的每个项目添加到 "strings"bean),但我不知道如何做我想做的事。
这个想法是,我试图在 fxml 文件的开头定义一个项目列表,以便我可以在 fxml 文件的其他部分多次引用该列表。我不知道这个列表中会有多少项目,所以我不想给每个项目它自己的 ID。如何在不获取父元素的情况下引用一系列元素?或者有更好的方法吗?
在您的代码的第一个版本中,如果您将 fx:id
赋给 CustomControl
:
<CustomControl fx:id="customControl">
<String fx:value="value1" />
<String fx:value="value2" />
</CustomControl>
那么您应该能够使用
在 FXML 文件的其他地方引用该列表
${customControl.strings}
作为属性值,或
<fx:reference source="customControl.strings"/>
作为一个元素。
或者,如果您在 CustomControl
class 中定义 setStrings(...)
方法,我认为第二种方法有效,例如:
@DefaultProperty("strings")
public class CustomControl extends HBox {
ChoiceBox<String> choiceBox = new ChoiceBox();
public ObservableList<String> getStrings() {
return stringsProperty().get();
}
public void setStrings(ObservableList<String> strings) {
stringsProperty().set(strings);
}
public ObjectProperty<ObservableList<String>> stringsProperty() {
return choiceBox.itemsProperty();
}
}
在这个版本中,DefaultProperty
似乎不遵循 setStrings(...)
方法,但如果您明确指定 属性 它会起作用:
<fx:define>
<FXCollections fx:factory="observableArrayList" fx:id="collection">
<String fx:value="value1" />
<String fx:value="value2" />
</FXCollections>
</fx:define>
...
<CustomControl>
<strings>
<fx:reference source="collection" />
</strings>
</CustomControl>
我有以下 Java 代码:
@DefaultProperty("strings")
public class CustomControl extends HBox {
ChoiceBox<String> choiceBox = new ChoiceBox();
public ObservableList<String> getStrings() {
return choiceBox.getItems();
}
}
以及以下 FXML 代码:
<CustomControl>
<String fx:value="value1" />
<String fx:value="value2" />
</CustomControl>
这工作正常,但如果我用以下 FXML 代码替换 FXML 代码,它就不起作用:
<fx:define>
<FXCollections fx:factory="observableArrayList" fx:id="collection">
<String fx:value="value1" />
<String fx:value="value2" />
</FXCollections>
</fx:define>
...
<CustomControl>
<fx:reference source="collection" />
</CustomControl>
当我运行这个时,我得到以下类型的错误:
Unable to coerce [value1, value2] to class String.
我理解错误(它认为我想将整个字符串列表放入 "strings" bean 的第一个元素,而实际上我想要将列表中的每个项目添加到 "strings"bean),但我不知道如何做我想做的事。 这个想法是,我试图在 fxml 文件的开头定义一个项目列表,以便我可以在 fxml 文件的其他部分多次引用该列表。我不知道这个列表中会有多少项目,所以我不想给每个项目它自己的 ID。如何在不获取父元素的情况下引用一系列元素?或者有更好的方法吗?
在您的代码的第一个版本中,如果您将 fx:id
赋给 CustomControl
:
<CustomControl fx:id="customControl">
<String fx:value="value1" />
<String fx:value="value2" />
</CustomControl>
那么您应该能够使用
在 FXML 文件的其他地方引用该列表${customControl.strings}
作为属性值,或
<fx:reference source="customControl.strings"/>
作为一个元素。
或者,如果您在 CustomControl
class 中定义 setStrings(...)
方法,我认为第二种方法有效,例如:
@DefaultProperty("strings")
public class CustomControl extends HBox {
ChoiceBox<String> choiceBox = new ChoiceBox();
public ObservableList<String> getStrings() {
return stringsProperty().get();
}
public void setStrings(ObservableList<String> strings) {
stringsProperty().set(strings);
}
public ObjectProperty<ObservableList<String>> stringsProperty() {
return choiceBox.itemsProperty();
}
}
在这个版本中,DefaultProperty
似乎不遵循 setStrings(...)
方法,但如果您明确指定 属性 它会起作用:
<fx:define>
<FXCollections fx:factory="observableArrayList" fx:id="collection">
<String fx:value="value1" />
<String fx:value="value2" />
</FXCollections>
</fx:define>
...
<CustomControl>
<strings>
<fx:reference source="collection" />
</strings>
</CustomControl>