如何处理Property <t>,更改侦听器和属性的初始化?</t>

时间:2014-08-12 08:24:37

标签: java properties javafx listener

我正在使用JavaFX的Property<T>类,我对结果,缩小示例代码非常满意:

public CircularListCursor<E> {
    private final Property<E> elementProperty;

    public CircularListCursor() {
        this.elementProperty = new SimpleObjectProperty(/*some value*/);
    }

    //various methods that call elementProperty.setValue(/*some value*/);
}

用法:

private final CircularListCursor<SelectionData> selectionDataCursor;

...

selectionDataCursor.elementProperty().addListener((observableValue, oldValue, newValue) -> {
    oldValue.getLabel().setStyle("-fx-text-fill: black");
    newValue.getLabel().setStyle("-fx-text-fill: red");
});

现在这几乎完全 ,但它不会触发对象的构造。以这种方式工作是合乎逻辑的,因为在构造期间属性尚未绑定,因此也不能触发任何更改事件。

但我希望在构造过程中获得初始值以通知干净代码,有没有办法这样做?

2 个答案:

答案 0 :(得分:3)

在JavaFX中没有直接的解决方案。

然而,通过将侦听器代码移动到私有事件处理程序方法中,您可以使事情变得更容易/更清晰。然后可以在构造结束时调用此方法一次以初始化对象状态。感谢Java 8 lambda表达式,您可以直接将事件处理程序方法的方法引用用作侦听器:

// register event handler method    
selectionDataCursor.elementProperty().addListener(this::onElementChanged);

// call listener once for initialization:
onElementChanged(selectionDataCursor.elementProperty(), null, selectionDataCursor.getElement());

...

// event handler method
private void onElementChanged(ObservableValue<? extends E> observableValue, E oldValue, E newValue) {
    if (oldValue != null) oldValue.getLabel().setStyle("-fx-text-fill: black");
    if (newValue != null) newValue.getLabel().setStyle("-fx-text-fill: red");
}

旁注:无法再删除通过方法引用构建的侦听器。更具体地说,以下代码不会删除侦听器,因为this::onElementChanged每次创建一个新的侦听器时都不会等同于已注册的侦听器:

selectionDataCursor.elementProperty().removeListener(this::onElementChanged);

答案 1 :(得分:0)

使用EasyBind,您可以

  1. styleProperty
  2. 中选择嵌套的elementProperty
  3. 将嵌套的styleProperty绑定到某个可观察的字符串(在您的情况下,为红色文本填充的常量字符串)。
  4. bind方法提供一个额外的字符串参数,用于在元素更改时重置旧元素的样式属性。
  5. 以下是代码:

    ObservableValue<String> constRed = new SimpleStringProperty("-fx-text-fill: red");
    EasyBind.monadic(selectionDataCursor.elementProperty())
            .selectProperty(e -> e.getLabel().styleProperty())
            .bind(constRed, "-fx-text-fill: black");
    

    请注意您不需要注册任何侦听器 - 一个绑定就可以完成所有操作。绑定更多是声明性,而侦听器则更为必要(副作用)。