JavaFX属性模式旨在扩展旧的标准JavaBean模式。因此,在您的示例中,根据JavaBean约定,您有一个类型
double为的(读写)属性
amount。这是由两种方法确定的
public double getAmount() ;public void setAmount(double amount);
JavaBean模式通过“绑定属性”允许某些有限的“可观察性”,其中Bean支持注册
PropertyChangeListener。UI工具箱通常需要观察属性并响应更改。例如,
Label具有
text属性是有意义的。如果
text属性发生更改,则
Label需要通知该属性,以便它知道自己重新绘制。乍一看,将JavaBean与绑定属性一起使用将是实现此目的的一种方法。但是,在UI工具箱中使用此机制会产生性能问题,因为如果不立即计算该值,就无法通知该值不再有效。这意味着,例如,对属性的每次单独更改都会重新计算布局。
JavaFX团队显然打算做的是定义一个模式
- 符合标准JavaBean模式,并且
- 支持的可观察属性,可以在每次更改值时都跟踪无效而无需重新计算从属值(“惰性可观察值”)
因此,JavaFX解决方案是创建同时支持
ChangeListeners和
InvalidationListeners的属性,这些属性在值更改时通知,而s在值不再有效时通知。这意味着,例如,布局机制可以跟踪当前是否有效,而在无效时不强制重新计算。仅在实际屏幕脉冲时(即渲染场景时),并且仅在无效时,才会重新计算布局。
(作为快速的概念验证,请考虑以下事项:
DoubleProperty width = new SimpleDoubleProperty(3);DoubleProperty height = new SimpleDoubleProperty(4);ObservableDoublevalue area = Bindings.createDoubleBinding(() -> { double a = width.get() * height.get(); System.out.println("Computed area: "+a); return a ;}, width, height);System.out.println("Area is "+area.getValue());width.set(2);height.set(3);System.out.println("Area is "+area.getValue());请注意,中间值当
width为2且
height仍为4时,永远不会进行计算。)
因此,JavaFX中的值由这些Observable表示,
Properties它们支持无效侦听器和更改侦听器,这意味着它们基本上是“惰性可观察的”。通过属性访问器方法(
amountProperty()在您的示例中)公开属性本身足以支持此功能。
然而,从语义上讲,公开
DoubleProperty表示bean具有type值
double。为了保持与旧JavaBean约定的兼容性,此bean应该通过公开相应的
get和
set方法来通告这一事实。因此,JavaFX属性模式既需要“属性访问器”(
amountProperty()),也需要标准JavaBean方法(
getAmount()和
setAmount(...))。这意味着遵循JavaFX模式的bean可以在使用标准JavaBean模式的任何地方使用,例如在JPA中。
请注意,该模式才能正常工作,它应该永远是真实的,
amountProperty().get() ==getAmount()并且
amountProperty().set(x)具有相同的效果
setAmount(x)。如示例中所述
get,通过和
set方法可以保证(即使bean类是子类的)
final。
如果您自己调用方法来检索或更改属性的值,则调用哪个都无所谓,因为可以保证它们具有相同的效果。由于JavaFX属性模式是JavaBean模式的扩展,因此可能会稍微偏爱调用
get和
set方法:从某种意义上来说,访问值仅需要JavaBean功能,而不需要完整的JavaFX属性功能,因此它可能会使语义上只能依靠该功能。但是,实际上,使用哪种都没有区别。



