0

So I'm using JavaFx for my application, and what I'm trying to do is: On my first page, I select an object through one of its properties with a ComboBox. I store this property in a variable in my controller, and then I load a new page in which I retrieve my variable, do a SELECT in my database using the property I previously stored, and change the values of some text fields using my retrieved object(within the query).

There is the code of my Controller:

package fr.agglomistral.controller;

import fr.agglomistral.classedao.BusDAO;
import fr.agglomistral.classedao.LigneDAO;
import fr.agglomistral.classedao.ParcoursDAO;
import fr.agglomistral.classedao.StationDAO;
import fr.agglomistral.classemetier.Bus;
import fr.agglomistral.classemetier.Ligne;
import fr.agglomistral.classemetier.Parcours;
import fr.agglomistral.classemetier.Station;
import fr.agglomistral.outils.ConnexionMysql;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import javafx.stage.Window;

import javax.xml.transform.Result;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class GestionnaireController {
    @FXML
    private Stage stage;
    @FXML
    private Scene scene;
    @FXML
    private Parent root;
    @FXML
    public Button logout;
    @FXML
    public Button back;

    //Bus related parameters
    @FXML
    public Button manageBus;
    @FXML
    private Button createBus;
    @FXML
    private TextField marqueField;
    @FXML
    private TextField immatriculationField;
    @FXML
    private TextField placesAssisesField;
    @FXML
    private TextField placesDeboutField;
    @FXML
    public ComboBox<String> selectImmatBus;
    @FXML
    public Button deleteBus;
    private Boolean busIsAdded = false;
    @FXML
    public Button updateBus;
    @FXML
    public TextField marqueUpdateField;
    @FXML
    public TextField immatriculationUpdateField;
    @FXML
    public TextField placesAssisesUpdateField;
    @FXML
    public TextField placesDeboutUpdateField;
    @FXML
    private String selectImmatBusValue;


public void openGestionBus(ActionEvent actionEvent) {
        try {
            root = FXMLLoader.load(getClass().getResource("/fr/agglomistral/vues/gestionnaire/bus/GestionBus.fxml"));
            stage =(Stage)((Node)actionEvent.getSource()).getScene().getWindow();
            scene = new Scene(root,1200,700);
            Image favicon = new Image(getClass().getResourceAsStream("/fr/agglomistral/vues/LogoFini.png"));
            stage.getIcons().add(favicon);
            stage.setTitle("AggloMistral-Gestion des Bus");
            stage.setScene(scene);
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public void openUpdateBus(ActionEvent actionEvent) {
        try {
            root = FXMLLoader.load(getClass().getResource("/fr/agglomistral/vues/gestionnaire/bus/UpdateBus.fxml"));
            stage =(Stage)((Node)actionEvent.getSource()).getScene().getWindow();
            scene = new Scene(root,1200,700);
            Image favicon = new Image(getClass().getResourceAsStream("/fr/agglomistral/vues/LogoFini.png"));
            stage.getIcons().add(favicon);
            stage.setTitle("AggloMistral-Mettre à Jour un Bus");
            stage.setScene(scene);
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


public void openBusUpdateForm(ActionEvent actionEvent) {
        try {
            selectImmatBusValue = selectImmatBus.getValue();
            root = FXMLLoader.load(getClass().getResource("/fr/agglomistral/vues/gestionnaire/bus/BusUpdateForm.fxml"));
            stage =(Stage)((Node)actionEvent.getSource()).getScene().getWindow();
            scene = new Scene(root,1200,700);
            Image favicon = new Image(getClass().getResourceAsStream("/fr/agglomistral/vues/LogoFini.png"));
            stage.getIcons().add(favicon);
            stage.setTitle("AggloMistral-Mettre à Jour un Bus");
            stage.setScene(scene);
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

public void addBusToList() throws SQLException {
        if (!busIsAdded) {
            BusDAO busDAO = new BusDAO();
            ResultSet listeBus = busDAO.index();
            while (listeBus.next()){
                String immat = listeBus.getString("IMMATRICULATION");
                selectImmatBus.getItems().add(immat);
            }
            busIsAdded = true;
        }
    }

    public void fillBusPlaceholders (Bus bus) {
        marqueUpdateField.setText(bus.getMarque());
        immatriculationUpdateField.setText(bus.getImmatriculation());
        placesAssisesUpdateField.setText(String.valueOf(bus.getNbplacesassises()));
        placesDeboutUpdateField.setText(String.valueOf(bus.getNbplacesdebout()));
    }


    public void aaaa(MouseEvent mouseEvent) {
        BusDAO busDAO = new BusDAO();
        fillBusPlaceholders(busDAO.findByImmat(selectImmatBusValue));
    }

My first page fxml file:

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.Polyline?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="700.0" prefWidth="1200.0" style="-fx-background-color: white;" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fr.agglomistral.controller.GestionnaireController">
   <children>
      <VBox prefHeight="700.0" prefWidth="1200.0" style="-fx-background-color: a1e3e3;">
         <children>
            <ImageView fitHeight="135.0" fitWidth="172.0">
               <image>
                  <Image url="@../../LogoFini.png" />
               </image>
               <VBox.margin>
                  <Insets left="515.0" />
               </VBox.margin>
            </ImageView>
            <Button fx:id="back" cache="true" mnemonicParsing="false" onAction="#openGestionBus" prefHeight="0.0" prefWidth="203.0" style="-fx-background-color: a1e3e3; -fx-border-color: #014d6d; -fx-border-radius: 50;" text="Retour" textFill="#014d6d">
               <font>
                  <Font name="System Bold" size="18.0" />
               </font>
               <opaqueInsets>
                  <Insets />
               </opaqueInsets>
               <graphic>
                  <Polyline fill="#014d6d" points="-34.5, 29.0, -19.5, 19.5, -20.5, 41.0, -33.5, 29.0" stroke="#014d6d" strokeType="INSIDE" />
               </graphic>
               <VBox.margin>
                  <Insets left="34.0" top="-100.0" />
               </VBox.margin>
            </Button>
         </children>
      </VBox>
      <GridPane hgap="10" layoutX="10.0" layoutY="128.0" prefHeight="276.0" prefWidth="837.0" vgap="10">
         <padding>
            <Insets bottom="40.0" left="350.0" right="40.0" top="46.0" />
         </padding>
         <columnConstraints>
            <ColumnConstraints halignment="RIGHT" maxWidth="Infinity" minWidth="237.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="ALWAYS" maxWidth="218.0" minWidth="181.0" prefWidth="200.0" />
         </columnConstraints>
         <rowConstraints>
            <RowConstraints />
            <RowConstraints minHeight="10.0" prefHeight="30.0" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" />
            <RowConstraints />
            <RowConstraints />
         </rowConstraints>
         <children>
            <Label text="Mettre un Bus à Jour" textFill="#014d6d" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.rowIndex="0" GridPane.rowSpan="1">
               <font>
                  <Font name="Arial Bold" size="24.0" />
               </font>
               <GridPane.margin>
                  <Insets bottom="20" left="0" right="0" top="20" />
               </GridPane.margin>
            </Label>
            <ComboBox fx:id="selectImmatBus" editable="true" onAction="#addBusToList" onShowing="#addBusToList" prefHeight="25.0" prefWidth="171.0" promptText="Immatriculation du Bus" visibleRowCount="100" GridPane.columnIndex="1" GridPane.rowIndex="1" />
            <Label text="Sélectionnez un Bus à éditer :" GridPane.rowIndex="1">
               <font>
                  <Font size="15.0" />
               </font>
            </Label>
         </children>
      </GridPane>
      <Button fx:id="updateBus" defaultButton="true" layoutX="10.0" layoutY="10.0" onAction="#openBusUpdateForm" prefHeight="40.0" prefWidth="223.0" text="Mettre le Bus à Jour" AnchorPane.leftAnchor="490.0" AnchorPane.topAnchor="336.0">
         <font>
            <Font size="18.0" />
         </font>
      </Button>
   </children>
</AnchorPane>

And the page I'm opening by clicking on the first page button:

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.Polyline?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="700.0" prefWidth="1200.0" style="-fx-background-color: white;" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fr.agglomistral.controller.GestionnaireController">
   <children>
      <VBox onMouseClicked="#aaaa" prefHeight="700.0" prefWidth="1200.0" style="-fx-background-color: a1e3e3;">
         <children>
            <ImageView fitHeight="135.0" fitWidth="172.0">
               <image>
                  <Image url="@../../LogoFini.png" />
               </image>
               <VBox.margin>
                  <Insets left="515.0" />
               </VBox.margin>
            </ImageView>
            <Button fx:id="back" cache="true" mnemonicParsing="false" onAction="#openGestionBus" prefHeight="0.0" prefWidth="203.0" style="-fx-background-color: a1e3e3; -fx-border-color: #014d6d; -fx-border-radius: 50;" text="Retour" textFill="#014d6d">
               <font>
                  <Font name="System Bold" size="18.0" />
               </font>
               <opaqueInsets>
                  <Insets />
               </opaqueInsets>
               <graphic>
                  <Polyline fill="#014d6d" points="-34.5, 29.0, -19.5, 19.5, -20.5, 41.0, -33.5, 29.0" stroke="#014d6d" strokeType="INSIDE" />
               </graphic>
               <VBox.margin>
                  <Insets left="34.0" top="-100.0" />
               </VBox.margin>
            </Button>
            <GridPane alignment="center" hgap="10" vgap="10">
               <padding>
                  <Insets bottom="40" left="40" right="40" top="40" />
               </padding>
               <columnConstraints>
                  <ColumnConstraints halignment="RIGHT" maxWidth="Infinity" minWidth="237.0" prefWidth="100" />
                  <ColumnConstraints hgrow="ALWAYS" maxWidth="218.0" minWidth="181.0" prefWidth="200" />
               </columnConstraints>
               <rowConstraints>
                  <RowConstraints />
                  <RowConstraints />
                  <RowConstraints />
                  <RowConstraints />
                  <RowConstraints />
                  <RowConstraints />
                  <RowConstraints />
                  <RowConstraints />
               </rowConstraints>
               <children>
                  <Label prefHeight="32.0" prefWidth="229.0" text="Mettre à jour le Bus" textAlignment="CENTER" textFill="#014d6d" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.rowIndex="0" GridPane.rowSpan="1">
                     <font>
                        <Font name="Arial Bold" size="24.0" />
                     </font>
                     <GridPane.margin>
                        <Insets bottom="20" left="0" right="0" top="20" />
                     </GridPane.margin>
                  </Label>
                  <Label text="Marque :" GridPane.columnIndex="0" GridPane.rowIndex="2">
                     <font>
                        <Font size="18.0" />
                     </font>
                  </Label>
                  <Label text="Immatriculation :" GridPane.columnIndex="0" GridPane.rowIndex="3">
                     <font>
                        <Font size="18.0" />
                     </font>
                  </Label>
                  <Button fx:id="updateBus" defaultButton="true" onAction="#updateBus" prefHeight="46.0" prefWidth="196.0" text="Mettre le Bus à Jour" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.rowIndex="6" GridPane.rowSpan="1">
                     <GridPane.margin>
                        <Insets bottom="20" left="0" right="0" top="20" />
                     </GridPane.margin>
                     <font>
                        <Font size="18.0" />
                     </font>
                  </Button>
                  <Label text="Nombre de places assises :" GridPane.rowIndex="4">
                     <font>
                        <Font size="18.0" />
                     </font>
                  </Label>
                  <Label text="Nombre de places debouts :" GridPane.rowIndex="5">
                     <font>
                        <Font size="18.0" />
                     </font>
                  </Label>
                  <TextField fx:id="marqueUpdateField" GridPane.columnIndex="1" GridPane.rowIndex="2" />
                  <TextField fx:id="immatriculationUpdateField" GridPane.columnIndex="1" GridPane.rowIndex="3" />
                  <TextField fx:id="placesAssisesUpdateField" GridPane.columnIndex="1" GridPane.rowIndex="4" />
                  <TextField fx:id="placesDeboutUpdateField" GridPane.columnIndex="1" GridPane.rowIndex="5" />
               </children>
               <VBox.margin>
                  <Insets top="80.0" />
               </VBox.margin>
            </GridPane>
         </children>
      </VBox>
   </children>
</AnchorPane>

I'm getting the following error when clicking on the 2nd page which triggers my 'aaaa' function:

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException 
    at javafx.fxml@18.0.1/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1857)
    at javafx.fxml@18.0.1/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1724)
    at javafx.base@18.0.1/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base@18.0.1/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base@18.0.1/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base@18.0.1/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base@18.0.1/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base@18.0.1/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics@18.0.1/javafx.scene.Scene$ClickGenerator.postProcess(Scene.java:3586)
    at javafx.graphics@18.0.1/javafx.scene.Scene$MouseHandler.process(Scene.java:3890)
    at javafx.graphics@18.0.1/javafx.scene.Scene.processMouseEvent(Scene.java:1874)
    at javafx.graphics@18.0.1/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2607)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
    at javafx.graphics@18.0.1/com.sun.glass.ui.View.handleMouseEvent(View.java:551)
    at javafx.graphics@18.0.1/com.sun.glass.ui.View.notifyMouse(View.java:937)
    at javafx.graphics@18.0.1/com.sun.glass.ui.win.WinApplication._runLoop(Native
    at javafx.graphics@18.0.1/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.reflect.InvocationTargetException 
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:77)
    at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at javafx.base@18.0.1/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml@18.0.1/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:84)
    at javafx.fxml@18.0.1/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1852)
Caused by: java.lang.NullPointerException: Cannot invoke "fr.agglomistral.classemetier.Bus.getMarque()" because "bus" is null 
    at fr.agglomistral.controller.GestionnaireController.fillBusPlaceholders(GestionnaireController.java:366)
    at fr.agglomistral.controller.GestionnaireController.aaaa(GestionnaireController.java:665)

I tried to use the debug, and this is what I noticed, at first, everything works just fine: so when I select a value in the comboBox, the value is stored in my variable "selectImmatBusValue", but then, when I arrive on my new page and I click to trigger my "aaaa" function, the variable "selectImmatBusValue" is reset to null.... Why? Is it because when I create a new page, all my variables are reset to my default value? and in that case, how could I pass my value from one page to another? Thank you

Slaw
  • 37,820
  • 8
  • 53
  • 80
Lilian Carion
  • 111
  • 1
  • 9
  • 2
    Please don't format stack traces as quote blocks. It makes it harder to read. You should format stack traces as _code_ blocks. If you can't because Stack Overflow says something like, "too much code", then it's better to just not format the stack trace at all and let another user edit your question for you (as opposed to adding `>` to every line, as that messes up the line separators of the original stack trace, which is non-trivial to fix). – Slaw Jun 29 '22 at 12:38
  • 2
    As for your error, the problem is rooted in trying to use the same controller class with multiple FXML files. Don't do this. By default, each time you load an FXML file, a **new** instance of the controller class is created, and only the fields associated with the _one_ FXML file are injected. This makes it difficult to reason about which fields are `null` and when. The relationship between controller classes and FXML files should be _one-to-one_. – Slaw Jun 29 '22 at 12:41
  • I edited my post, the problem is if I use the code block, the exception is written on a single line... So I just deleted the code format @Slaw – Lilian Carion Jun 29 '22 at 12:41
  • 2
    The variables are not “reset to null”. When you load the FXML a new instance of the controller is created, so you have a whole new set of instance variables. Use a different controller class for each fxml file, and pass data between the controllers as shown in the duplicate. – James_D Jun 29 '22 at 12:41
  • Alright, so I should create a new controller in which I put my selectImmatBusValue field ? – Lilian Carion Jun 29 '22 at 12:43
  • this smells like a repost of a deleted question .. is it? If so: don't (too many deletes might lead to the suspension of your account) - instead edit the previous to make it answerable. BTW: when posting a code example that doesn't work, make sure it's a [mcve] .. minding the __M__! - if you did, you wouldn't run into the limit which prevents you from formatting the stacktrace as code ;) – kleopatra Jun 29 '22 at 12:51
  • 1
    "_Alright, so I should create a new controller in which I put my selectImmatBusValue field ?_" – If by "create a new controller" you mean creating a new controller **class**, then yes. Make a separate controller class for each of your FXML files. If you need to communicate between the different views, then check out the duplicate. – Slaw Jun 29 '22 at 12:57

0 Answers0