Javafx“网格已经在场景图中,不能设置为root”错误

问题描述 投票:0回答:1

我正在构建一个计算器,我希望它能够为用户在简单和科学的布局之间切换。它适用于“简单”场景。但是,当我尝试将场景切换为“科学”时,它会给我标题的错误。我正在尝试将BorderPane设置为wrap,然后在Top上放置一个“Settings”按钮,在Center上放置一个GridPane。

我没有设置任何根。我知道它必须默认设置为root用户,但我发布了这个问题因为我不理解错误。我相信它在添加BorderPane的外部包装之前正在工作。你能帮我理解我做错了什么以及如何解决它吗?

这是完整的错误btw:

Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Grid hgap=10.0, vgap=8.0, alignment=TOP_LEFTis already inside a scene-graph and cannot be set as root
    at javafx.scene.Scene$9.invalidated(Scene.java:1100)
    at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:111)
    at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
    at javafx.scene.Scene.setRoot(Scene.java:1072)
    at javafx.scene.Scene.<init>(Scene.java:347)
    at javafx.scene.Scene.<init>(Scene.java:223)
    at Calculator.CreateScientific(Calculator.java:198)
    at Calculator.lambda$1(Calculator.java:51)
    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:8411)
    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:394)
    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$353(GlassViewEventHandler.java:432)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
    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$147(WinApplication.java:177)
    at java.lang.Thread.run(Unknown Source)

这是我的代码:

public class Calculator extends Application {

    Stage window; //Outside wrap
    Scene simpleScene; //Scene for simple calculator
    Scene scientificScene; //Scene for scientific calculator
    Scene settingsScene; //Scene for the format settings
    static String format = "Simple"; //Global variable for the format
    Button[] commonButtons = new Button[24];

    public static void main(String[] args) {

        //Calculator calculator = new Calculator(); //Constructor not working

        launch(args); //Initialize the GUI

    }

    @Override
    public void start(Stage primaryStage) throws Exception { //GUI initialization gets you here. The GUI must have a primaryStage

        window = primaryStage; //Set the Stage named window to be the primaryStage of the program

        //Termination confirmation dialog box
        window.setOnCloseRequest(e -> {
            e.consume();
            termConfirm();
        });

        Button settingsButton = new Button("Settings"); //Create the button Settings
        //settingsButton.getStylesheets().add("file:Styles/ButtonHover.css"); //Doesn't seem to work for now
        settingsButton.setOnAction(e -> { //Lambda expression for pressing the button
            SettingsBox.display("Settings", "Simple or Scienfitic format?"); //Call display() of the class SettingsBox passing the name and label into it. Keep the result in the global variable format
            //Depending on the answer from the button press chose which layout and scene to call
            if(format == "Simple") {
                CreateSimple(commonButtons, settingsButton);
            }
            else if(format == "Scientific") {
                CreateScientific(commonButtons, settingsButton);
            }
            else {
                System.out.println(format); //This appears when I leave the same format and press ok
            }
        });

        Button zero = new Button("0");
        Button one = new Button("1");
        Button two = new Button("2");
        Button three = new Button("3");
        Button four = new Button("4");
        Button five = new Button("5");
        Button six = new Button("6");
        Button seven = new Button("7");
        Button eight = new Button("8");
        Button nine = new Button("9");
        Button equal = new Button("=");
        Button plus = new Button("+");
        Button minus = new Button("-");
        Button mult = new Button("x");
        Button div = new Button("/");
        Button dec = new Button(".");
        Button opp = new Button("Opp");
        Button clear = new Button("C");
        Button del = new Button("Del");
        Button perc = new Button("%");
        Button sqrt = new Button("V");
        Button sqr = new Button("^2");
        Button inv = new Button("Inv");
        Button ce = new Button("CE");

        commonButtons[0] = zero;
        commonButtons[1] = one;
        commonButtons[2] = two;
        commonButtons[3] = three;
        commonButtons[4] = four;
        commonButtons[5] = five;
        commonButtons[6] = six;
        commonButtons[7] = seven;
        commonButtons[8] = eight;
        commonButtons[9] = nine;
        commonButtons[10] = equal;
        commonButtons[11] = plus;
        commonButtons[12] = minus;
        commonButtons[13] = mult;
        commonButtons[14] = div;
        commonButtons[15] = dec;
        commonButtons[16] = opp;
        commonButtons[17] = clear;
        commonButtons[18] = del;
        commonButtons[19] = perc;
        commonButtons[20] = sqrt;
        commonButtons[21] = sqr;
        commonButtons[22] = inv;
        commonButtons[23] = ce;

        //Initial layout and scene
        CreateSimple(commonButtons, settingsButton);
        window.show(); //Show the stage
    }

    private void CreateSimple(Button[] commonButtons, Button settingsButton) {

        BorderPane simplePane = new BorderPane();

        GridPane simpleGrid = new GridPane();

        simpleGrid.setPadding(new Insets(10, 10, 10, 10));
        simpleGrid.setVgap(8);
        simpleGrid.setHgap(10);

        GridPane.setConstraints(commonButtons[0], 1, 7);
        GridPane.setConstraints(commonButtons[1], 0, 6);
        GridPane.setConstraints(commonButtons[2], 1, 6);
        GridPane.setConstraints(commonButtons[3], 2, 6);
        GridPane.setConstraints(commonButtons[4], 0, 5);
        GridPane.setConstraints(commonButtons[5], 1, 5);
        GridPane.setConstraints(commonButtons[6], 2, 5);
        GridPane.setConstraints(commonButtons[7], 0, 4);
        GridPane.setConstraints(commonButtons[8], 1, 4);
        GridPane.setConstraints(commonButtons[9], 2, 4);
        GridPane.setConstraints(commonButtons[10], 3, 7);
        GridPane.setConstraints(commonButtons[11], 3, 6);
        GridPane.setConstraints(commonButtons[12], 3, 5);
        GridPane.setConstraints(commonButtons[13], 3, 4);
        GridPane.setConstraints(commonButtons[14], 3, 3);
        GridPane.setConstraints(commonButtons[15], 2, 7);
        GridPane.setConstraints(commonButtons[16], 0, 7);
        GridPane.setConstraints(commonButtons[17], 1, 3);
        GridPane.setConstraints(commonButtons[18], 2, 3);
        GridPane.setConstraints(commonButtons[19], 0, 2);
        GridPane.setConstraints(commonButtons[20], 1, 2);
        GridPane.setConstraints(commonButtons[21], 2, 2);
        GridPane.setConstraints(commonButtons[22], 3, 2);
        GridPane.setConstraints(commonButtons[23], 0, 3);


        simpleGrid.getChildren().addAll(commonButtons);

        simplePane.setTop(settingsButton);
        simplePane.setCenter(simpleGrid);
        simpleScene = new Scene(simplePane, 300, 300); //Height and width of the scene

        window.setScene(simpleScene); //Pass the created scene to the window stage
        window.setTitle("Simple Calculator"); //Set the stage's title (margin of the window at the top)
    }

    private void CreateScientific(Button[] commonButtons, Button settingsButton) {

        BorderPane scientificPane = new BorderPane();

        GridPane scientificGrid = new GridPane();

        scientificGrid.setPadding(new Insets(10, 10, 10, 10));
        scientificGrid.setVgap(8);
        scientificGrid.setHgap(10);

        GridPane.setConstraints(commonButtons[0], 1, 7);
        GridPane.setConstraints(commonButtons[1], 0, 6);
        GridPane.setConstraints(commonButtons[2], 1, 6);
        GridPane.setConstraints(commonButtons[3], 2, 6);
        GridPane.setConstraints(commonButtons[4], 0, 5);
        GridPane.setConstraints(commonButtons[5], 1, 5);
        GridPane.setConstraints(commonButtons[6], 2, 5);
        GridPane.setConstraints(commonButtons[7], 0, 4);
        GridPane.setConstraints(commonButtons[8], 1, 4);
        GridPane.setConstraints(commonButtons[9], 2, 4);
        GridPane.setConstraints(commonButtons[10], 3, 7);
        GridPane.setConstraints(commonButtons[11], 3, 6);
        GridPane.setConstraints(commonButtons[12], 3, 5);
        GridPane.setConstraints(commonButtons[13], 3, 4);
        GridPane.setConstraints(commonButtons[14], 3, 3);
        GridPane.setConstraints(commonButtons[15], 2, 7);
        GridPane.setConstraints(commonButtons[16], 0, 7);
        GridPane.setConstraints(commonButtons[17], 1, 3);
        GridPane.setConstraints(commonButtons[18], 2, 3);
        GridPane.setConstraints(commonButtons[19], 0, 2);
        GridPane.setConstraints(commonButtons[20], 1, 2);
        GridPane.setConstraints(commonButtons[21], 2, 2);
        GridPane.setConstraints(commonButtons[22], 3, 2);
        GridPane.setConstraints(commonButtons[23], 0, 3);

        scientificGrid.getChildren().addAll(commonButtons);

        scientificPane.setRight(settingsButton);
        scientificPane.setBottom(scientificGrid);
        scientificScene = new Scene(scientificGrid, 600, 600); //Height and width of the scene

        window.setScene(scientificScene); //Pass the created scene to the window stage
        window.setTitle("Scientific Calculator"); //Set the stage's title (margin of the window at the top)
    }

    private void termConfirm() {
        Boolean answer = ConfirmBox.display("Exit", "Are you sure you want to exit the Calculator?");
        if(answer) {
            window.close();
        }
    }
}
public class AlertBox {

    public static void display(String title, String message) {
        Stage window = new Stage();

        window.initModality(Modality.APPLICATION_MODAL);
        window.setTitle(title);;
        window.setMinWidth(250);

        Label label = new Label();

        label.setText(message);
        Button closeButton = new Button("Close");
        closeButton.setOnAction(e -> window.close());
        VBox layout = new VBox(10);
        layout.getChildren().addAll(label, closeButton);
        layout.setAlignment(Pos.CENTER);

        Scene scene = new Scene(layout);
        window.setScene(scene);
        window.showAndWait();
    }

}
public class SettingsBox {

    static String format = Calculator.format;

    public static void display(String title, String message) {
        Stage window = new Stage();

        window.initModality(Modality.APPLICATION_MODAL);
        window.setTitle(title);
        window.setMinWidth(250);

        Label label = new Label("Settings");
        label.setText(message);

        final ToggleGroup formatGroup = new ToggleGroup();

        RadioButton simple = new RadioButton("Simple");
        simple.setToggleGroup(formatGroup);
        simple.setSelected(true);

        RadioButton scientific = new RadioButton("Scientific");
        scientific.setToggleGroup(formatGroup);

        if(Calculator.format == "Simple") {
            formatGroup.selectToggle(simple);
        }
        else if(Calculator.format == "Scientific") {
            formatGroup.selectToggle(scientific);
        }

        Button ok = new Button("OK");

        simple.setOnAction(e -> format = "Simple");

        scientific.setOnAction(e -> format = "Scientific");

        window.setOnCloseRequest(e -> {
            format = Calculator.format;
        });

        ok.setOnAction(e -> {
            window.close();
            Calculator.format = format;
        });

        VBox layout = new VBox(10);
        layout.getChildren().addAll(label, simple, scientific, ok);
        layout.setAlignment(Pos.CENTER);

        Scene scene = new Scene(layout);
        window.setScene(scene);
        window.showAndWait();
    }

}
public class ConfirmBox {

    static Boolean answer = false;

    public static Boolean display(String title, String message) {
        Stage window = new Stage();

        window.initModality(Modality.APPLICATION_MODAL);
        window.setTitle(title);
        window.setMinWidth(250);

        Label label = new Label("Settings");
        label.setText(message);

        Button yes = new Button("Yes");

        Button no = new Button("No");

        yes.setOnAction(e -> {
            answer = true;
            window.close();
        });

        no.setOnAction(e -> {
            answer = false;
            window.close();
        });

        HBox questionLayout = new HBox(10);
        questionLayout.getChildren().add(label);

        HBox answerLayout = new HBox(10);
        answerLayout.getChildren().addAll(yes, no);

        BorderPane borderPane = new BorderPane();
        borderPane.setTop(questionLayout);
        borderPane.setLeft(answerLayout);

        Scene scene = new Scene(borderPane);
        window.setScene(scene);
        window.showAndWait();

        return answer;
    }
}
java javafx grid javafx-8
1个回答
0
投票

你有:

scientificPane.setBottom(scientficGrid);

紧随其后:

scientificScene = new Scene(scientificGrid, 600, 600);

这使得scientificGrid既是scientificPane的孩子又是scientificScene的根源 - 因此错误。你可能打算打电话:

scientificScene = new Scene(scientificPane, 600, 600);
© www.soinside.com 2019 - 2024. All rights reserved.