Как соединить фигуры линией в javafx
Пытаюсь визуально изобразить генеалогическое дерево, используя JavaFX. Само оригинальное окно - это BorderPane, который обернут в ScrollPane, который обернут в Vbox, который обернут в Hbox.
<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ui.ViewController">
<children>
<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" HBox.hgrow="ALWAYS">
<children>
<ScrollPane fitToHeight="true" fitToWidth="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="800.0" VBox.vgrow="ALWAYS">
<content>
<BorderPane fx:id="root" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity">
<bottom>
<ImageView fitHeight="75.0" fitWidth="100.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="BOTTOM_RIGHT">
<image>
<Image url="@tree.png" />
</image>
<BorderPane.margin>
<Insets bottom="20.0" right="20.0" />
</BorderPane.margin>
</ImageView>
</bottom></BorderPane>
</content>
</ScrollPane>
</children>
</VBox>
</children>
</HBox>
Каждая ячейка члена семьи - это StackPane, внутри которого лежит Rectangle с текстом.
При построении дерева создается новый HBox для родителей, внутрь каждого кладется VBox. И вот туда уже добавляется конструкция со StackPane.
private void addMother(M member, VBox motherVBox) {
M mother = member.getMother();
HBox parentsHBox = new HBox(20);
parentsHBox.setAlignment(Pos.CENTER);
motherVBox.getChildren().add(parentsHBox);
if (mother.getMother() != null) {
VBox grandMotherVBox = new VBox(40);
grandMotherVBox.setAlignment(Pos.BOTTOM_CENTER);
addMother(mother, grandMotherVBox);
grandMotherVBox.getChildren().add(new MemberBox<>(mother.getMother()).getPane());
if (mother.getFather() == null) {
emptyBox(member, parentsHBox);
}
parentsHBox.getChildren().add(grandMotherVBox);
}
if (mother.getFather() != null) {
VBox grandFatherVBox = new VBox(40);
grandFatherVBox.setAlignment(Pos.BOTTOM_CENTER);
addFather(mother, grandFatherVBox);
grandFatherVBox.getChildren().add(new MemberBox<>(mother.getFather()).getPane());
if (mother.getMother() == null) {
emptyBox(member, parentsHBox);
}
parentsHBox.getChildren().add(grandFatherVBox);
}
}
Столкнулась с двумя проблемами:
- я не могу найти координаты прямоугольников по отношению к сцене.
Bounds boundsToScene = mainMember.getRectangle().localToScene(mainMember.getRectangle().getBoundsInLocal());
Выдает нули. Если беру координаты LocalToScreen, моя линия появляется совершенно в некорректном месте.
- Вся конструкция при разворачивании экрана центрируется, а линия остается заякоренной относительно размеров окна, соответственно, ее положение меняется относительно соответствующих прямоугольников. Линию добавляю в BorderPane. Возможно, в этом проблема?
public void horizontalConnection(Box<Person> member, BorderPane root) {
Bounds bounds = member.getRectangle().localToScene(member.getRectangle().getBoundsInLocal());
double y = bounds.getMaxY() - (bounds.getMaxY() - bounds.getMinY()) / 2;
double x1 = bounds.getMaxX();
double x2 = x1 + 40;
Line line = new Line(x1, y, x2, y);
line.setStroke(Color.DARKGREY);
root.getChildren().add(line);
}
Подскажите, пожалуйста, как корректно определить координаты линии и как ее корректно расположить. Может быть я в целом неправильно строю модель, если есть советы, буду очень признательна.