我试图做一条线,指向属性中的节点:

ObjectProperty<Node> pointedToNode = new SimpleObjectProperty();


我想要一行这样指向它:

line.endXProperty().bind(pointedToNode.get().layoutXProperty());


问题是当pointedToNode更改,绑定值(pointedToNode.get())已更改并且layoutXProperty()不再有效时。

如果pointedToNode的值为null,我还需要该行不可见。

我尝试了一些自定义的双重绑定,但没有成功。

最佳答案

使用普通API:

ChangeListener<Number> xListener = (obs, oldX, newX) ->
    line.setEndX(newX.doubleValue());
pointedToNode.addListener((obs, oldNode, newNode) -> {
    if (oldNode != null) {
        oldNode.layoutXProperty().removeListener(xListener);
    }
    if (newNode != null) {
        newNode.layoutXProperty().addListener(listener);
    }
});


或者,使用EasyBind框架:

line.endXProperty().bind(
    EasyBind.select(pointedToNode)
    .selectObject(Node::layoutXProperty)
    .orElse(-1)); // value if pointedToNode is null


您可以尝试使用Bindings.select(标准)API,该API看上去有点类似于EasyBind,但有几个缺点:它不能很好地处理“链”中的null值(即,如果pointedToNode.get()null );它不是类型安全的;而且很容易过早地进行垃圾收集。

line.endXProperty().bind(Bindings.selectDouble(pointedToNode, "layoutX"));


我建议使用EasyBind方法,或者,如果由于某种原因不想使用第三方库,只需在第一个代码块中使用“手工”侦听器方法。

为了提高知名度,只需

line.visibleProperty().bind(pointedToNode.isNull());

10-04 21:05