-1

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!

Omer Hen
  • 172
  • 1
  • 12
  • 4
    what exact line is throwing the NullPointerException? Include the stacktrace. Does the file exist in the same package as the class in which ``switchScenes`` is defined? – f1sh Oct 10 '17 at 12:38
  • The exact line: Scene scene = loginButton.getScene(); in the switchScene method. Yes, all of the files in my program exist in the same packet. And the stacktrace: Caused by: java.lang.NullPointerException at sample.Main.switchScenes(Main.java:35) at sample.Controller.verifyLogin(Controller.java:35) thanks @f1sh – Omer Hen Oct 10 '17 at 12:47
  • Thus `loginButton` is null. See https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it – M. le Rutte Oct 10 '17 at 12:56
  • I've already acknowledged that loginButton is null, the think is that I did define it in the FXML code, fx:id="loginButton". That's why I still don't understand why it doesn't work. I also tried doing: Button loginButton = new Button(); to actuall initialize it, but it still doesn't work. @M.leRutte – Omer Hen Oct 10 '17 at 13:00
  • 1
    but in your code i can see ``@FXML Button login``, which is a different name... – f1sh Oct 10 '17 at 13:05
  • Oh yeah, I guess I copied the code wrong, sorry about that. In my program its loginButton, not just login. @f1sh – Omer Hen Oct 10 '17 at 13:11
  • 1
    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 Oct 10 '17 at 13:54
  • Yup that was it, thank you so much! What I did was moving the switchScene method into the controller file, and then it worked. @James_D – Omer Hen Oct 10 '17 at 13:59

2 Answers2

0

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.

Omer Hen
  • 172
  • 1
  • 12
0

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.