I'm developing a JavaFX application using FXML and scene builder but I'm stuck with loading a new window using a menu bar option.
I click the menu bar option and using the code, I pass parameters to a window changer method however the error I get back is a java.lang.NullPointerException indicating the parameters I'm attempting to pass to the method are in fact not, leading the values to be null.
The exact error is: Caused by: java.lang.NullPointerException: Cannot invoke "javafx.stage.Stage.setTitle(String)" because "this.stage" is null
I have a window changer controller with this method:
public class WindowChanger
private Stage stage;
private Scene scene;
private Parent parent;
public void changeToNewRecordWindow(ActionEvent newRecordClick, String windowView, String windowTitle) throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource(windowView));
parent = loader.load();
scene = new Scene(parent);
stage.setTitle(windowTitle);
stage = (Stage) parent.getScene().getWindow();
stage.setScene(scene);
stage.show();
}
The main application controller file has this method:
public class MainApplicationController {
WindowChanger sc;
@FXML
protected void newRecord(ActionEvent newRecordClick) throws IOException {
sc = new WindowChanger();
sc.changeToNewRecordWindow(newRecordClick, "/application/NewHealthRecordView.fxml", "Create New Record");
}
}
with this MainAppView.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainApplicationController">
<children>
<AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS">
<children>
<MenuBar prefHeight="27.0" prefWidth="640.0">
<menus>
<Menu mnemonicParsing="false" text="Records">
<items>
<MenuItem mnemonicParsing="false" onAction="#newRecord" text="New" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Exit Program">
<items>
<MenuItem mnemonicParsing="false" onAction="#closeClicked" text="Exit Program" />
</items>
</Menu>
</menus>
</MenuBar>
<Label alignment="CENTER" layoutX="155.0" layoutY="177.0" style=" " text="Main window data to be done" textAlignment="CENTER" textFill="#9f9f9f" wrapText="false">
<font>
<Font size="18.0" />
</font>
</Label>
</children>
</AnchorPane>
</children>
</VBox>
Which I'm then trying to call this FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.NewHealthRecordController">
<children>
<Label layoutX="62.0" layoutY="28.0" prefHeight="19.0" prefWidth="45.0" text="Label 0" />
<Label layoutX="62.0" layoutY="72.0" text="Label 1" />
<Label layoutX="62.0" layoutY="113.0" text="Label 2" />
<Label layoutX="62.0" layoutY="158.0" text="Label 3" />
<Label layoutX="178.0" layoutY="158.0" text="Label 4" />
<Label layoutX="339.0" layoutY="158.0" text="Leabel 5" />
<Label layoutX="62.0" layoutY="194.0" text="Label 6" />
<ComboBox editable="true" layoutX="178.0" layoutY="25.0" prefWidth="150.0" promptText="Choose date..." />
<TextField layoutX="179.0" layoutY="68.0" />
<TextField layoutX="179.0" layoutY="109.0" />
<TextField layoutX="214.0" layoutY="154.0" prefHeight="25.0" prefWidth="79.0" />
<TextField layoutX="376.0" layoutY="154.0" prefHeight="25.0" prefWidth="79.0" />
<TextArea layoutX="102.0" layoutY="194.0" prefHeight="124.0" prefWidth="358.0" />
<Button layoutX="141.0" layoutY="343.0" mnemonicParsing="false" text="Submit" />
<Button layoutX="325.0" layoutY="343.0" mnemonicParsing="false" text="Cancel" />
</children>
</AnchorPane>
It seems similar to this question question however i'm not sure where the 'fx:id' for the AnchorPane should go and then how to call it from the WindowChanger class.
Can anyone provide guidance on where I might be missing passing the values correctly?
EDIT: @James_D below pointed it out but I found that if i used this code:
FXMLLoader loader = new FXMLLoader(getClass().getResource(windowView));
parent = loader.load();
stage = new Stage();
stage.setTitle(windowTitle);
stage.setScene(new Scene(parent));
stage.show();
it worked but I didn't quite know why. Now I see I added
stage = new Stage();