JavaFX属性:重写getBean()方法?

时间:2017-03-22 02:40:43

标签: java javafx javafx-8

ReadOnlyProperty.getBean()的Javadoc说:

  

对象getBean()

     

返回包含此属性的Object。如果   该属性不包含在Object中,返回null。

我注意到在许多节点中,定义了大多数(如果不是全部)属性,以便覆盖getBean()方法。当然,考虑到getBean()在Javadoc中所说的内容,这样做是完全合理的。

但是,大多数人(比如你和我)可能会这样做:

ObjectProperty<MyClass> myObj = new SimpleObjectProperty<>();

我们不会覆盖getBean()方法,一切似乎都没有它。那么,是否有一些我们因为没有覆盖getBean()而遗漏的东西?

我已经看到Javadoc给出了很多覆盖这个方法的例子。例如来自PseudoClass Javadoc:

public boolean isMagic() {
    return magic.get();
}

public BooleanProperty magicProperty() {
    return magic;
}

public BooleanProperty magic =
    new BooleanPropertyBase(false) {

    @Override protected void invalidated() {
        pseudoClassStateChanged(MAGIC_PSEUDO_CLASS. get());
    }

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

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

private static final PseudoClass MAGIC_PSEUDO_CLASS = PseudoClass.getPseudoClass("xyzzy");

我们大多数人甚至不会使用抽象基类来实例化一个属性(很可能甚至不熟悉这样做)。为什么这个例子会这样做,而不是简单地这样做:

public boolean isMagic() {
    return magic.get();
}

public BooleanProperty magicProperty() {
    return magic;
}

public BooleanProperty magic =
    new SimpleBooleanPropertyBase(false) {

    @Override protected void invalidated() {
        super.invalidated();
        pseudoClassStateChanged(MAGIC_PSEUDO_CLASS. get());
    }
};

private static final PseudoClass MAGIC_PSEUDO_CLASS = PseudoClass.getPseudoClass("xyzzy");

或者更为熟悉的方法,即向BooleanProperty添加失效侦听器:

public BooleanProperty magic = new BooleanPropertyBase(false);
magic.addListener(observable -> pseudoClassStateChanged(MAGIC_PSEUDO_CLASS. magic.get());

编写Javadoc的方式,它表明这是正确的方法;如果你偏离了这种做法,你可能没有正确地做到这一点,并且你可能得不到预期的结果。

所以,这些是我的问题:

  1. 我们是否需要覆盖getBean()
  2. 在什么条件下我们需要或应该覆盖它?
  3. 是否有任何条件我们不能覆盖它?

1 个答案:

答案 0 :(得分:4)

TL;博士

  1. 您不必覆盖getBean()。
  2. 如果您需要这些信息,您应该覆盖它。
  3. 我不知道任何条件,你不能覆盖它。
  4. 属性“bean”是关于属性的元信息,是可选的。 (这同样适用于属性btw的“名称”。)属性的核心功能(获取和设置值,绑定,侦听器)将在您指定名称和拥有bean之后工作。

    但您可能希望在应用程序代码中使用此信息。例如,如果重用侦听器,则可以使用此信息来标识事件的来源。通用库和工具也可以使用此信息。例如,可以使用bean和name构建ScenicView(虽然我不知道它是如何实现的)。

    没有必要覆盖抽象基类。所有SimpleProperty类都有构造函数,允许您设置名称和bean。

    大多数内部属性覆盖抽象基类而不是实例化SimpleProperty的原因是内存占用量较小。如果你在少数几个对象中只有几个属性,这并不重要,因为你只保存了几个字节。但是,如果你在数百甚至数千个节点中拥有数十个属性,并且尝试在有限的设备上运行,那么这样的事情就开始变得重要了。出于同样的原因,内部属性覆盖invalidated()而不是附加侦听器。