0

i'm trying to redirect a user after he connect to the database.

This is my controller with the login method :

package packages.home;

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.TextField;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import static javax.swing.JOptionPane.showMessageDialog;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;


public class Controller extends Thread {

    @FXML
    private Button btnClose;

    @FXML
    private TextField txtUsername;

    @FXML
    private TextField txtPassword;

    @FXML
    private Label lblErrors;

    @FXML
    private Button btnConnect;

    /// --
    Connection laConnection = GestionConnection.getLaConnection();
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;


    public void handleButtonAction(MouseEvent event) throws IOException{

        if (event.getSource() == btnClose) {
            System.exit(0);
            System.out.println("Fermeture de l'application.");
        }

        if (event.getSource() == btnConnect) {

            //login here
            if (logIn().equals("Success")) {
                try {

                    //add you loading or delays - ;-)
                    Node node = (Node) event.getSource();
                    Stage stage = (Stage) node.getScene().getWindow();

                    //stage.setMaximized(true);
                    stage.close();
                    Scene scene = new Scene(FXMLLoader.load(getClass().getResource("Login.fxml")));
                    stage.setScene(scene);
                    stage.show();

                } catch (IOException ex) {
                    System.err.println(ex.getMessage());
                }

            }
        }

    }


    private String logIn() {

        String status = "Success";
        String username = txtUsername.getText();
        String password = txtPassword.getText();

        if(username.isEmpty() || password.isEmpty()) {

            setLblErrors(Color.RED, "Champs vides.");
            status = "Error";

        } else {

            //query
            String sql = "SELECT * FROM admins Where username = ? and password = ?";

            try {

                // On test la requête
                System.out.println("Hello");
                preparedStatement = laConnection.prepareStatement(sql);
                preparedStatement.setString(1, username);
                preparedStatement.setString(2, password);
                resultSet = preparedStatement.executeQuery();

                if (!resultSet.next()) {
                    setLblErrors(Color.TOMATO, "Nom d'utilisateur ou mot de passe incorrect");
                    status = "Error";

                } else {
                    setLblErrors(Color.GREEN, "Authentification réussite, redirection en cours ...");
                    showMessageDialog(null, "Vous êtes bien connecté");
                }




            } catch (SQLException ex) {

                System.err.println(ex.getMessage());
                status = "Exception";
            }
        }
        return status;

    }


    private void setLblErrors(Color color, String text) {
        lblErrors.setTextFill(color);
        lblErrors.setText(text);
        System.out.println(text);
    }

}

This is my new fxml controller :

package packages.home;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.layout.AnchorPane;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

public class DashboardController implements Initializable {

    @FXML
    private AnchorPane rootPane;

    public DashboardController(AnchorPane rootPane) {
        this.rootPane = rootPane;
    }


    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {

    }

    @FXML
    private void loadSecond(ActionEvent event) throws IOException{
        AnchorPane pane = FXMLLoader.load(getClass().getResource("dashboard.fxml"));
        rootPane.getChildren().setAll(pane);
    }
}

I do know how to make the link between my first controller and my new controller.

I'm new to javaFX and i wil be happy to learn new things about it.

Thanks in advance for your help.

  • You could get a reference to the `scene` (make it static) created at the start method of your application. Then set the root the new page. `Main.scene.setRoot(FXMLLoader.load(...))` add this at the end of the completed action. You could make it into its own function for later use. – Dr. Confused Mar 30 '20 at 07:21
  • no, don't make anything static - that's the very worst option you could choose. Instead, read the duplicate and apply to your context. When stuck, come back with a [mcve] demonstrating what's not working as expected – kleopatra Mar 30 '20 at 13:40

1 Answers1

0

Static Way

For example:

 public class Main {
    public static void main(String[] args) { ... }

    public static Scene scene;

    @Override 
    public void start (Stage stage) {
        ...
        scene = new Scene(FXMLoader.load(...)); //Controller fxml
        stage.setScene(scene);
        ...
    }

    public static void setRoot(AnchorPane pane, Parent parent) {
        pane.getChildren().clear();
        scene.setRoot(parent);
    }
}

In Controller.java create an @FXML reference to the AnchorPane being used and pass it in the function.

if (connected) {
    Main.setRoot(pane, FXMLoader.load(...)); //new screen fxml
}

EDIT: Getting reference

public void setRoot(AnchorPane pane, Parent parent) {
    pane.getChildren().clear();
    pane.getScene().setRoot(parent);
}

Don't call getScene() in the initialize method of a controller for the scene will be null.

if (connected) {
    setRoot(pane, FXMLoader.load(...)); //new screen fxml
}
Dr. Confused
  • 76
  • 1
  • 6
  • possible - but application global state (all the public static xx) is the worst of all options .. – kleopatra Mar 30 '20 at 10:50
  • @kleopatra I updated the answer the same logic will apply. I didn't know if you cared if it was static :] hope it helps! `FXMLLoader.load(...)` is a static method, so I would change that as well. – Dr. Confused Mar 30 '20 at 11:31
  • it's still very suboptimal ... have a look at the other options of the duplicate :) – kleopatra Mar 30 '20 at 11:39
  • just in case you are wondering: the reason you don't get a downvote is that the question is very suboptimal (not providing a [mcve]) as well ;) – kleopatra Mar 30 '20 at 11:41