3

I'm triying to make a library with login posibility and i need to know what user is logged in in all my scenes.

I'm triyng to send the login details(the response from the database) from LoginController to MainController via SceneController.

In SceneController I'm changing the scenes via a parameter that holds the resource file name and the current stage.

LoginController.java

public class LoginController implements Initializable {
    @FXML
    private Button cancelButton;
    @FXML
    private Button loginButton;
    @FXML
    private Label loginMessageLabel;
    @FXML
    private TextField usernameField;
    @FXML
    private TextField passwordField;

    public void initialize(URL url, ResourceBundle resourceBundle){
    }

    public void loginButtonOnAction(ActionEvent event){
        if(!usernameField.getText().isBlank() && !passwordField.getText().isBlank()){
            validateLogin();
        }else{
            loginMessageLabel.setText("Datele introduse nu sunt corecte!");
        }
    }

    public void cancelButtonOnAction(ActionEvent event){
        Stage stage = (Stage) cancelButton.getScene().getWindow();
        stage.close();
    }

    public void validateLogin(){
        DatabaseConnection connectionNew = new DatabaseConnection();
        Connection connectDB = connectionNew.getConnection();

        String verifyLogin = "SELECT count(1), id, name FROM users WHERE Username= '"+usernameField.getText()+"' AND Password ='"+passwordField.getText()+"'";
        System.out.println(verifyLogin);
        try{

            Statement statement = connectDB.createStatement();
            ResultSet queryResult = statement.executeQuery(verifyLogin);

            while(queryResult.next()){

                if(queryResult.getInt(1) == 1){
                    Stage stage = (Stage) loginButton.getScene().getWindow();
                    SceneController sceneController = new SceneController();
                    sceneController.switchScene(stage, "main-view.fxml");
                }else{
                    loginMessageLabel.setText("Datele introduse nu sunt corecte!");
                }

            }

        }catch (Exception e){
            throw new RuntimeException("unhandled", e);
        }
    }

}

MainController.java

public class MainController implements Initializable {

    private static String paneName;
    private static String userId;
    private static String defaultImagePath = "C:\\Users\\costi\\Desktop\\LibraryImages\\";
    private static String defaultImageName = "default.png";
    public TableView<Book> tableViewSearch, tableViewHome;
    public TableColumn<Book,String> colSearchTitle, colHomeTitle, colSearchPublicatedOn, colHomePublicatedOn, colSearchPublishingHouse, colHomePublishingHouse, colSearchSummary, colHomeSummary;
    public TableColumn<Book,Integer> colSearchPrice, colHomePrice, colSearchId, colHomeId;
    @FXML
    private Button cancelButton, menuHomeButton, menuSearchButton, borrowBookButton;
    @FXML
    private Pane paneHome, paneSearch, paneBookDetails;
    @FXML
    private TextField searchField, titleField, publishingHouseField, priceField, bookIdField, userIdField;
    @FXML
    private DatePicker publishedOnField;
    @FXML
    private TextArea summaryTextArea;
    @FXML
    private FlowPane flowPaneCoverImage;

    public void initialize(URL url, ResourceBundle resourceBundle) {
        paneHome.toFront();
        setPaneName("paneHome");
        setMainData();
    }
    public void setMainData(){
        colHomeId.setCellValueFactory(new PropertyValueFactory<>("Id"));
        colHomeTitle.setCellValueFactory(new PropertyValueFactory<>("Title"));
        colHomePublicatedOn.setCellValueFactory(new PropertyValueFactory<>("PublicatedOn"));
        colHomePublishingHouse.setCellValueFactory(new PropertyValueFactory<>("PublishingHouse"));
        colHomeSummary.setCellValueFactory(new PropertyValueFactory<>("Summary"));
        colHomePrice.setCellValueFactory(new PropertyValueFactory<>("Price"));
        HomeController homeController = new HomeController();
        tableViewHome.setRowFactory( tv -> {
            TableRow<Book> row = new TableRow<>();
            row.setOnMouseClicked(event -> {
                if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
                    paneBookDetails.toFront();
                    Book rowData = row.getItem();

                    String date = rowData.getPublicatedOn();
                    var dateTimeFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
                    var dateTime = LocalDate.parse(date, dateTimeFormatter);

                    bookIdField.setText(Integer.toString(rowData.getId()));
                    titleField.setText(rowData.getTitle());
                    publishingHouseField.setText(rowData.getPublishingHouse());
                    priceField.setText(Integer.toString(rowData.getPrice()));
                    publishedOnField.setValue(dateTime);
                    summaryTextArea.setText(rowData.getSummary());

                    InputStream stream = null;
                    try {
                        stream = new FileInputStream(defaultImagePath + rowData.getCover());
                    } catch (FileNotFoundException e) {
                        try {
                            stream = new FileInputStream(defaultImagePath + defaultImageName);
                        } catch (FileNotFoundException ex) {
                        }
                    }

                    Image image = new Image(stream);
                    ImageView imageView = new ImageView(image);
                    imageView.setFitHeight(flowPaneCoverImage.getHeight());
                    imageView.setFitWidth(flowPaneCoverImage.getWidth());
                    flowPaneCoverImage.getChildren().clear();
                    flowPaneCoverImage.getChildren().add(imageView);
                }
            });
            return row ;
        });

        tableViewHome.setItems(homeController.getBooks());
    }

    public void searchButtonOnAction(ActionEvent event) {
        colSearchId.setCellValueFactory(new PropertyValueFactory<>("Id"));
        colSearchTitle.setCellValueFactory(new PropertyValueFactory<>("Title"));
        colSearchPublicatedOn.setCellValueFactory(new PropertyValueFactory<>("PublicatedOn"));
        colSearchPublishingHouse.setCellValueFactory(new PropertyValueFactory<>("PublishingHouse"));
        colSearchSummary.setCellValueFactory(new PropertyValueFactory<>("Summary"));
        colSearchPrice.setCellValueFactory(new PropertyValueFactory<>("Price"));
        tableViewSearch.setRowFactory( tv -> {
            TableRow<Book> row = new TableRow<>();
            row.setOnMouseClicked(ev -> {
                if (ev.getClickCount() == 2 && (! row.isEmpty()) ) {
                    paneBookDetails.toFront();
                    Book rowData = row.getItem();

                    String date = rowData.getPublicatedOn();
                    var dateTimeFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
                    var dateTime = LocalDate.parse(date, dateTimeFormatter);

                    bookIdField.setText(Integer.toString(rowData.getId()));
                    titleField.setText(rowData.getTitle());
                    publishingHouseField.setText(rowData.getPublishingHouse());
                    priceField.setText(Integer.toString(rowData.getPrice()));
                    publishedOnField.setValue(dateTime);
                    summaryTextArea.setText(rowData.getSummary());

                    InputStream stream = null;
                    try {
                        stream = new FileInputStream(defaultImagePath + rowData.getCover());
                    } catch (FileNotFoundException e) {
                        try {
                            stream = new FileInputStream(defaultImagePath + defaultImageName);
                        } catch (FileNotFoundException ex) {
                        }
                    }

                    Image image = new Image(stream);
                    ImageView imageView = new ImageView(image);
                    imageView.setFitHeight(flowPaneCoverImage.getHeight());
                    imageView.setFitWidth(flowPaneCoverImage.getWidth());
                    flowPaneCoverImage.getChildren().clear();
                    flowPaneCoverImage.getChildren().add(imageView);
                }
            });
            return row ;
        });
        SearchController searchController = new SearchController();
        tableViewSearch.setItems(searchController.getBooks(searchField.getText()));
    }

    public void cancelButtonOnAction(ActionEvent event){
        Stage stage = (Stage) cancelButton.getScene().getWindow();
        stage.close();
    }

    public void menuButtonOnAction(ActionEvent event){
        if(event.getSource() == menuHomeButton){
            setPaneName("paneHome");
            paneHome.toFront();
            setMainData();
        }else if(event.getSource() == menuSearchButton){
            setPaneName("paneSearch");
            paneSearch.toFront();
        }
    }

    public void backButtonOnAction(ActionEvent event){
        var lastPannelName = getPaneName();

        System.out.println(lastPannelName);

        if(lastPannelName == "paneHome"){
            paneHome.toFront();
        }else if(lastPannelName == "paneSearch"){
            paneSearch.toFront();
        }
    }

    public void borrowBookOnAction(ActionEvent event){
        HomeController homeController = new HomeController();
        var currentBookId = Integer.valueOf(bookIdField.getText());
        try {
            homeController.borrowBook(1, 1);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        System.out.println((currentBookId));
    }

    public static String getPaneName() {
        return paneName;
    }

    public void display(String ceva){
        System.out.println(ceva);
    }

    public static void setPaneName(String paneName) {
        MainController.paneName = paneName;
    }

}

SceneController.java

public class SceneController {

    private double xOffset = 0;
    private double yOffset = 0;

    public void switchScene(Stage stage, String file) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource(file));
        
        root.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                xOffset = event.getSceneX();
                yOffset = event.getSceneY();
            }
        });

        root.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                stage.setX(event.getScreenX() - xOffset);
                stage.setY(event.getScreenY() - yOffset);
            }
        });

        stage.setScene(new Scene(root));
        stage.show();
    }

}
Kratos
  • 33
  • 4
  • Does this answer your question? [Passing Parameters JavaFX FXML](https://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml) – Giovanni Contreras Jan 02 '23 at 17:02
  • No, it doesn't help, my problem is that i use a separate Scene Controller than usual and i don't know how to pass values through scenes – Kratos Jan 02 '23 at 17:04
  • 4
    You would need to define a method in `SceneController` that allows you to pass the data. Alternatively, use a [MVC approach](https://stackoverflow.com/questions/32342864/applying-mvc-with-javafx) and make the username part of the model. – James_D Jan 02 '23 at 17:23
  • 1
    Unrelated: [don't use `PropertyValueFactory`](https://stackoverflow.com/questions/72437983/why-should-i-avoid-using-propertyvaluefactory-in-javafx). – jewelsea Jan 02 '23 at 18:06

1 Answers1

6

Using the method:

In SceneController.switchScene, replace:

Parent root = FXMLLoader.load(getClass().getResource(file));

with:

FXMLLoader loader = new FXMLLoader(
   getClass().getResource(
      file
   )
); 

Parent root = loader.load();
Controller controller = loader.getController();

// do other stuff

return controller;

returning a Controller from switchScene.

Then use it:

MainController mainController = (MainController)
    sceneController.switchScene(stage, "main-view.fxml");
mainController.setLoginDetails(loginDetails);

Alternatives

There are other options for doing this (some avoid the cast).

For example,

  • passing the login details to the switchScene method, which gets the controller from the loader and sets the login details on it, or
  • creating the controller up front, setting the login details on it and passing the controller to the switchScene method, which sets the controller on the loader before loading, or
  • using a controller factory mechanism like this clever thing from eden, or
  • applying a MVC approach.
jewelsea
  • 150,031
  • 14
  • 366
  • 406