Cannot use root.getchildren(), only root.getchildrenunmodifiable()

Nicolas :

Context

I'm creating a GUI for a small game. The game has a start screen. When the player clicks on start, the scene of the stage changes from the menu scene to the game scene. The new game scene has as a parent the Group and contains some elements like the player's score and name, all of which have been defined in an FXML file. So far the program works.

Problem

My goal now is to create a grid which will be the base of my game. This grid should appear when on the game scene when the player starts the game from the menu. Later on I would like to be able to change the size of the board based on user input

What I tried

1. Creating the grid in the eventhandler

My reasoning is to create the grid as the player clicks the "Singleplayer" button that launches the game. Following that reasoning I would simply get the children of the root node (a group) and add the gridpane to it

Why I am stuck

The following code snippet displays the controller that handles the on button click event. Commented away, I created a button, got the root node and use the standard getChildren().add(...) method. However this fails. Intellij actually proposes to use getChildrenUnmodifiable() instead. From my understanding, getChildrenUnmodifiable() is read only, which does not serve my purpose. I read that the issue is that the parent is protected and cannot be modified. Then where should I go to modify it?

@FXML
public void onButtonChangeScene(ActionEvent event) throws IOException {
    // Go to single player window
    if (event.getSource().equals(singleplayer)){
        Parent root = FXMLLoader.load(getClass().getResource("Views/board.fxml"));
        Scene rootscene = new Scene(root);

        //Get stage information
        Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();
        window.setScene(rootscene);


        // Creates the board
        Button button1 = new Button("Button 1");
        //Part that fails
        root.getchildren().add(button1);

        window.show();

The fxml file looks like this

Group xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.BoardController">
   <children>
      <BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0">
         <left>
            <AnchorPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
               <children>
                  <Label alignment="CENTER" contentDisplay="CENTER" layoutY="6.0" prefHeight="17.0" prefWidth="200.0" text="Player 1">
                     <font>
                        <Font size="30.0" />
                     </font>
                  </Label>
                  <Label alignment="CENTER" contentDisplay="CENTER" layoutY="51.0" prefHeight="17.0" prefWidth="200.0" text="1200">
                     <font>
                        <Font size="30.0" />
                     </font>
                  </Label>
                  <Button fx:id="abandon" layoutX="71.0" layoutY="342.0" mnemonicParsing="false" onAction="#onButtonChangeScene" text="Abandon" />
               </children>
            </AnchorPane>
         </left>
         <right>
            <AnchorPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
               <children>
                  <Label alignment="CENTER" contentDisplay="CENTER" layoutY="7.0" prefHeight="17.0" prefWidth="200.0" text="Player 2">
                     <font>
                        <Font size="30.0" />
                     </font>
                  </Label>
                  <Label alignment="CENTER" contentDisplay="CENTER" layoutY="52.0" prefHeight="17.0" prefWidth="200.0" text="800">
                     <font>
                        <Font size="30.0" />
                     </font>
                  </Label>
               </children>
            </AnchorPane>
         </right>
         <center>
            <GridPane fx:id="gridpane" BorderPane.alignment="CENTER">
              <columnConstraints>
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
              </columnConstraints>
              <rowConstraints>
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
              </rowConstraints>
               <children>
                  <ImageView fitHeight="118.0" fitWidth="99.0" pickOnBounds="true" preserveRatio="true">
                     <image>
                        <Image url="@../Images/bluecard.png" />
                     </image>
                  </ImageView>
                  <ImageView fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" GridPane.rowIndex="1" />
                  <ImageView fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="1" GridPane.rowIndex="1" />
                  <ImageView fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" GridPane.rowIndex="2" />
                  <ImageView fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="1" GridPane.rowIndex="2" />
               </children>
            </GridPane>
         </center>
      </BorderPane>
   </children>
</Group>

2. Creating the grid statically in fxml

I tried to just create the gridpane in FXML using scenebuilder. However I am unsure how to interact with the fxml using code to modify the size or content of the gridpane.

Questions

1 What is the best way to add the GridPane to the parent node

a) Create it in the event handler.

b) Create it in the FXML file statically, and modify the size of the board

2 How do I solve the issue of the root.getChildren() to be able to add the node?

g kexxt :

you need to use .add() with Pane and your root is not a Pane.

try

private BorderPane mainpane = (BorderPane)root.getchildren();
mainpane.add(gridpane);

or

set a fx:id to a Pane you want to add the gridPane like:

<BorderPane fx:id = "mainpane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0">

then you can do like :

private BorderPane mainpane;
private GridPane gridpane;
mainpane.add(gridpane);

and

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=359395&siteId=1