JavaFX-无法将对象强制为SimpleListProperty

JavaFX-无法将对象强制为SimpleListProperty,java,javafx,javafx-8,Java,Javafx,Javafx 8,我试图确定是否有一种方法可以从fxml加载ListProperty,比如SimpleListProperty,而不包括FXCollections层。有没有办法使案例1的功能与案例2类似 public class AppMenuItem extends MenuItem { private SimpleListProperty<InteractionDefinition> interactions = new SimpleListProperty<>();

我试图确定是否有一种方法可以从fxml加载
ListProperty
,比如
SimpleListProperty
,而不包括
FXCollections
层。有没有办法使案例1的功能与案例2类似

public class AppMenuItem extends MenuItem {
    private SimpleListProperty<InteractionDefinition> interactions = new SimpleListProperty<>();

    public void setInteractions(ObservableList<InteractionDefintion> interactionsTmp);
}
公共类AppMenuItem扩展了MenuItem{
私有SimpleListProperty交互=新SimpleListProperty();
公共交互(可观察列表交互TMP);
}
案例1


案例2


答案 问题是存在setter方法。在FXML文档简介部分,您将看到:

属性元素 标记名以小写字母开头的元素表示对象属性。属性元素可以表示以下内容之一:

  • 属性设置器
  • 只读列表属性
  • 只读映射属性
属性设置器 如果元素表示属性setter,则元素的内容(必须是文本节点或嵌套类实例元素)将作为属性的值传递给setter

只读列表属性 只读列表属性是一个Bean属性,其getter返回
java.util.list
的实例,并且没有相应的setter方法。只读列表元素的内容在处理时会自动添加到列表中

FXMLLoader
处理
标记时,它将尝试使用标记中定义的对象更新相应的属性。其如何更新属性取决于上述文件中规定的规则,其中一些规则已在上文中引用。由于您有一个setter方法(以
setInteractions(observelist)
的形式),它将尝试将标记中定义的对象强制为
observelist
,并使用setter方法;这是因为property元素被确定为“property setter”,而不是“只读列表属性”。因此,案例1失败,因为您没有定义一个
ObservableList
,而是定义多个
InteractionDefinition
s

如果您想使用案例1,您需要将
iteractions
属性设置为只读,并添加一个getter方法。仅从
fxmloader
的角度来看,该属性才需要是只读的。换句话说,只要没有遵循标准JavaBean约定的setter方法,
fxmloader
就会假定该属性是只读的

至少,将代码更改为以下内容将允许您使用用例1:

您希望得到强制错误,因为有一个setter,它需要一个
可观察列表
,而不是
字符串
。有趣的是,如果稍微更改FXML,就会出现错误


现在抛出一个错误。那么是什么原因呢?我能发现的唯一区别是使用。如果指定了默认属性,而您未在FXML文件中显式使用元素标记(例如,
),则它将作为“只读列表属性”(如果默认属性是或包含
列表
),而不是“属性设置器”。一旦明确使用元素标记(例如
),则其行为与本答案第一部分所述相同我找不到明确描述这种行为的文档,这可能意味着这是一个bug。另外,请注意,我只在Java 10.0.2上尝试过这种方法

如果您希望依赖于此,并且由于
MenuItem
没有
DefaultProperty
,您可以尝试使用以下方法:

Java代码:

@DefaultProperty(“交互”)
公共类AppMenuItem扩展了MenuItem{
私有最终列表属性交互=新的SimpleListProperty(“交互”);
公共最终交互(可观察列表交互){
this.interactions.set(interactions);
}
公共最终可观察列表getInteractions(){
返回交互。get();
}
公共最终列表属性交互属性(){
回报互动;
}
}
FXML文件:


对不起,沙拉!结果证明你在钱的问题上是对的,而我使用的setter方法确实是give造成了我的问题。在这种情况下,默认项对我没有多大好处,因为这是我们小部件集合的更广泛的解决方案,我认为它们只会为完全定制的小部件和独特的情况真正增加价值。
public class AppMenuItem extends MenuItem {

    private SimpleListProperty<InteractionDefinition> interactions = new SimpleListProperty<>();

    public ObservableList<InteractionDefinition> getInteractions() {
        return iteractions.get();
    }

}