公开绑定属性

属性应该如何暴露?

例如:

class A{ private ObjectProperty objx; } class B{ private ObjectProperty objy; } 

我们想将objy绑定到objx或者从Bobjx添加一个监听器。 为objx做一个吸气剂objx ? 或者有没有办法制作一个包装函数来绑定并公开这个函数?

标准模式是

 class A { private final ObjectProperty objx = new SimpleObjectProperty<>(); public ObjectProperty objxProperty() { return objx ; } public final X getObjx() { return objxProperty().get(); } public final void setObjx(X objx) { objxProperty().set(objx); } } 

这里的想法是你有一个属性本身的访问器方法(一个“属性访问器”: objxProperty() ),它可以用于绑定和注册监听器,但该属性也显示为常规Java Bean :即那里是标准的getset方法。 一般契约是你应该总是有x.getObjx() == x.objxProperty().get() ,这是通过使Java Bean访问器方法( getObjx()setObjx )最终来强制执行的。

如果您希望能够在内部修改属性,但希望仅公开只读属性(其他代码可以绑定到该属性),请使用ReadOnlyObjectWrapper

 class A { private final ReadOnlyObjectWrapper objx = new ReadOnlyObjectWrapper<>(); public ReadOnlyObjectProperty objxProperty() { return objx.getReadOnlyProperty(); } public final X getObjx() { return objxProperty().get(); } } 

还要看看这个powerpoint演示文稿 ,虽然陈旧,但它显示了许多有用的习惯用法,例如属性的惰性和超级惰性初始化。

以下结构在JavaFX中广泛使用:

 class A { // Private inner property private ObjectProperty objx; // Public property accessor method public final ObjectProperty objxProperty() { if (objx == null) objx = new SimpleObjectProperty(DEFAULT_VALUE); return objx; } // Public setter method public final void setObjx(X val) { objxProperty().set(val); } // Public getter method public final X getObjx() {return objx == null ? DEFAULT_VALUE : objx.get();} } 

你在这里看到的是懒惰初始化 。 诀窍是私有内部属性在被(真的)被请求之前不会被初始化。

公共属性访问器objxProperty()将初始化私有内部属性objx 。 此属性访问器方法用于公开绑定和侦听的内部属性。 private内部属性获取“Property”后缀,可以将其视为JavaFX中的约定。

公共setter方法setObjx使用此属性访问器方法,因此在请求设置此属性的值的情况下,将初始化内部属性。

在公共getter getObjx()情况下有点不同,就好像内部属性尚未初始化(在属性上没有直接访问请求而之前没有设置请求),直接返回默认值而不初始化内部属性,进一步延迟初始化程序。

例如,对于JavaFX中TextFieldalignmentProperty ,您可以看到此技术。

如果你不想让事情复杂化,James_D在他的回答中解释的“标准模式”实际上是标准(方法命名与此处相同)。