Reputation: 31
I have two TreeViews in my JavaFX GUI, which I fill dynamically. They can have a lot of data, so most of the time, they will be scrollable. Afterwards, I create connections (or rather edges) between the TreeCells of both TreeViews. I draw a Line from the source cell to the target cell and create Bindings. My code for that is the following:
line.startYProperty().bind(Bindings.createDoubleBinding(() -> {
Bounds b = sourceCell.getBoundsInParent();
return b.getMaxY() + b.getHeight() / 2;
}, sourceCell.boundsInParentProperty()));
line.endYProperty().bind(Bindings.createDoubleBinding(() -> {
Bounds b = targetCell.getBoundsInParent();
return b.getMaxY() + b.getHeight() / 2;
}, targetCell.boundsInParentProperty()));
Now, that does work for me, until I start scrolling one of the TreeViews. When the connected cell is scrolled out of the visible area of the treeview, the line position resets and connects itself to a different cell.
I figured that is because the binding is to a TreeCell and they can dynamically change their value depending on the visible data, but what would be the alternative to make it work?
How would I keep the Line bound to the original TreeCell without it changing when scrolled out and back into the view?
My example code:
@Override
public void start(Stage primaryStage) {
try {
AnchorPane root = new AnchorPane();
Scene scene = new Scene(root, 700, 400);
primaryStage.setScene(scene);
primaryStage.show();
TreeItem sourceRoot = new TreeItem("source");
sourceRoot.setExpanded(true);
TreeItem targetRoot = new TreeItem("target");
targetRoot.setExpanded(true);
TreeView<String> source = new TreeView<String>(sourceRoot);
TreeView<String> target = new TreeView<String>(targetRoot);
target.setLayoutX(400.0);
root.getChildren().add(source);
root.getChildren().add(target)
// fill and randomly select two visible cells
for (int i = 0; i < 100; i++) {
sourceRoot.getChildren().add(new TreeItem("ItemS " + i));
targetRoot.getChildren().add(new TreeItem("ItemT " + i));
}
TreeCell<String> sourceCell = (TreeCell<String>) source.lookupAll(".tree-cell").toArray()[2];
TreeCell<String> targetCell = (TreeCell<String>) target.lookupAll(".tree-cell").toArray()[4];
Line line = new Line();
line.setStartX(source.getWidth());
line.startYProperty().bind(Bindings.createDoubleBinding(() -> {
Bounds b = sourceCell.getBoundsInParent();
return b.getMinY() + b.getHeight() / 2;
}, sourceCell.boundsInParentProperty()));
line.setEndX(target.getLayoutX());
line.endYProperty().bind(Bindings.createDoubleBinding(() -> {
Bounds b = targetCell.getBoundsInParent();
return b.getMinY() + b.getHeight() / 2;
}, targetCell.boundsInParentProperty()));
root.getChildren().add(line);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
Upvotes: 0
Views: 64