简体   繁体   中英

JavaFX NullPointerException with fxml

I am creating a basic login window for a program of mine and I can't seem to switch scenes without the program giving me a "NullPointerException" error. Code:

public class Controller {

@FXML
private javafx.scene.control.TextField usernameTextField, passwordTextField;
@FXML
private Label loginFailed;

public static void main(String[] args) {

}

@FXML
private void verifyLogin() throws IOException { // Verifying the both the username, and password exists in the database
    Configure obj = new Configure();
    Main obj1 = new Main();
    String username = usernameTextField.getText();
    String password = passwordTextField.getText();

    try {
        Scanner scanner = new Scanner(obj.file);

        //now read the file line by line...
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            if(line.contains(username) && line.contains(password)) {
                System.out.println("Half Way");
                obj1.switchScenes("userHomescreen.fxml");
                System.out.println("True");
                return;
            }
        }
    } catch(FileNotFoundException e) {
        System.out.println("ERROR! File not found!");
    }
    loginFailed.setText("Wrong Username or Wrong Password!");
}

}

This is the controller class for the first scene. My program is linked to a file, that I'm using the scanner class and checking for password and username.

@FXML Button loginButton
void switchScenes(String sceneName) throws IOException {
    Scene scene = loginButton.getScene();
    Window window = scene.getWindow();
    Stage stage = (Stage) window;

    Parent primaryStage = FXMLLoader.load(getClass().getResource(sceneName));
    Scene primaryScene = new Scene(primaryStage);
    stage.setScene(primaryScene);
    stage.show();

}

That's the method that I'm using to switch scenes, the login button is a button on the first scene, Im using it in order to get the first scene, and from that get the window.

Finally, that's the fxml code:

    <GridPane alignment="center" hgap="10" vgap="10" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <columnConstraints>
      <ColumnConstraints />
   </columnConstraints>
   <rowConstraints>
      <RowConstraints />
   </rowConstraints>
   <children>
      <Pane fx:id="loginPane" prefHeight="540.0" prefWidth="395.0">
         <children>
            <Label layoutX="22.0" layoutY="91.0" text="Username:" />
            <Label layoutX="22.0" layoutY="178.0" text="Password" />
            <TextField fx:id="usernameTextField" layoutX="22.0" layoutY="122.0" prefHeight="25.0" prefWidth="351.0" />
            <TextField fx:id="passwordTextField" layoutX="22.0" layoutY="204.0" prefHeight="25.0" prefWidth="351.0" />
            <Button fx:id="loginButton" layoutX="22.0" layoutY="271.0" mnemonicParsing="false" onAction="#verifyLogin" prefHeight="25.0" prefWidth="130.0" text="Login" />
            <Label fx:id="loginFailed" layoutX="25.0" layoutY="240.0" prefHeight="17.0" prefWidth="351.0" />
         </children></Pane>
   </children>
</GridPane>

So to get back to my question, please help me understand, and fix, the NullPointer error that occurs in the switchScenes method. Thanks a lot!

Like @James_D said, the problem was -

The FXMLLoader initializes @FXML-annotated fields in the controller. You are not calling switchScenes(...) on the controller, you are calling it on some other object you created. Hence loginButton is not initialized and is still null. - James_D

So I simply moved the swtichScene method into the Controller class, and it worked.

try code below :

public void switchScenes(String sceneName){
    try {      
        Stage stage = loginButton.getScene().getWindow();

        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource(sceneName));
        Parent root = loader.load();
        Scene primaryScene = new Scene(root);
        stage.setScene(primaryScene);                   
    } catch (IOException ex) {
        JOptionPane.showMessageDialog(null, "Failed to Open Scene");            
        ex.getCause();
    }
}

Note : string sceneName should be "/PackageName/FXMLfile.fxml"

"/" before PackageName is important.

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