我正在使用 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");
});
现在这几乎完美地工作了,但它不会触发对象的构造。它以这种方式工作是合乎逻辑的,因为该属性在构造期间尚未绑定(bind),因此也不会触发更改事件。
但我确实希望在构造期间收到初始值的通知以允许干净的代码,有没有办法做到这一点?
最佳答案
在 JavaFX 中没有直接的解决方案。
不过,您可以通过将监听器代码移动到私有(private)事件处理程序方法中来使事情变得更简单/更清晰。然后可以在构造结束时调用一次此方法来初始化对象状态。感谢 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);
关于java - 如何处理 Property<T>、更改监听器和属性初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25259446/