Ibi
Ibi

Reputation: 31

TreeCell Line Bindings messing up at scroll

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

Answers (0)

Related Questions