何时使用JavaFX属性setter和getter,而不是直接使用该属性 [英] When to use JavaFX properties setter and getter, instead of using the property directly

查看:97
本文介绍了何时使用JavaFX属性setter和getter,而不是直接使用该属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我熟悉Java,但刚刚开始学习JavaFX,并专门了解JavaFX属性。我理解Oracle的以下示例中显示的基本设计模式:

  package propertydemo; 

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;

class Bill {

//定义一个变量来存储属性
private DoubleProperty amountDue = new SimpleDoubleProperty();

//为属性的值定义一个getter
public final double getAmountDue(){return amountDue.get();}

//定义一个setter for属性的值
public final void setAmountDue(double value){amountDue.set(value);}

//为属性本身定义一个getter
public DoubleProperty amountDueProperty() {return amountDue;}

}

我不明白的是何时/为什么我会使用getter和setter方法,而不是直接使用Property?



我在想的是你可能需要在getter中使用一些自定义代码/或setter可以对数据进行一些操作前/后操作/验证,但是如果你创建了一个自定义的getter和/或setter,那么你会得到不同的结果,这取决于你是直接使用getter / setter还是属性,对我来说,似乎很危险。



如果getter / setter只是调用Property的get和se方法,然后为什么要有它们?



任何对此的见解都将受到赞赏。

解决方案

JavaFX属性模式旨在扩展旧的标准JavaBean模式。因此,在您的示例中,根据JavaBean约定,您具有类型为 double 的(读写)属性,名为 amount 。这由两种方法决定

  public double getAmount(); 
public void setAmount(double amount);

JavaBean模式通过绑定属性允许一些有限的可观察性,其中bean支持注册a PropertyChangeListener
UI工具包通常需要观察属性并响应更改。例如, Label 有一个 text 属性是有意义的。如果 text 属性发生更改,则需要通知 Label ,以便它知道重绘自身。乍一看,使用具有绑定属性的JavaBeans将是一种方法。但是,在UI工具包中使用此机制会产生性能问题,因为如果不立即计算值,则无法通知值不再有效。这意味着,例如,布局将在对属性的每次单独更改时重新计算。



JavaFX团队显然希望做的是定义一个模式


  1. 符合标准JavaBean模式,

  2. 支持可观察属性,可以跟踪失效而无需重新计算依赖项每次值改变时的值(懒惰的可观察值)

因此,JavaFX解决方案是创建支持<$ c的属性$ c> ChangeListener s,在值更改时得到通知, InvalidationListener 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);
返回a;
},宽度,高度);
System.out.println(Area is+ area.getValue());
width.set(2);
height.set(3);
System.out.println(Area is+ area.getValue());

请注意,当 width 为2且时,中间值为高度仍为4,永远不会计算。)



因此,JavaFX中的值由这些可观察的 属性 ,它支持失效侦听器和更改侦听器,这意味着它们基本上是懒惰的可观察。通过属性访问器方法(在您的示例中 amountProperty())公开属性本身就足以支持此功能。



<但是,在语义上,暴露 DoubleProperty 意味着bean的值为 double 。为了保持与旧JavaBean约定的兼容性,这个bean应该通过公开相应的 get set 来宣传这一事实。方法。因此,JavaFX Property模式既需要属性访问器( amountProperty()),也需要标准的JavaBean方法( getAmount() setAmount(...))。这意味着遵循JavaFX模式的bean可以在使用标准JavaBean模式的任何地方使用,例如在 JPA中



请注意,为了使模式正常工作, amountProperty()。get()== getAmount()并且 amountProperty()。set(x) setAmount(x)具有相同的效果。通过使获取设置方法 final ,如您的示例所示。



如果您自己调用方法来检索或更改属性的值,则不会你称之为什么,因为它们保证具有相同的效果。由于JavaFX Property模式是JavaBean模式的扩展,因此可能会非常轻微地调用 get set 方法:在某种意义上,访问该值只需要JavaBean功能,而不是完整的JavaFX属性功能,因此它可能只是依赖于该功能而具有某种语义意义。然而,在实践中,你使用它没有任何区别。


I am familiar with Java, but just starting to learn JavaFX, and specifically learn about JavaFX properties. I understand the basic design pattern as shown in the following example from Oracle:

package propertydemo;

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;

class Bill {

    // Define a variable to store the property
    private DoubleProperty amountDue = new SimpleDoubleProperty();

    // Define a getter for the property's value
    public final double getAmountDue(){return amountDue.get();}

    // Define a setter for the property's value
    public final void setAmountDue(double value){amountDue.set(value);}

     // Define a getter for the property itself
    public DoubleProperty amountDueProperty() {return amountDue;}

}

What I don't understand is when/why I would use the getter and setter methods, instead of using the Property directly?

What I was thinking is that you may want some custom code in the getter and/or setter that may do some pre or post manipulation/validation of the data, but if you create a custom getter and/or setter, you would get different results then, depending on whether you use the getter/setter or property directly, which to me, seems dangerous.

If the getter/setter simply call the Property's get and set methods, then why even have them?

Any insights into this would be appreciated.

解决方案

The JavaFX property pattern is designed to extend the old, standard JavaBean pattern. So in your example, according to the JavaBean convention, you have a (read-write) property of type double called amount. This is determined by the two methods

public double getAmount() ;
public void setAmount(double amount);

The JavaBean pattern allows some limited "observability" via "bound properties", in which beans support registering a PropertyChangeListener. A UI toolkit often has need to observe properties and respond to changes. For example, it makes sense for a Label to have a text property. If the text property changes, the Label needs to be notified, so that it knows to repaint itself. At first glance, using JavaBeans with bound properties would be a way to do this. However, using this mechanism in a UI toolkit produces performance issues, because there is no way to have notifications that a value is no longer valid without computing it immediately. This means, for example, that layout would be recomputed on every individual change to a property.

What the JavaFX team apparently were aiming to do was define a pattern that

  1. conformed to the standard JavaBean pattern, and
  2. supported observable properties where invalidation could be tracked without recomputing dependent values every time the value changed ("lazily observable values")

So the JavaFX solution is to create properties which support both ChangeListeners, which are notified when a value changes, and InvalidationListeners, which are notified when a value is no longer valid. This means that, for example, a layout mechanism can track whether or not it is currently valid without forcing a recomputation when it becomes invalid. The layout will only recompute on an actual screen pulse (i.e. when the scene is rendered), and only if it is invalid.

(As a quick proof-of-concept, consider the following:

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());

Note here that the intermediate value, when width is 2 and height is still 4, is never computed.)

So values in JavaFX are represented by these observable Properties which support both invalidation listeners and change listeners, meaning they are basically "lazily observable". Exposing the property itself via a property accessor method (amountProperty() in your example) is enough to support this functionality.

Semantically, however, exposing a DoubleProperty means the bean has a value of type double. In order to maintain compatibility with the old JavaBean convention, this bean should advertise this fact by exposing the corresponding get and set methods. Consequently, the JavaFX Property pattern requires both a "property accessor" (amountProperty()) as well as the standard JavaBean methods (getAmount() and setAmount(...)). This means that beans following the JavaFX pattern can be used anywhere the standard JavaBean pattern is used, for example in JPA.

Note that for the pattern to work correctly, it should always be true that amountProperty().get() == getAmount() and that amountProperty().set(x) has the same effect as setAmount(x). This is guaranteed (even if the bean class is subclassed) by making the get and set methods final, as in your example.

If you are invoking the methods yourself to retrieve or change the value of the property, it doesn't matter which you call, since they are guaranteed to have the same effect. Since the JavaFX Property pattern is an extension of the JavaBean pattern, there may be a very slight preference to call the get and set methods: in a sense accessing the value only needs the JavaBean functionality, not the full JavaFX property functionality, so it might make some semantic sense to only rely on that functionality. In practice, however, it makes no difference which you use.

这篇关于何时使用JavaFX属性setter和getter,而不是直接使用该属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆