0

Hello I am working on a little project which javaFX, basically, I have two windows. the first one is the user account interface (Account.FXML) which allow the user to access his account and it contains an edit button that shows up the second window (edit.FXML) once is clicked. the second window allows the user to update his infos. what I want to do is to update the tableView in the first window when the user click on edit button in the second window so I am trying to call the UserDetails() metodh from the first window through communication between controllers but I get a Null pointer exception in (EditController.java) at line controller.UserDetails(); can you tell me how to fix this error ?

accountController.java:

 public class accountController implements Initializable {

    @FXML
    private TableColumn<User, Integer> id;
    @FXML
    private TableColumn<User, String> username;
    @FXML
    private TableColumn<User, String> email;
    @FXML
    private TableColumn<User, String> password;
    @FXML
    private TableView<User> table;

    public void userDetails() {

        try {

            userDao dao = new userDao();
            ObservableList<User> list = dao.LoadAll();
             id.setCellValueFactory(new PropertyValueFactory<>("id"));
             username.setCellValueFactory(new PropertyValueFactory<>("username"));
            email.setCellValueFactory(new PropertyValueFactory<>("email"));
            password.setCellValueFactory(new PropertyValueFactory<>("password"));
            table.setItems(list);
            table.setEditable(true);
        } catch (Exception ex) {
            Logger.getLogger(AccountController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
        
    @FXML
    void editUserDetails(ActionEvent event) {
        UserModel item = table.getSelectionModel().getSelectedItem();
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Edit.fxml"));
            Parent root = loader.load();
            editController controller = (editController) loader.getController();
            controller.txtId.setText(String.valueOf(item.getId()));
            controller.txtId.setEditable(false);
            controller.txtUserName.setText(item.getUserName());
            controller.txtEmail.setText(item.getEmail());
            controller.txtPassword.setText(item.getPassword());
            Scene scene = new Scene(root);
            scene.setFill(Color.TRANSPARENT);
            Stage stage = new Stage();
            stage.setScene(scene);
            stage.initModality(Modality.APPLICATION_MODAL);
            stage.initStyle(StageStyle.TRANSPARENT);
            stage.showAndWait();
        } catch (Exception ex) {
            Logger.getLogger(ConsultationController.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
public void initialize(URL url, ResourceBundle rb) {
    UserDetails();
}
}

account.FXML

 <AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.home.accountController">
   <children>
      <TableView fx:id="table" layoutX="52.0" layoutY="100.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
        <columns>
          <TableColumn fx:id="col_id" prefWidth="50.0" text="id" />
          <TableColumn fx:id="col_username" prefWidth="75.0" text="USER NAME" />
          <TableColumn fx:id="col_email" prefWidth="180.0" text="Email" />
          <TableColumn fx:id="col_password" prefWidth="180.0" text="Password" />
        </columns>
      </TableView>
      <Button mnemonicParsing="false" onAction="#editUserDetails" prefHeight="40.0" prefWidth="261.0" styleClass="btnAdd" stylesheets="@style.css" text="Edit" />
   </children>
   <padding>
      <Insets bottom="20.0" left="20.0" right="20.0" />
   </padding>
</AnchorPane>

editController.java

    public class editController implements Initializable {

    @FXML
    protected TextField txtId;
    @FXML
    protected TextField txtUserName;
    @FXML
    protected TextField txEmail;
    @FXML
    protected TextField txtPassowrd;
    
    @FXML
    void update(ActionEvent event) { 
        int id = Integer.parseInt(txtId.getTexT());
        String username = txtUserName.getText();
        String email = txtEmail.getText();
        String password = txtPassword.getText();
        User user = new User();
        user.setId(id);
        user.setUserName(username);
        user.setEmail(email);
        user.setPassword(password));
        try {
            int count = userDao.getInstance().update(user); // userDao is the class that contains the SQL statement.
            if (count == 1) {
                FXMLLoader loader = new FXMLLoader(getClass().getResource("account.fxml"));
                accountController controller = (accountController) loader.getController();
                controller.userDetails();
            } else {
                Alert error = new Alert(Alert.AlertType.ERROR, "Faild", ButtonType.OK);
                error.showAndWait();
            }
        } catch (Exception ex) {
            Logger.getLogger(EditController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

edit.FXML

 <AnchorPane fx:id="rootPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="589.0" prefWidth="600.0" style="-fx-border-width: 1px; -fx-border-color: black;" xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.home.editController">
      <HBox layoutX="137.0" layoutY="42.0" prefHeight="472.0" prefWidth="600.0" style="-fx-background-color: white;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="42.0">
         <children>                                 . 
                                                    .
                                                    .
                  <Button fx:id="update" mnemonicParsing="false" onAction="#update" text="Update" />
                  <Button fx:id="exit" layoutX="10.0" layoutY="398.0" mnemonicParsing="false" onAction="#exit" text="Quitter" />
         </children>
      </HBox>
   </children>
</AnchorPane>

user.java

    public class User {
    private final IntegerProperty id = new SimpleIntegerProperty();
    private final StringProperty usename = new SimpleStringProperty();
    private final StringProperty email = new SimpleStringProperty();
    private final StringProperty password = new SimpleStringProperty();

    public user(Integer id, String username, String email, String password) {
        setId(id);
        setUserName(username);
        setEmail(email);
        setPassword(Password);
    }

    public User() {
        
    }

    public final IntegerProperty IdProperty() {
        return this.id;
    }

    public final java.lang.Integer getId() {
        return this.IdProperty().get();
    }

    public final void setId(final java.lang.Integer id) {
        this.idProperty().set(id);
    }
    
    public final StringProperty UserNameProperty() {
        return this.username;
    }

    public final java.lang.String getUserNmae() {
        return this.UserNameProperty().get();
    }

    public final void setUserName(final java.lang.String username) {
        this.UserNameProperty().set(username);
    }
    
        public final StringProperty EmailProperty() {
        return this.email;
    }

    public final java.lang.String getEmail() {
        return this.EmailProperty().get();
    }

    public final void setEmail(final java.lang.String email) {
        this.EmailProperty().set(email);
    }
    
        public final StringProperty PasswordProperty() {
        return this.password;
    }

    public final java.lang.String getPassword() {
        return this.PasswordProperty().get();
    }

    public final void setPassword(final java.lang.String Password) {
        this.PasswordProperty().set(password);
    }
mimobok
  • 1
  • 1
  • 1
    [mcve] please .. and stick to java naming conventions! – kleopatra Feb 26 '21 at 14:59
  • the fxml must be __loaded__ before its controller is fully usable – kleopatra Feb 26 '21 at 15:03
  • 2
    Consider using a MVC-type approach, instead of communicating directly between controllers. See https://stackoverflow.com/questions/32342864/applying-mvc-with-javafx – James_D Feb 26 '21 at 15:40
  • @kleopatra I updated UserDetails method to userDetails thanks for the warning – mimobok Feb 26 '21 at 16:55
  • good starter :) now the same for methods in User and no underscores .. – kleopatra Feb 26 '21 at 16:56
  • @kleopatra update has been done thank you again :) – mimobok Feb 26 '21 at 17:23
  • I have a question why I cant call the method from editController just like I did while passing the values from userController to editController ? – mimobok Feb 26 '21 at 17:27
  • Because the `FXMLLoader` only creates a controller when it loads the FXML file (how would it know what kind of controller to create, if it hadn't loaded the file?). It doesn't help though, because you've already loaded that FXML file once, and you need the controller that was created that time you loaded the FXML; you don't want to load the FXML a second time and create a new controller. – James_D Feb 26 '21 at 19:52
  • @James_D thank you for your reply – mimobok Feb 26 '21 at 22:58

0 Answers0