简体   繁体   中英

Adding dynamic buttons on GridPane FXML JavaFX

I've started a project requested by our instructor building an application in JavaFX.

I used SceneBuilder for FXML Part when I want to add buttons on gridpane, but it didn't work. The connection with the database is okay. On the first part of the application, the user logs in. After that he/she comes on UserWindow, but the buttons aren't displayed.

File Main.java :

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class Main extends Application {
    Stage window;
    Controller c;
    ControllerB cB;

    @Override
    public void start(Stage primaryStage) throws Exception {
        window = primaryStage;

        FXMLLoader f = new FXMLLoader();
        FXMLLoader f2 = new FXMLLoader();
        f.setLocation(Main.class.getResource("sample.fxml"));
        f2.setLocation(Main.class.getResource("UserWindow.fxml"));

        Parent root = f.load();
        Parent root2 = f2.load();
        Scene s = new Scene(root, 500, 340);

        // Controllers
        c = f.getController();
        c.setMain(this);
        c.setScene2(new Scene(root2, 900, 500));

        cB = f2.getController();
        cB.setMain(this);
        cB.setScene(s);

        window.setTitle("Remote Works");
        window.setScene(s);
        window.show();
    }


    public static void main(String[] args) {
        launch(args);
    }


    public void setUserData(Object o) {
        window.setUserData(o);
    }


    public void setScene(Scene scene) {
        window.setScene(scene);
        window.show();
    }

    public void setScene2(Scene scene) {
        window.setScene(scene);
        window.show();
    }
}

File ControllerB.java :

package sample;


import javafx.collections.*;
import javafx.event.ActionEvent;
import javafx.fxml.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.*;


public class ControllerB implements Initializable {

    @FXML
    private GridPane Box;

    @FXML
    private Label nameUser;

    @FXML
    private Label matriculeUser;

    @FXML
    private Label fonctionUser;

    @FXML
    private Button deconnect;

    private Scene scene1;
    private Main main;
    ObservableList<String> ecoles;


    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        try {
            schoolretrieve();
            int size = ecoles.size();
            Node[] n = new Node[size];
            for (int i = 0; i < n.length; i++) {
                FXMLLoader loader = new FXMLLoader(getClass().getResource("Bloc.fxml"));
                ControllerItem controller = new ControllerItem();
                loader.setController(controller);
                n[i] = loader.load();
                controller.setButtonInst(ecoles.get(i)); // Until this part all works
                Box.getChildren().add(n[i]); // But it doesn't add buttons to GridPane
            }
        } catch (IOException | NullPointerException | SQLException e) {
            //System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }


}

File ControllerItem.java :

package sample;

import javafx.fxml.FXML;

import javafx.scene.control.Button;


public class ControllerItem {

    @FXML
    private Button buttonInst;

    public Button getButtonInst() {
        return buttonInst;
    }

    public void setButtonInst(String s) {
        buttonInst.setText(s);
    }

}

File Bloc.fxml :

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>

<Button fx:id="buttonInst" mnemonicParsing="false" prefHeight="132.0" prefWidth="201.0" stylesheets="@../styles.css" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" />

File UserWindow.fxml :

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.shape.*?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="497.0" prefWidth="710.0" styleClass="pane" stylesheets="@../styles.css" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.ControllerB">
   <left>
      <Pane prefHeight="497.0" prefWidth="156.0" BorderPane.alignment="CENTER">
         <children>
            <ImageView fitHeight="150.0" fitWidth="151.0" layoutX="11.0" pickOnBounds="true" preserveRatio="true" />
            <Circle fill="#e1ebf5" layoutX="78.0" layoutY="88.0" opacity="0.18" radius="74.0" stroke="BLACK" strokeType="INSIDE" />
            <Label fx:id="nameUser" layoutX="10.0" layoutY="196.0" prefHeight="50.0" prefWidth="136.0" text="Nom Utilisateur :" />
            <Label fx:id="fonctionUser" layoutX="11.0" layoutY="259.0" prefHeight="37.0" prefWidth="136.0" text="Statut : " />
            <Label fx:id="matriculeUser" layoutX="10.0" layoutY="306.0" prefHeight="37.0" prefWidth="136.0" text="Identifiant : " />
            <Button fx:id="deconnect" layoutX="20.0" layoutY="364.0" mnemonicParsing="false" onAction="#onAction" prefHeight="27.0" prefWidth="117.0" text="deconnexion" />
         </children>
      </Pane>
   </left>
   <center>
       <Pane opacity="0.0" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: #f7cc3d;"
             BorderPane.alignment="CENTER">
           <GridPane fx:id="Box" alignment="TOP_CENTER" hgap="3.0" layoutX="70.0" layoutY="96.0"
                     nodeOrientation="LEFT_TO_RIGHT" opacity="0.95" prefHeight="305.0" prefWidth="415.0"
                     styleClass="gridpane" stylesheets="@../ss.css" vgap="3.0"/>

       </Pane>
   </center>
</BorderPane>

So you have file UserWindow.fxml and you have declared a GridPane in it. I suggest you to don't make a separate .fxml file for the button.

Just do it like this in your ControllerB:

@Override
public void initialize(URL url, ResourceBundle resourceBundle) {

    schoolretrieve();
    int size = ecoles.size();
    //Node[] n = new Node[size];
    for (int i = 0; i < size; i++) {
        //FXMLLoader loader = new FXMLLoader(getClass().getResource("Bloc.fxml"));
        //ControllerItem controller = new ControllerItem();
        //loader.setController(controller);
        //n[i] = loader.load();
        //controller.setButtonInst(ecoles.get(i));
        //Box.getChildren().add(n[i]);

        Button btn = new Button(ecoles.get(i));
        Box.add(btn, 0, i); // Button is added to next row every time.
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM