Как соединить фигуры линией в javafx

Рейтинг: 1Ответов: 0Опубликовано: 17.04.2023

Пытаюсь визуально изобразить генеалогическое дерево, используя 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);
        }
    }

Столкнулась с двумя проблемами:

  1. я не могу найти координаты прямоугольников по отношению к сцене.
Bounds boundsToScene = mainMember.getRectangle().localToScene(mainMember.getRectangle().getBoundsInLocal());

Выдает нули. Если беру координаты LocalToScreen, моя линия появляется совершенно в некорректном месте.

  1. Вся конструкция при разворачивании экрана центрируется, а линия остается заякоренной относительно размеров окна, соответственно, ее положение меняется относительно соответствующих прямоугольников. Линию добавляю в 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);
    }

Подскажите, пожалуйста, как корректно определить координаты линии и как ее корректно расположить. Может быть я в целом неправильно строю модель, если есть советы, буду очень признательна.

Ответы

Ответов пока нет.