Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaFX:FXML中的双向绑定_Java_Javafx_Data Binding_Fxml_Two Way Binding - Fatal编程技术网

JavaFX:FXML中的双向绑定

JavaFX:FXML中的双向绑定,java,javafx,data-binding,fxml,two-way-binding,Java,Javafx,Data Binding,Fxml,Two Way Binding,我正在使用JavaFX,并且正在研究数据绑定。 我发现我可以在FXML中定义单向绑定,如下所示: 这意味着usernameTextField的文本正在“观察”controller.userName属性 但这会创建一个单向绑定。如果controller.userName属性更改,我会在文本字段中看到更新的文本,该部分工作正常。但是我不能再在文本字段中插入文本,因为我已经进行了单向绑定 我所能找到的关于这一点的文章已经有四年多的历史了,但我不知道JavaFX是否已经更新以支持更精细的绑定。实现这一

我正在使用JavaFX,并且正在研究数据绑定。 我发现我可以在FXML中定义单向绑定,如下所示:

这意味着usernameTextField的文本正在“观察”controller.userName属性

但这会创建一个单向绑定。如果controller.userName属性更改,我会在文本字段中看到更新的文本,该部分工作正常。但是我不能再在文本字段中插入文本,因为我已经进行了单向绑定

我所能找到的关于这一点的文章已经有四年多的历史了,但我不知道JavaFX是否已经更新以支持更精细的绑定。

实现这一点的方法是:



但此功能尚未启用(上次在OpenJFX13上检查),使用它将导致
FXMLLoader
抛出
不支持操作异常(“此功能当前未启用”)

正如前面所说,没有简单的方法从FXML进行双向绑定。然而,它可以从FXML完成,但也就是说,不能使用FXML本身。以下是我的发现

块 第一种也是最明显的方法是使用
通过JavaScript进行所需的任何绑定。例如,可以使用以下代码段进行双向绑定:


javafx.beans.binding.Bindings.Bindings(
controller.someProperty(),
aControl.textProperty()
);
这里的
someProperty()
是名为
some
的属性的控制器方法

自定义帮助器类 第二个选项是创建一个helper类,然后在
块中使用它(使用上面的约定):


下面是这样一个类的示例实现:

包u7n.示例;
导入javafx.beans.binding.Bindings;
导入javafx.beans.property.property;
公共类投标{
私有对象o1;
私有字符串p1;
公共对象getO1(){return o1;}
public void setO1(对象o1){this.o1=o1;bind();}
公共字符串getP1(){return p1;}
public void setP1(字符串p1){this.p1=p1;bind();}
私有对象o2;
私有字符串p2;
公共对象getO2(){return o2;}
public void setO2(Object o2){this.o2=o2;bind();}
公共字符串getP2(){return p2;}
public void setP2(字符串p2){this.p2=p2;bind();}
私有无效绑定(){
if(o1==null | | p1==null | | o2==null | | p2==null)返回;
试一试{
@抑制警告(“未选中”)
属性property1=(属性)o1.getClass().getMethod(p1+“属性”).invoke(o1);
@抑制警告(“未选中”)
属性property2=(属性)o2.getClass().getMethod(p2+“属性”).invoke(o2);
Bindings.bindBidirective(property1,property2);
}
捕获(例外e){
e、 printStackTrace();
}
o1=o2=null;
p1=p2=null;
}
}
它使用反射来访问属性,因为我还没有找到让FXMLLoader将属性而不是其值传递给setter的方法

总而言之 这两种方法都不理想,但可以从FXML进行双向绑定,尽管这种方式并不方便。当然,大概是

<TextField fx:id="aControl" text="#{controller.some}"/>


这样会更好,但唉。另外,我不知道这两种方法在场景生成器中的效果如何,因为我不使用它。

此代码非常有效:

<TextField fx:id="usernameTextField" text="${controller.userName}"/>

我在另一篇文章的某个地方偶然发现了这一点,评论员发现这是一个bug,应该被删除。@Troels他们已经放弃了在FXML中声明双向绑定的语法,但实际的实现从未实现。不幸的是,有一个已经存在了一年多没有更新的版本。这样做似乎很奇怪,它三心二意地提供了部分功能,然后又放弃了它。我不希望控制器中引用我的GUI组件。谢谢你的输入,thouhg@Troels我还有一堆代码行,这些代码行应该从我的控制器中删除到FXML。等待在将来的版本中启用该功能。@Troels注意到JavaFX是开源的,这意味着任何有足够时间和动力的人都可以。我不是建议你做贡献者,我只是把信息放在那里。不,这段代码根本不起作用,并给出“此功能当前未启用。”错误。编辑后,将“#{controller.userName}”替换为“${controller.userName}”,然后它将是单向绑定,而不是双向绑定。
public String getUserName() { return "mystringvalue"; }