是否应该认为开发人员应该在JavaFX中实现自己的XXXProperties?

时间:2018-10-19 19:36:16

标签: java javafx

我正在阅读有关javafx属性的信息,但无法理解为什么我们可用于创建属性实例的非抽象类(例如SimpleStringProperty)的名称中带有Simple字。据我所知,Simple的实现意味着basic的某些实现。

是否假定开发人员应该实现自己的XXXProperty,而该属性必须在JavaFX中扩展XXXPropertyBase

让我们考虑例如SimpleStringProperty。

 java.lang.Object
    javafx.beans.binding.StringExpression
        javafx.beans.property.ReadOnlyStringProperty
            javafx.beans.property.StringProperty
                javafx.beans.property.StringPropertyBase
                    javafx.beans.property.SimpleStringProperty 

我们是否应该开发将扩展OurStringProperty的{​​{1}}?

同时在javadoc中被称为StringPropertyBase。那么,为什么我们需要这个javafx.beans.property.StringProperty class provides a full implementation of a Property wrapping a String value?怎么解释?

2 个答案:

答案 0 :(得分:1)

这里是一个示例,该示例如何使用JavaFX提供的实现将简单的基于对象的属性添加到您的类中(对于String和基本类型存在类似的类):

let oldparents = [...siblings[childitem].my.parents];// or you can use Array.from
let newparents = oldparents.filter(e => e != selected.my.place); // here the arrow function also needs to be updated, remove the braces

以下是基于JavaFX提供的一些基类的只读属性实现的示例:

private final ObjectProperty<Foo> foo = new SimpleObjectProperty<>(this,
        "foo", null);

public final Foo getFoo() {
    return fooProperty().get();
}

public final void setFoo(Foo foo) {
    fooProperty().set(foo);
}

public ObjectProperty<Foo> fooProperty() {
    return foo;
}

然后在少数情况下,您想提供自己的属性实现。例如。我在SimpleEventHandlerProperty中写了Drombler Commons

我希望这些样本能使事情变得更清楚。

答案 1 :(得分:1)

这取决于

标准JavaFX库中有一个相当普遍的模式,用于创建扩展“基”类之一(ReadOnlyXXXPropertyBaseXXXPropertyBase)的本地或匿名类。以我的经验,这样做通常是出于以下两个原因之一:

  1. 这是一个只读属性,其值是从属性外部进行管理的。
  2. 该属性无效时,必须在内部进行某些事情。

要查看第一种情况的示例,请查看source code of ListPropertyBase。此属性类具有自己的两个属性emptysize,它们继承自ListExpression。正如预期的那样,这些属性反映了所包含的ObservableList的空白状态和尺寸状态。这些属性的实现方式是作为本地类,但它们的值由ObservableList本身管理。 ListPropertyBase类仅在适当时让它们触发更改事件。

在第二种情况下,本地或匿名类将覆盖由​​invalidated类中的大多数(全部)提供的受保护的XXXPropertyBase方法。属性无效时将调用此方法。它允许一个人做出反应而没有监听程序的开销。您可以通过查看source code of ButtonBase来了解这一点。例如,onAction属性:

public final ObjectProperty<EventHandler<ActionEvent>> onActionProperty() { return onAction; }
public final void setOnAction(EventHandler<ActionEvent> value) { onActionProperty().set(value); }
public final EventHandler<ActionEvent> getOnAction() { return onActionProperty().get(); }
private ObjectProperty<EventHandler<ActionEvent>> onAction = new ObjectPropertyBase<EventHandler<ActionEvent>>() {
    @Override protected void invalidated() {
        setEventHandler(ActionEvent.ACTION, get());
    }

    @Override
    public Object getBean() {
        return ButtonBase.this;
    }

    @Override
    public String getName() {
        return "onAction";
    }
};

如果属性无效,则invalidated方法会从EventHandler注册/注销Node

话虽如此,如果您不需要添加自定义行为,请坚持将ReadOnlyXXXWrapper用于只读属性,将SimpleXXXProperty用于读写属性。


Simple

为什么具体实现的名称中有Simple?为什么不仅仅将XXXProperty作为具体实现呢?

由于我没有参与开发,所以我无法给出确切的答案,但是我可以提供一个猜测:JavaFX开发人员希望提供多个“扩展点”,以提供不同程度的“已实现”。需要完全定制吗?扩展XXXProperty。需要定制吗?扩展XXXPropertyBase。依此类推。

SimpleXXXProperty类需要与XXXProperty类名称不冲突的名称。 Simple之所以合适,是因为它们就是简单的实现。他们什么也不做,只是接口需要什么。


值得一提

在API级别上,几乎每个JavaFX类都将属性公开为ReadOnlyXXXPropertyXXXProperty。决不是Property<SomeObject>SimpleXXXProperty。基本上,关于属性,请考虑将ReadOnlyXXXPropertyXXXProperty用作“接口编程”。就像您公开List而不是ArrayList一样。

我也会考虑该报价:

  

此类提供了Property的完整实现,该String包装了一个StringProperty值。

具有误导性。如果您查看int atoi(char *s) { int c=1, a=0, sign, start, end, base=1; //Determine if the number is negative or positive if (s[0] == '-') sign = -1; else if (s[0] <= '9' && s[0] >= '0') sign = 1; else if (s[0] == '+') sign = 2; //No further processing if it starts with a letter else return 0; //Scanning the string to find the position of the last consecutive number while (s[c] != '\n' && s[c] <= '9' && s[c] >= '0') c++; //Index of the last consecutive number from beginning start = c - 1; //Based on sign, index of the 1st number is set if (sign==-1) end = 1; else if (sign==1) end = 0; //When it starts with +, it is actually positive but with a different index //for the 1st number else { end = 1; sign = 1; } //This the main loop of algorithm which generates the absolute value of the //number from consecutive numerical characters. for (int i = start; i >=end ; i--) { a += (s[i]-'0') * base; base *= 10; } //The correct sign of generated absolute value is applied return sign*a; } 的来源,肯定不是 一个“完整的实现”。也许是要说它的API级别类?也许是试图说它实现了所有必要的接口?老实说,我不知道...