JavaFX – I switched scenes, but I can't come back

I have a problem with switching scenes in my JavaFX app. I can change scene from my main scene to second scene (adding scene) by clicking addingButton, but when I am already in adding scene and I click goBackButton to switch second scene for main scene program returns error.

This is main scene

package com.company.gui;


import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;

public class GUIMainScene
{
    static VBox layout = new VBox();
    static Label label = new Label();
    static Button addingButton = new Button();
    static Button deletingButton = new Button();
    static Button stuffButton = new Button();


public static Scene setScene()
{
    setLabel();
    setButtons();
    setLayout();
    return new Scene(layout);
}


private static void setLabel()
{
    label.setText("Welcome in our dog shelter!");
    label.setPrefSize(400, 80);
    label.setAlignment(Pos.CENTER);
    label.setFont(new Font("Cambria", 24));
}

private static void setButtons()
{
    setAddingButton();
    setDeletingButton();
    setStuffButton();
}

private static void setLayout()
{
    layout.getChildren().addAll(label, addingButton, deletingButton, stuffButton);
    layout.setAlignment(Pos.CENTER);
    layout.setSpacing(40);
}

private static void setAddingButton()
{
    addingButton.setText("Give us a dog");
    addingButton = setButtonSize(addingButton);
    addingButton.setOnAction(e -> GUIScenesManager.switchScene(GUIAddingScene.setScene()));

}

private static void setDeletingButton()
{
    deletingButton.setText("Get a dog");
    deletingButton = setButtonSize(deletingButton);

}

private static void setStuffButton()
{
    stuffButton.setText("Only for stuff!");
    stuffButton = setButtonSize(stuffButton);
}

private static Button setButtonSize(Button button)
{
    button.setPrefSize(400, 120);
    return button;
}
}

This is GUIScenesManager

package com.company.gui;


import javafx.scene.Scene;
import javafx.stage.Stage;

public class GUIScenesManager
{
    private static Stage stage;

    public static void start(Stage firstStage, Scene firstScene)
    {
        stage = firstStage;
        stage.setScene(firstScene);
        stage.show();
    }

    public static void switchScene(Scene scene)
    {
        stage.setScene(scene);
    }
}

This is my second scene called addingScene

package com.company.gui;


import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;


public class GUIAddingScene
{
    static Label titleLabel = new Label();

    static TextField nameTextField = new TextField();
    static TextField ageTextField = new TextField();
    static TextField healthTextField = new TextField();

    static Button okButton = new Button();
    static Button goBackButton = new Button();

    static HBox topLayout = new HBox();
    static VBox centerLayout = new VBox();
    static HBox bottomLayout = new HBox();
    static BorderPane mainLayout = new BorderPane();

    static String name;
    static int age;
    static String health;
public static Scene setScene()
{
    setLabel();
    setTextFields();
    setButtons();
    setLayout();
    return new Scene(mainLayout);
}


private static void setLabel()
{
    titleLabel.setText("Please describe your dog");
    titleLabel.setPrefSize(400, 80);
    titleLabel.setAlignment(Pos.CENTER);
    titleLabel.setFont(new Font("Cambria", 24));
}


private static void setTextFields()
{
    setNameTextField();
    setAgeTextField();
    setHealthTextField();
}

private static void setNameTextField()
{
    nameTextField.setPromptText("name");
}

private static void setAgeTextField()
{
    ageTextField.setPromptText("age");
}

private static void setHealthTextField()
{
    healthTextField.setPromptText("health status");
}


private static void setButtons()
{
    setOkButton();
    setGoBackButton();
}

private static void setOkButton()
{
    okButton.setText("Ok");
    okButton = setButtonSize(okButton);
}

private static void setGoBackButton()
{
    goBackButton.setText("Return");
    goBackButton = setButtonSize(goBackButton);
    goBackButton.setOnAction(e -> GUIScenesManager.switchScene(GUIMainScene.setScene()));
}

private static Button setButtonSize(Button button)
{
    button.setPrefSize(100, 60);
    return button;
}


private static void setLayout()
{
    setTopLayout();
    setCenterLayout();
    setBottomLayout();
    setMainLayout();
}


private static void setTopLayout()
{
    topLayout.getChildren().add(titleLabel);
    topLayout.setAlignment(Pos.CENTER);
}

private static void setCenterLayout()
{
    centerLayout.getChildren().addAll(nameTextField, ageTextField, healthTextField);
    centerLayout.setAlignment(Pos.CENTER);
}

private static void setBottomLayout()
{
    bottomLayout.getChildren().addAll(okButton, goBackButton);
}

private static void setMainLayout()
{
    mainLayout.setTop(topLayout);
    mainLayout.setCenter(centerLayout);
    mainLayout.setBottom(bottomLayout);
}

}

This error i get

Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Children: duplicate children added: parent = VBox@367eb532[styleClass=root]
    at javafx.scene.Parent$2.onProposedChange(Parent.java:454)
    at com.sun.javafx.collections.VetoableListDecorator.addAll(VetoableListDecorator.java:234)
    at com.sun.javafx.collections.VetoableListDecorator.addAll(VetoableListDecorator.java:103)
    at com.company.gui.GUIMainScene.setLayout(GUIMainScene.java:47)
    at com.company.gui.GUIMainScene.setScene(GUIMainScene.java:25)
    at com.company.gui.GUIAddingScene.lambda$setGoBackButton$0(GUIAddingScene.java:93)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Node.fireEvent(Node.java:8413)
    at javafx.scene.control.Button.fire(Button.java:185)
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:417)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
    at com.sun.glass.ui.View.notifyMouse(View.java:937)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:748)

2
Leave a Reply

avatar
2 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Jason Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Jason
Guest

The exception is clear: duplicate children added

You are trying to add the same nodes every time you call setLayout() which in turn calls getChildren().addAll(yourElems...). It’s called from your setScene() method.

You have the following options:

  • remove and re-add children when you are swapping screens
  • hide and show containers
  • swap scenes
Jason
Guest

I’m new to JavaFX but look at the error:

duplicate children added

On the second click you re-setup your nodes and also you adding the nodes to your parent – again. And that’s the error.

Put your nodes to the parent once (e. g. in a static block):

static {
    setLayout();
}