JavaFX - 我切换了场景,但我无法回来

时间:2017-05-16 11:39:58

标签: java javafx

我在JavaFX应用中切换场景时遇到问题。我可以通过单击addingButton将场景从我的主场景更改为第二场景(添加场景),但是当我已经添加场景时,我点击goBackButton切换第二个场景,主场景程序返回错误。

这是主要场景

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;
}
}

这是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);
    }
}

这是我的第二个场景,名为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);
}

}

此错误我

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 个答案:

答案 0 :(得分:0)

例外是明确的:duplicate children added

每次拨打setLayout()时,您都会尝试添加相同的节点,getChildren().addAll(yourElems...)会调用setScene()。它是从您的Date方法调用的。

您有以下选择:

  • 在交换屏幕时删除并重新添加子项
  • 隐藏和展示容器
  • swap scenes

答案 1 :(得分:0)

我是JavaFX的新手,但看看错误:

  

重复儿童添加

在第二次单击时,您重新设置节点,并再次将节点添加到父节点。这就是错误。

将您的节点放到父节点上(例如,在静态块中):

static {
    setLayout();
}