Search code examples
javafxscenestagefxmlloader

JavaFX opening new screens everytime


I am trying to create a basic login application where after entering the credentials the user must be taken to a new Screen.

But when I run my application and enter the credentials it goes to a new screen, but I can see that this is a new window and the old window is still open in the background.

Below is my code:

package com.gsx.controller;

import java.io.IOException; 
import java.util.logging.Logger;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import application.Main;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class LoginController {

private Scene scene;

@FXML
private TextField databaseUserName;

@FXML
private TextField databasePassword;

@FXML
private AnchorPane mainPageAnchorPane;

private static SessionFactory sessionFactory = null;


//Controller method to handle the click of the Database Login button
//This method needs to try and setup a database connection based on the credentials provided
//and advance to the next stage if it is successfull in establishing the connection
//If the credentials entered are incorrect an error message must be displayed and the 
//control must remain in the same page.
@FXML
public void handleLoginButtonClick(ActionEvent actionEvent){



    Session session = null;

    try{

    Configuration configuration = new Configuration();
    //configuration.configure("applicationConfig.xml");
    configuration.configure("applicationConfig.xml");
    configuration.setProperty("hibernate.connection.username",databaseUserName.getText());
    configuration.setProperty("hibernate.connection.password",databasePassword.getText());
    System.out.println("Configuration was successful");
    System.out.println(configuration.getProperty("connection.username"));
    System.out.println(configuration.getProperty("hibernate.connection.password"));
    //Create the session factory
    sessionFactory = configuration.buildSessionFactory();

    //Get the session object
    session = sessionFactory.getCurrentSession();



        //Begin the transaction
        Transaction transaction = session.beginTransaction();

        System.out.println("Connection successful");
        //some problem here debug this tomorrow

        AnchorPane root = new AnchorPane();
        Scene scene = new Scene(root,650,800);
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/com/gsx/frontend/mainPage.fxml"));
        System.out.println(fxmlLoader);
        scene.setRoot((Parent)fxmlLoader.load());
        Main.stage.setScene(scene);
        Main.stage.show();
    }
    catch(Exception exception){

        exception.printStackTrace();
        Alert alert = new Alert(AlertType.ERROR, "The login information is incorrect",ButtonType.OK);
        alert.setTitle("Invalid Cred!!");
        alert.show();
        if(alert.getResult() == ButtonType.OK){

        }
    }
    finally{
        System.out.println("Finally Block to take care of closing the session and the session Factory");
        if(null!=session){
            System.out.println("Session is not Null. Closing it");
            session.close();
        }

    }



}



//Method to show the Login Screen
public void showLoginScreen(){
    try{
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("login.fxml"));
        scene.setRoot((Parent)fxmlLoader.load());
        }
    catch(IOException exception){
        Logger.getLogger(LoginController.class.getName());
    }
}

public static SessionFactory getSessionFactory() {
    return sessionFactory;
}

}

Can you please help me on what I am doing wrong?


Solution

  • Ok so things you do wrong: In your login controller, you create a complet new instance of Stage class. And when you create new stage, it is shown in new window, so you have two options. Either close old stage when you load new stage, or you should access your primary stage and set a scene.

    To acces stage, you can use following, this will acces your login stage,but same logic can be used in your primary stage:

    databaseUserName.getScene.getWindow
    

    Now you can use this to call .hide() method which will close stage, or you could set new scene on that stage.

    Dont forget you can always cast this

    databaseUserName.getScene.getWindow
    

    To (Stage), if you need to, and also, dont try to acces that from initialize because it will return null.

    Lastly, i suggest you to use some framework, like afterburnerfx, or anyother if you plan making application with lot of scenes.

    Lastly you could make your primaryStage static but i strongly advice against that

    I wrote this from phone, so sorry for any errors. If you need any further assistance ask away.