我正在构建一个计算器,我希望它能够为用户在简单和科学的布局之间切换。它适用于“简单”场景。但是,当我尝试将场景切换为“科学”时,会出现标题错误。我试图将BorderPane设置为环绕,然后在顶部放置“设置”按钮,在中央放置GridPane。
我没有将任何内容设置为root。我知道默认情况下必须将其设置为root,但是我发布了此问题,因为我不理解该错误。我相信它在添加BorderPane的外部包装之前是可行的。您能帮助我了解我做错了什么以及如何解决吗?
这是完整的错误,顺便说一句:
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;
}
}
答案 0 :(得分:0)
您有:
scientificPane.setBottom(scientficGrid);
紧随其后的是:
scientificScene = new Scene(scientificGrid, 600, 600);
这使scientificGrid
既是scientificPane
的子代,又是scientificScene
的根,因此出现错误。您可能想打电话给
scientificScene = new Scene(scientificPane, 600, 600);