我正在使用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");
});
现在这几乎完全 ,但它不会触发对象的构造。以这种方式工作是合乎逻辑的,因为在构造期间属性尚未绑定,因此也不能触发任何更改事件。
但我做希望在构造过程中获得初始值以通知干净代码,有没有办法这样做?
答案 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,您可以
styleProperty
。elementProperty
styleProperty
绑定到某个可观察的字符串(在您的情况下,为红色文本填充的常量字符串)。bind
方法提供一个额外的字符串参数,用于在元素更改时重置旧元素的样式属性。以下是代码:
ObservableValue<String> constRed = new SimpleStringProperty("-fx-text-fill: red");
EasyBind.monadic(selectionDataCursor.elementProperty())
.selectProperty(e -> e.getLabel().styleProperty())
.bind(constRed, "-fx-text-fill: black");
请注意您不需要注册任何侦听器 - 一个绑定就可以完成所有操作。绑定更多是声明性,而侦听器则更为必要(副作用)。