Java 无法使用正确的值填充表格单元格组合框

Java 无法使用正确的值填充表格单元格组合框,java,mysql,Java,Mysql,我有一个MySQl数据库,有两个表;用户和用户角色 表用户包含以下字段: (PK)int用户标识 字符串用户名 字符串密码 字符串名 字符串姓氏 (FK)内部角色\u id 表用户角色包含以下字段: (PK)int角色\u id 字符串角色类型 我有一个tableview,我想在其中基于组合框表格单元格编辑用户表中的角色id。我需要组合框表格单元格以字符串名称的形式包含角色类型,但返回角色id的字符串 我有两个模型UserModel和RoleModel。RoleModel包含从数据库检索到的角色

我有一个MySQl数据库,有两个表;用户和用户角色

表用户包含以下字段: (PK)int用户标识 字符串用户名 字符串密码 字符串名 字符串姓氏 (FK)内部角色\u id

表用户角色包含以下字段: (PK)int角色\u id 字符串角色类型

我有一个tableview,我想在其中基于组合框表格单元格编辑用户表中的角色id。我需要组合框表格单元格以字符串名称的形式包含角色类型,但返回角色id的字符串

我有两个模型UserModel和RoleModel。RoleModel包含从数据库检索到的角色id和角色类型。UserModel从用户表中检索所有字段,并在TableView中显示这些字段。我想要实现的是一个表单元格组合框,其中包含user_role表中的所有记录,当进行选择时,它将为用户更改存储在后端数据库中的值。如果需要的话,我不确定如何将UserModel和RoleModel这两个类合并在一起以达到预期的结果。还是有其他解决办法

public class RoleModel {


    private final StringProperty roleId;
    private final StringProperty roleName;



    public RoleModel(String roleId, String roleName){
        this.roleId = new SimpleStringProperty(roleId);
        this.roleName = new SimpleStringProperty(roleName);
    }

    public String getId() {return roleId.get(); }
    public String getRoleName() { return roleName.get(); }
    public StringProperty roleIdProperty(){ return roleId; }
    public StringProperty roleNameProperty(){ return roleName; }
    public void setRoleId(String roleId){this.roleId.set(roleId);}
    public void setRoleName(String roleName){this.roleName.set(roleName);}
}

public class UserModel {

    private final StringProperty userId;
    private final StringProperty userName;
    private final StringProperty password;
    private final StringProperty roleName;
    private final StringProperty firstName;
    private final StringProperty lastName;

    public UserModel(String userId, String userName, String password, String roleName, String firstName, String lastName){

        this.userId = new SimpleStringProperty(userId);
        this.userName = new SimpleStringProperty(userName);
        this.password = new SimpleStringProperty(password);
        this.roleName = new SimpleStringProperty(roleName);
        this.firstName = new SimpleStringProperty(firstName);
        this.lastName = new SimpleStringProperty(lastName);
    }

    public String getUserId(){
        return userId.get();
    }

    public String getUserName(){
        return userName.get();
    }

    public String getPassword(){
        return password.get();
    }

    public String getRoleName(){
        return roleName.get();
    }

    public String getFirstName(){
        return firstName.get();
    }

    public String getLastName(){
        return lastName.get();
    }

    public void setUserId(String id){
        this.userId.set(id);
    }

    public void setUserName(String userName){
        this.userName.set(userName);
    }

    public void setPassword(String password){
        this.password.set(password);
    }

    public void setRoleName(String role){
        this.roleName.set(role);
    }

    public void setFirstName(String firstName){
        this.firstName.set(firstName);
    }

    public void setLastName(String lastName){
        this.lastName.set(lastName);
    }

    public StringProperty userIdProperty(){
        return userId;
    }

    public StringProperty userNameProperty(){
        return userName;
    }

    public StringProperty passwordProperty(){
        return password;
    }

    public StringProperty roleNameProperty(){
        return roleName;
    }

    public StringProperty firstNameProperty(){
        return firstName;
    }

    public StringProperty lastNameProperty(){
        return lastName;
    }
}

public class UserController implements Initializable{  //Initializable allows tagged FXML to be accessed

    //Create form variables
    @FXML
    private TextField userName;
    @FXML
    private TextField password;
    @FXML
    private ComboBox<RoleModel> role;
    @FXML
    private TextField firstName;
    @FXML
    private TextField lastName;

    @FXML
    private Button btnAddUser;

    //Create table variables using UserModel
    @FXML
    private TableView<UserModel> userTable;
    @FXML 
    private TableColumn<UserModel, String> idColumn;
    @FXML
    private TableColumn<UserModel, String> userNameColumn;
    @FXML
    private TableColumn<UserModel, String> passwordColumn;
    @FXML
    private TableColumn<UserModel, String> roleColumn;
    @FXML
    private TableColumn<UserModel, String> firstNameColumn;
    @FXML
    private TableColumn<UserModel, String> lastNameColumn;

    private DBConnection DBconnection; //Create a DBConnection object to access the database   


    private ObservableList<UserModel> userData; //Create array to store data from the user table
    private ObservableList<RoleModel> roleType;  //Create array to store data from the role table

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


        this.DBconnection = new DBConnection();
        try {
            setupCellValueFactories();
            loadUserData(); //Call method to load the user table when the window opens
            loadRoleOptions();
            populateRolesCombobox(); //Call method to load role type into the role combobox

            setupUserNameColumn();
            setupPasswordColumn();
            setupRoleColumn();
            setupFirstNameColumn();
            setupLastNameColumn();
            setTableEditable();
        } catch (SQLException error) {
            System.err.print(error);
        }

    }

    private void setupCellValueFactories(){
        this.idColumn.setCellValueFactory(new PropertyValueFactory<>("userId"));
        this.userNameColumn.setCellValueFactory(new PropertyValueFactory<>("userName"));
        this.passwordColumn.setCellValueFactory(new PropertyValueFactory<>("password"));
        this.roleColumn.setCellValueFactory(new PropertyValueFactory<>("roleName"));
        this.firstNameColumn.setCellValueFactory(new PropertyValueFactory<>("firstName"));
        this.lastNameColumn.setCellValueFactory(new PropertyValueFactory<>("lastName"));
    }

    @FXML
    private void addUser(ActionEvent event) {
        String SQL = "INSERT INTO user (user_name, password, first_name, last_name, role_id) VALUES (?,?,?,?,?)";

        try {
            Connection connection = DBConnection.getConnection();

            PreparedStatement statement = connection.prepareStatement(SQL);
            statement.setString(1, this.userName.getText());
            statement.setString(2, this.password.getText());
            statement.setString(3, this.firstName.getText());
            statement.setString(4, this.lastName.getText());
            statement.setString(5, this.role.getSelectionModel().getSelectedItem().getId());

            statement.execute();
            connection.close();

            this.userName.setText("");
            this.password.setText("");
            this.firstName.setText("");
            this.lastName.setText("");

            loadUserData();


        } catch (SQLException error) {
             System.err.print(error);
        }
    }

    @FXML
    private void deleteUser(){

        PreparedStatement statement;

         String SQL = "DELETE user \n" +
                      "FROM mpd_production.user \n" +
                      "WHERE user_id = ?";
        try{
            Connection connection = DBConnection.getConnection();  //Create a connection to the database
            statement = connection.prepareStatement(SQL);
            statement.setString(1, userTable.getSelectionModel().getSelectedItem().getUserId());

            statement.executeUpdate();

            connection.close();

            loadUserData();

        } catch (SQLException error){
            System.out.println(error);
        }
    }

    private void updateUser(String newValue, String columnName){
        String SQL = "";

        switch(columnName) {
            case "userName":
                SQL = "UPDATE user SET user_name = ? WHERE user_id = ?";
                break;
            case "password":
                SQL = "UPDATE user SET password = ? WHERE user_id = ?";
                break;
            case "role":
                SQL = "UPDATE user SET role_id = ? WHERE user_id = ?";
                break;
            case "firstName":
                SQL = "UPDATE user SET first_name = ? WHERE user_id = ?";
                break;
            case "lastName":
                SQL = "UPDATE user SET last_name = ? WHERE user_id = ?";
                break;
        }

        PreparedStatement statement;
        try{
            Connection connection = DBConnection.getConnection(); //Create a connection to the database
            statement = connection.prepareStatement(SQL);
            statement.setString(1, newValue);
            statement.setString(2, userTable.getSelectionModel().getSelectedItem().getUserId());

            statement.executeUpdate();

            connection.close();

            loadUserData();

        } catch (SQLException error){
            System.out.println(error);
        }  
    }

    private void setupUserNameColumn(){
        //sets the cell factory to use Editcell which will handle key press
        //and firing commit events
        this.userNameColumn.setCellFactory(TextFieldTableCell.forTableColumn());
        this.userNameColumn.setOnEditCommit(new EventHandler<CellEditEvent<UserModel, String>>(){
            @Override
            public void handle(CellEditEvent Event){
                updateUser(Event.getNewValue().toString(), "userName");
            }
        });

    }

    private void setupPasswordColumn(){
        //sets the cell factory to use Editcell which will handle key press
        //and firing commit events
        this.passwordColumn.setCellFactory(TextFieldTableCell.forTableColumn());
        this.passwordColumn.setOnEditCommit(new EventHandler<CellEditEvent<UserModel, String>>(){
            @Override
            public void handle(CellEditEvent Event){
                updateUser(Event.getNewValue().toString(), "password");
            }
        });
    }

    private void setupRoleColumn(){
        //sets the cell factory to use Editcell which will handle key press
        //and firing commit events
        this.roleColumn.setCellFactory(ComboBoxTableCell.forTableColumn());
        this.roleColumn.setOnEditCommit(new EventHandler<CellEditEvent<UserModel, String>>(){
            @Override
            public void handle(CellEditEvent Event){
                updateUser(Event.getNewValue().toString(), "role");
                System.out.println(Event.getNewValue());
            }

        });

    }

    private void setupFirstNameColumn(){
        this.firstNameColumn.setCellFactory(TextFieldTableCell.forTableColumn());
        this.firstNameColumn.setOnEditCommit(new EventHandler<CellEditEvent<UserModel, String>>(){
            @Override
            public void handle(CellEditEvent Event){
                updateUser(Event.getNewValue().toString(), "firstName");
            }
        });
    }

    private void setupLastNameColumn(){
        this.lastNameColumn.setCellFactory(TextFieldTableCell.forTableColumn());
        this.lastNameColumn.setOnEditCommit(new EventHandler<CellEditEvent<UserModel, String>>(){
            @Override
            public void handle(CellEditEvent Event){
                updateUser(Event.getNewValue().toString(), "lastName");
            }
        });
    }

    //This method populates the role combobox
    public void populateRolesCombobox(){
            this.role.setItems(roleType); //Set the items of the combobox to the roleData
            this.role.setCellFactory(roleTypeFactory);
            this.role.setButtonCell(roleTypeFactory.call(null));
    }



    private void setTableEditable(){
        userTable.setEditable(true); //Allows the individual cells to be selected
        userTable.getSelectionModel().cellSelectionEnabledProperty().set(true); //When characters or numbers are pressed it will start the edit in the editable fields
        userTable.setOnKeyPressed(event -> {
            if(event.getCode().isLetterKey() || event.getCode().isDigitKey()){
                editFocusedCell();
            } else if (event.getCode() == KeyCode.RIGHT || event.getCode() == KeyCode.TAB){
                userTable.getSelectionModel().selectNext();
                event.consume();
            } else if (event.getCode() == KeyCode.LEFT){
                selectPrevious();
                event.consume();
            }
        });
    }

    private void editFocusedCell(){
        final TablePosition<UserModel, ?> focusedCell = userTable.focusModelProperty().get().focusedCellProperty().get();
            userTable.edit(focusedCell.getRow(), focusedCell.getTableColumn());
    }

    private void selectPrevious(){
        if(userTable.getSelectionModel().isCellSelectionEnabled()){
            //in the cell selection mode, we have to wrap around, going from
            //right-to-left, and then wrapping to the end of the previous line
            TablePosition<UserModel, ?> pos = userTable.getFocusModel().getFocusedCell();
            if(pos.getColumn() - 1 >= 0){
                //go to previous row
                userTable.getSelectionModel().select(pos.getRow(), getTableColumn(pos.getTableColumn(), -1));
            } else if(pos.getRow() < userTable.getItems().size()) {
                //wrap to end of the previous row
                userTable.getSelectionModel().select(pos.getRow() - 1, userTable.getVisibleLeafColumn(userTable.getVisibleLeafColumns().size() - 1));
            } else {
                int focusIndex = userTable.getFocusModel().getFocusedIndex();
                if(focusIndex == - 1){
                    userTable.getSelectionModel().select(userTable.getItems().size() - 1);
                } else if(focusIndex > 0) {
                    userTable.getSelectionModel().select(focusIndex - 1);
                }
            }
        }

    }

    private TableColumn<UserModel, ?> getTableColumn(final TableColumn<UserModel, ?> column, int offset){
        int columnIndex = userTable.getVisibleLeafIndex(column);
        int newColumnIndex = columnIndex + offset;
        return userTable.getVisibleLeafColumn(newColumnIndex);
    }





    private void loadUserData()throws SQLException{

        String SQL = "SELECT user.user_id, user.user_name, user.password, user_role.role_name, user.first_name, user.last_name\n" +  //Create SQL query to pull data from user table
                     "FROM user_role\n" +
                     "INNER JOIN user ON user_role.role_id = user.role_id ";

        try {
            Connection connection = DBConnection.getConnection(); //Create a connection to the Database
            this.userData = FXCollections.observableArrayList(); //Generate array

            ResultSet resultSet = connection.createStatement().executeQuery(SQL); //Execute the SQL string and store that data in the results set object
            while (resultSet.next()){ //Loop through the data until the method next() can no longer be called
               this.userData.add(new UserModel(resultSet.getString(1),resultSet.getString(2),resultSet.getString(3), resultSet.getString(4), resultSet.getString(5), resultSet.getString(6)));
            }

            connection.close();

        } catch (SQLException error) {
            System.err.println("Error " + error);
        }

        this.userTable.setItems(this.userData);
    }

    private void loadRoleOptions(){

        String SQL = "SELECT role_id, role_name \n" +  //Generate SQL query to pull related data
                     "FROM mpd_production.user_role;"; 

        try {
            Connection connection = DBConnection.getConnection();  //Create a connection to the database
            this.roleType = FXCollections.observableArrayList();
            ResultSet resultSet = connection.createStatement().executeQuery(SQL); //Execute the SQL string and store that data in the results set object
            while (resultSet.next()){ //Loop through the data until the method next() can no longer be called
                this.roleType.add(new RoleModel(resultSet.getString("role_id"), resultSet.getString("role_name")));  //Store role_id and role_name into the roleData array
            }
            connection.close(); //Finally, close the connection

        } catch (SQLException error) {
            System.out.println(error);
        }
    }

    Callback<ListView<RoleModel>, ListCell<RoleModel>> roleTypeFactory = listView -> new ListCell<RoleModel>(){
        @Override
        protected void updateItem(RoleModel item, boolean empty){
            super.updateItem(item, empty);
            setText(empty ? "" : item.getRoleName());
        }
    };
}
公共类角色模型{
私有财产所有权;
私有财产roleName;
公共角色模型(字符串角色ID、字符串角色名称){
this.roleId=新的SimpleStringProperty(roleId);
this.roleName=新的SimpleStringProperty(roleName);
}
公共字符串getId(){return roleId.get();}
公共字符串getRoleName(){返回roleName.get();}
public StringProperty roleIdProperty(){return roleId;}
public StringProperty roleNameProperty(){return roleName;}
public void setRoleId(String roleId){this.roleId.set(roleId);}
public void setRoleName(字符串roleName){this.roleName.set(roleName);}
}
公共类用户模型{
私有属性用户标识;
私有属性用户名;
私有财产密码;
私有财产roleName;
私有财产名;
私有财产姓氏;
public UserModel(字符串userId、字符串用户名、字符串密码、字符串roleName、字符串firstName、字符串lastName){
this.userId=新的SimpleStringProperty(userId);
this.userName=新的SimpleStringProperty(用户名);
this.password=新的SimpleStringProperty(密码);
this.roleName=新的SimpleStringProperty(roleName);
this.firstName=新的SimpleStringProperty(firstName);
this.lastName=新的SimpleStringProperty(lastName);
}
公共字符串getUserId(){
返回userId.get();
}
公共字符串getUserName(){
返回userName.get();
}
公共字符串getPassword(){
返回密码。get();
}
公共字符串getRoleName(){
返回roleName.get();
}
公共字符串getFirstName(){
返回firstName.get();
}
公共字符串getLastName(){
返回lastName.get();
}
public void setUserId(字符串id){
this.userId.set(id);
}
public void setUserName(字符串用户名){
this.userName.set(userName);
}
public void setPassword(字符串密码){
this.password.set(密码);
}
public void setRoleName(字符串角色){
this.roleName.set(角色);
}
public void setFirstName(字符串firstName){
this.firstName.set(firstName);
}
public void setLastName(字符串lastName){
this.lastName.set(lastName);
}
公共StringProperty userIdProperty(){
返回用户标识;
}
公共StringProperty userNameProperty(){
返回用户名;
}
公共字符串属性passwordProperty(){
返回密码;
}
public StringProperty roleNameProperty(){
返回roleName;
}
public StringProperty firstNameProperty(){
返回名字;
}
公共StringProperty lastNameProperty(){
返回姓氏;
}
}
公共类UserController实现可初始化{//Initializable允许访问标记的FXML
//创建表单变量
@FXML
私有文本字段用户名;
@FXML
私有文本字段密码;
@FXML
私有组合框角色;
@FXML
私有文本字段名;
@FXML
私有文本字段lastName;
@FXML
专用按钮;
//使用UserModel创建表变量
@FXML
私有表视图用户表;
@FXML
私有表列idColumn;
@FXML
私有TableColumn userNameColumn;
@FXML
私有表列passwordColumn;
@FXML
私有表列roleColumn;
@FXML
private TableColumn firstNameColumn;
@FXML
私有TableColumn lastNameColumn;
private DBConnection DBConnection;//创建一个DBConnection对象来访问数据库
private ObservableList userData;//创建数组以存储用户表中的数据
private ObservableList roleType;//创建数组以存储角色表中的数据
@凌驾
公共void初始化(URL、ResourceBundle、ResourceBundle){
this.DBconnection=new DBconnection();
试一试{
setupCellValueFactorys();
loadUserData();//在窗口打开时调用方法加载用户表
loadRoleOptions();
populateRolesCombobox();//调用方法将角色类型加载到角色组合框中
setupUserNameColumn();
setupPasswordColumn();
setupRoleColumn();
setupFirstNameColumn();
setupLastNameColumn();
setTableEditable();
}捕获(SQLException错误){
系统错误打印(错误);
}
}
私有void setupCellValueFactorys(){
this.idColumn.setCellValueFactory(新的PropertyValueFactory(“userId”);
this.userNameColumn.setCellValueFactory(新的PropertyValueFactory(“用户名”);
此.passwordColumn.setCellValueFactory(新属性值