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

是否认为开发人员应该在JavaFX中实现自己的XXXProperty?,java,javafx,Java,Javafx,我正在阅读有关javafx属性的文章,不明白为什么我们可以用来创建属性实例的非抽象类(例如SimpleStringProperty)的名称中有Simple单词。据我所知,实现中的Simple意味着basic实现某些东西 是否认为开发人员应该实现他们自己的XXXProperty,它必须在JavaFX中扩展XXXPropertyBase 让我们考虑例如Simple属性。< /P> java.lang.Object javafx.beans.binding.StringExpression

我正在阅读有关javafx属性的文章,不明白为什么我们可以用来创建属性实例的非抽象类(例如
SimpleStringProperty
)的名称中有
Simple
单词。据我所知,实现中的
Simple
意味着
basic
实现某些东西

是否认为开发人员应该实现他们自己的XXXProperty,它必须在JavaFX中扩展
XXXPropertyBase

让我们考虑例如Simple属性。< /P>

 java.lang.Object
    javafx.beans.binding.StringExpression
        javafx.beans.property.ReadOnlyStringProperty
            javafx.beans.property.StringProperty
                javafx.beans.property.StringPropertyBase
                    javafx.beans.property.SimpleStringProperty 
我们是否应该开发自己的
OurStringProperty
,以扩展
StringPropertyBase


同时,据说
javafx.beans.property.StringProperty类提供了包装字符串值的属性的完整实现。那么为什么我们需要这个
SimpleStringProperty
?如何解释?

下面是一个示例,介绍如何使用JavaFX提供的实现向类中添加简单的基于对象的属性(字符串和基元类型也有类似的类):

private final ObjectProperty foo=新的SimpleObject属性(此,
“foo”,空);
公开决赛Foo getFoo(){
返回fooProperty().get();
}
公开最终作废setFoo(Foo Foo){
fooProperty().set(foo);
}
公共对象属性fooProperty(){
返回foo;
}
以下是基于JavaFX提供的一些基类的只读属性实现示例:

public class MyClass {

    private final ReadOnlyBarProperty bar = new ReadOnlyBarProperty();

    public final Bar getBar() {
        return barProperty().get();
    }

    private void setBar(Bar bar) {
        this.bar.set(bar);
    }

    public ReadOnlyObjectProperty<Bar> barProperty() {
        return bar;
    }

    [...]

    private class ReadOnlyBarProperty extends ReadOnlyObjectPropertyBase<Bar> {

        private Bar bar = null;

        @Override
        public final Bar get() {
            return bar;
        }

        private void set(Bar newValue) {
            if (!Objects.equals(bar, newValue)) {
                bar = newValue;
                fireValueChangedEvent();
            }
        }

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

        @Override
        public String getName() {
            return "bar";
        }
    }
}
公共类MyClass{
private final ReadOnlyBarProperty bar=新的ReadOnlyBarProperty();
公共最终酒吧{
返回barProperty().get();
}
专用空心立根杆(条形){
此.bar.set(bar);
}
public ReadOnlyObjectProperty barProperty(){
返回杆;
}
[...]
私有类ReadOnlyBarProperty扩展了ReadOnlyObjectPropertyBase{
专用条=空;
@凌驾
公共最终酒吧{
返回杆;
}
专用无效集(条形新值){
如果(!Objects.equals(bar,newValue)){
bar=新值;
fireValueChangedEvent();
}
}
@凌驾
公共对象getBean(){
返回MyClass.this;
}
@凌驾
公共字符串getName(){
返回“bar”;
}
}
}
然后,在一些罕见的情况下,您希望提供自己的属性实现。我写了一封信

我希望这些样品能澄清一些问题。

视情况而定

标准JavaFX库中有一种相当常见的模式,即创建本地或匿名类来扩展其中一个“基类”(
readonlyxxpropertybase
XXXPropertyBase
)。根据我的经验,这样做通常有两个原因:

  • 它是一个只读属性,其值是从属性外部管理的
  • 当属性无效时,必须在内部发生某些事情
  • 要查看第一个案例的示例,请查看。此属性类有自己的两个属性,
    empty
    size
    ,继承自
    ListExpression
    。正如预期的那样,这些属性反映了所包含的
    ObservableList
    的空状态和大小状态。这些属性的实现方式是作为本地类,但它们的值由
    ObservableList
    本身管理。
    ListPropertyBase
    类只是让它们在适当的时候触发更改事件

    对于第二种情况,本地或匿名类将覆盖大多数(全部?)的
    XXXPropertyBase
    类提供的受保护的
    invalidated
    方法。当属性无效时调用此方法。它允许一个人做出反应,而不需要倾听者的开销。您可以通过查看。例如,
    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";
        }
    };
    
    public final ObjectProperty onActionProperty(){return onAction;}
    public final void setOnAction(EventHandler值){onActionProperty().set(value);}
    公共最终事件处理程序getOnAction(){return onActionProperty().get();}
    private ObjectProperty onAction=new ObjectPropertyBase(){
    @覆盖受保护的无效(){
    setEventHandler(ActionEvent.ACTION,get());
    }
    @凌驾
    公共对象getBean(){
    返回按钮base.this;
    }
    @凌驾
    公共字符串getName(){
    返回“onAction”;
    }
    };
    
    当属性无效时,
    invalidated
    方法从
    节点注册/注销
    EventHandler

    综上所述,如果不需要添加自定义行为,请坚持对只读属性使用
    readonlyxxwrapper
    ,对读写属性使用
    simplexxproperty


    简单
    ? 为什么具体实现的名称中有
    Simple
    ?为什么不让
    XXXProperty
    成为具体的实现

    我不能给出一个明确的答案,因为我没有参与开发,但我可以给出一个猜测:JavaFX开发人员希望提供多个“扩展点”,提供不同程度的“已经实现”。需要完全定制吗?扩展
    XXXProperty
    。需要定制吗?扩展
    XXXPropertyBase
    。等等

    simplexxproperty
    类需要的名称与
    XXXProperty
    类名称不冲突<代码>简单
    适合,因为这就是它们的简单实现。它们只做接口所需的事情


    值得一提 在API级别上,几乎每个JavaFX类都将属性公开为
    readonlyxxproperty
    XXXProperty
    。它从来都不是
    属性
    simplexxproperty
    。巴斯
    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";
        }
    };