Помещение HBox в BorderPane вызывает исключение в методе запуска JavaFX - PullRequest
1 голос
/ 18 февраля 2020

Я пытаюсь сделать макет, состоящий из списка TreeView и нескольких текстовых полей, кнопок внизу. Я подумал, что использовал бы BorderPane, чтобы удерживать мой макет на месте. Но я получаю Exception in Application start method, и это также говорит мне Children: duplicate children added: parent = BorderPane@71e344e8

У вас, ребята, есть представление о том, что происходит?

 public class Main extends Application {

        Stage window;
        TextField nameInput, quantityInput;
        TreeView<String> tree;

        public static void main(String[] args) {
            launch(args);
        }

        public void start (Stage primaryStage) throws Exception{

            window = primaryStage;
            window.setTitle("GrocerieList");

            // tree view
            TreeItem<String> root, food, drink;

            root = new TreeItem<>();
            root.setExpanded(true);

            // food
            food = makeBranch("Food",root);
            makeBranch("Banana", food);
            makeBranch("Coconut", food);
            makeBranch("Eggs", food);

            // drink
            drink = makeBranch("Drinks",root);
            makeBranch("Water", drink);
            makeBranch("Fanta", drink);
            makeBranch("Beer", drink);

            // tree
            tree = new TreeView<>(root);
            tree.setShowRoot(false);

            // bottom input fields
            nameInput = new TextField();
            nameInput.setPromptText("Productname");
            nameInput.setMinWidth(100);

            quantityInput = new TextField();
            quantityInput.setPromptText("Quantity");
            quantityInput.setMinWidth(100);

            // buttons
            Button addbutton = new Button("Add");

            // Layout
            // HBOX
            HBox hBox = new HBox();
            hBox.setPadding(new Insets(10));
            hBox.setSpacing(10);
            hBox.getChildren().addAll(nameInput, quantityInput, addbutton);

            // BorderPane
            BorderPane borderPane = new BorderPane();
            borderPane.getChildren().addAll(tree, hBox);
            borderPane.setCenter(tree);
            borderPane.setBottom(hBox);

            Scene scene = new Scene(borderPane, 520, 620);
            window.setScene(scene);
            window.show();

        }
        public TreeItem<String> makeBranch(String title, TreeItem<String> parent){
            TreeItem<String> item = new TreeItem<>(title);
            item.setExpanded(true);
            parent.getChildren().add(item);
            return item;
        }

Полная ошибка:

    Exception in Application start method
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.lang.IllegalArgumentException: Children: duplicate children added: parent = BorderPane@71e344e8
    at javafx.graphics/javafx.scene.Parent$3.onProposedChange(Parent.java:560)
    at javafx.base/com.sun.javafx.collections.VetoableListDecorator.add(VetoableListDecorator.java:206)
    at javafx.graphics/javafx.scene.layout.BorderPane$BorderPositionProperty.invalidated(BorderPane.java:692)
    at javafx.base/javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
    at javafx.base/javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147)
    at javafx.graphics/javafx.scene.layout.BorderPane.setCenter(BorderPane.java:268)
    at sample.Main.start(Main.java:70)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
Exception running application sample.Main

1 Ответ

2 голосов
/ 18 февраля 2020

Ваша проблема здесь:

BorderPane borderPane = new BorderPane();
borderPane.getChildren().addAll(tree, hBox);
borderPane.setCenter(tree);
borderPane.setBottom(hBox);

Вызовы setCenter и setBottom добавляют эти узлы в список детей. Поскольку вы вручную добавили два узла в список дочерних элементов, вызовы этих методов приводят к добавлению одного и того же узла к одному и тому же родительскому элементу дважды, что недопустимо. Когда дело доходит до макетов, которые предоставляют специальные свойства для позиционирования, такие как BorderPane, вы хотите избегать непосредственного взаимодействия со списком детей. Измените свой код на:

BorderPane borderPane = new BorderPane();
borderPane.setCenter(tree);
borderPane.setBottom(hBox);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...