Cir*_*irF 4 java javafx properties
我的问题是在使用 JavaFX 实现某种图形可视化时出现的。有 2 个类,称为Vertex和Edge,每条边连接 2 个(可能相同)顶点。每个具有自循环的顶点(具有相同开始和结束顶点的边)都存储 αDoubleProperty作为其自循环的首选角度。该角度是根据该顶点及其所有邻居的位置计算的。但是,由于图是动态构建的,顶点的邻居可能会发生变化,从而导致依赖项的动态列表,因此我必须修改DoubleBinding角度所绑定的依赖项。
然而,created bygetDependencies中的方法只返回一个不可变的副本:DoubleBindingBindings.createDoubleBinding
@Override
public ObservableList<?> getDependencies() {
return ((dependencies == null) || (dependencies.length == 0))?
FXCollections.emptyObservableList()
: (dependencies.length == 1)?
FXCollections.singletonObservableList(dependencies[0])
: new ImmutableObservableList<Observable>(dependencies);
}
Run Code Online (Sandbox Code Playgroud)
尽管该类DoubleBinding有一个bind似乎满足我的需要的方法,但它是受保护的:
protected final void bind(Observable... dependencies) {
if ((dependencies != null) && (dependencies.length > 0)) {
if (observer == null) {
observer = new BindingHelperObserver(this);
}
for (final Observable dep : dependencies) {
dep.addListener(observer);
}
}
}
Run Code Online (Sandbox Code Playgroud)
那么有什么方法可以让我随时修改依赖项而无需定义自己的依赖项DoubleBinding,或者我可以在不触及依赖项的情况下解决我的问题吗?
您可以将您的节点绑定DoubleProperty到ObservableList包含邻居节点的节点。这样,如果向列表添加或从列表中删除任何内容,绑定将失效。这是这个想法的一个非常快速的演示:
import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class BindingDemo {
public static void main(String[] args) {
ObservableList<GraphNode> neighbors = FXCollections.observableArrayList();
IntegerProperty total = new SimpleIntegerProperty();
total.bind(Bindings.createIntegerBinding(
() -> sum(neighbors),
neighbors
));
total.addListener((obs, oldTotal, newTotal) ->
System.out.println("Total = "+newTotal));
for (int i = 1 ; i <= 5 ; i++) {
System.out.println("Adding node with value "+i+":");
neighbors.add(new GraphNode(i));
}
}
private static int sum(ObservableList<GraphNode> nodes) {
int total = 0 ;
for (GraphNode node : nodes) {
total += node.value();
}
return total ;
}
public static record GraphNode(int value){}
}
Run Code Online (Sandbox Code Playgroud)
输出:
Adding node with value 1:
Total = 1
Adding node with value 2:
Total = 3
Adding node with value 3:
Total = 6
Adding node with value 4:
Total = 10
Adding node with value 5:
Total = 15
Run Code Online (Sandbox Code Playgroud)
从技术上讲,这并不能真正避免“无需定义我自己的绑定”的要求,但Bindings.createXXXBinding(...)API使这样做变得非常干净。