如何实现多个属性的绑定以相互监听?
我有两个Circle可拖动的节点,我想将它们与Line连接节点(不是从它们的中心,而是从它们的周边)连接起来。但是随着Circle拖动位置的变化,Line'sstartX和startY值发生变化,因此sLine成为两个Circles之间的最短线,与连接它们的半径的线共线。
我的问题是,让Line's startX, startY, endX, 和endY每个单独监听或绑定到Circles'centerXProperty和centerYProperty(或者更确切地说,绑定到具有这些属性值的计算)似乎过于冗长,因为这将导致总共 16 个绑定/侦听器。
我想知道是否有更简单或更方便的方法来实现这一点。我正在考虑创建一个对象SimpleDoubleProperty的斜率Line(y2 - y1)/(x2 - x1),绑定到两个centerXPropertys 和centerYPropertys,并且有startX, startY, endX, 和endY每个都听那个属性,但我也是不确定如何将单个属性绑定到这四个属性的结果计算。
这是我目前构建我的Line. 我正在尝试startXProperty和startYProperty绑定并意识到它正确更新了Line但仅在源 Circlesource移动时才更新,这促使我提出这个问题。TheendXProperty和endYPropertystill 都将Line锚定在目标圆的中心。如果需要,我可以提供我的整个代码,尽管我认为这足以满足我想要完成的任务。
public GraphEdge(GraphNode source, GraphNode target) {
this.source = source;
this.target = target;
this.setFill(Color.BLACK);
this.startXProperty().bind(Bindings.createDoubleBinding(() -> {
slope = (target.getCenterY() - source.getCenterY())/(target.getCenterX() - source.getCenterX());
return source.getCenterX() + Math.cos(Math.atan(slope)) * source.getRadius();
}, source.boundsInParentProperty()));
this.startYProperty().bind(Bindings.createDoubleBinding(() -> {
slope = (target.getCenterY() - source.getCenterY())/(target.getCenterX() - source.getCenterX());
return source.getCenterY() + Math.sin(Math.atan(slope)) * source.getRadius();
}, source.boundsInParentProperty()));
this.endXProperty().bind(Bindings.createDoubleBinding(() -> {
Bounds b = target.getBoundsInParent();
return b.getMinX() + b.getWidth() / 2;
}, target.boundsInParentProperty()));
this.endYProperty().bind(Bindings.createDoubleBinding(() -> {
Bounds b = target.getBoundsInParent();
return b.getMinY() + b.getHeight() / 2;
}, target.boundsInParentProperty()));
}
回答
createDoubleBinding接受依赖项列表。您应该列出每个行属性所依赖的所有属性。
this.startXProperty().bind(Bindings.createDoubleBinding(
() -> {
double slope = (target.getCenterY() - source.getCenterY())/(target.getCenterX() - source.getCenterX());
return source.getCenterX() + Math.cos(Math.atan(slope)) * source.getRadius();
},
source.centerXProperty(),
source.centerYProperty(),
target.centerXProperty(),
target.centerYProperty(),
source.radiusProperty(),
));
对其他三个线属性重复此操作。