Не может обновить Tableview с данными из базы данных (mysql) - PullRequest
0 голосов
/ 20 марта 2019

Я пытаюсь обновить свой tableView данными из базы данных mysql, но, несмотря на то, что я могу извлечь данные, таблица не обновляется.

Это мой класс контроллера для моего приложения

/*
* To change this license header, choose License Headers in Project 
Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package usermanagementsoftwere;

import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;
import java.sql.SQLException;
import java.util.ResourceBundle;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.Initializable;
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.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
/**
*
* @author JOSE FOUNDATION
*/
public class UsersController implements Initializable{

@FXML
private TableView<User> tableUsers;
@FXML
private TableColumn<User, String> colId;

@FXML
private TableColumn<User, String> colName;

@FXML
private TableColumn<User, String> colEmail;

@FXML
private Button Register;

private ObservableList<User> users = FXCollections.observableArrayList();

private DBConnect connect;

@Override
public void initialize(URL location, ResourceBundle resources) {


  try {
        connect = new DBConnect();
        users = connect.getUsersData();
    } catch (Exception ex) {
        AlertHelper.showAlert(Alert.AlertType.ERROR, null, "Error!",
                "Cannot connect to the database");
    } 



    tableUsers.setItems(users);


    colId.setCellValueFactory(new PropertyValueFactory<User, String>("id"));
    colName.setCellValueFactory(new PropertyValueFactory<User, String>("name"));
    colEmail.setCellValueFactory(new PropertyValueFactory<User, String>("email"));



}



@FXML
void registerButtonClicked(ActionEvent event) {
    openRegistrationForm();
}



private void openRegistrationForm(){
     try {
         FXMLLoader fxmlLoader = new FXMLLoader();
         fxmlLoader.setLocation(getClass().getResource("registration_form.fxml"));
         Stage stage = new Stage();
         stage.setTitle("Registration Form FXML Application");
         stage.setScene(new Scene(fxmlLoader.load(), 800, 500));
         stage.show();
     } catch (IOException ex) {
         Logger.getLogger(UsersController.class.getName()).log(Level.SEVERE, null, ex);
     }
}

public void refreshTable(){
      try {
        connect = new DBConnect();
        users = connect.getUsersData();
    } catch (Exception ex) {
        AlertHelper.showAlert(Alert.AlertType.ERROR, null, "Error!",
                "Cannot connect to the database");
    } 



}

}

Получение данных не является проблемой, но при этом обновляется tableView, что является проблемой.

Вот контроллер для приложения, которое должно инициировать обновление tableView.Я пытаюсь вызвать обновление tableView в методе submitData () (когда я отправляю форму пользователя):

/*
* To change this license header, choose License Headers in Project 
Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package usermanagementsoftwere;

/**
*
* @author JOSE FOUNDATION
*/
import java.io.IOException;
import java.net.URL;
import java.sql.SQLException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import javafx.stage.Window;

public class RegistrationFormController implements Initializable{
@FXML
private TextField nameField;

@FXML
private TextField emailField;

@FXML
private PasswordField passwordField;

@FXML
private Button submitButton;


UsersController users;

DBConnect connect = null;

 @Override
public void initialize(URL location, ResourceBundle resources) {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("usersgui.fxml"));
    try {
        Parent root = loader.load();
    } catch (IOException ex) {
        Logger.getLogger(RegistrationFormController.class.getName()).log(Level.SEVERE, null, ex);
    }

        this.users = (UsersController) loader.getController();

}

@FXML
protected void handleSubmitButtonAction(ActionEvent event) {
    Window owner = submitButton.getScene().getWindow();
    if(nameField.getText().isEmpty()) {
        AlertHelper.showAlert(Alert.AlertType.ERROR, owner, "Form Error!",
                "Please enter your name");
        return;
    }
    if(emailField.getText().isEmpty()) {
        AlertHelper.showAlert(Alert.AlertType.ERROR, owner, "Form Error!",
                "Please enter your email id");
        return;
    }
    if(passwordField.getText().isEmpty()) {
        AlertHelper.showAlert(Alert.AlertType.ERROR, owner, "Form Error!",
                "Please enter a password");
        return;
    }


    submitData();




}

public void submitData(){

    try {
        connect = new DBConnect();
    } catch (Exception ex) {
        AlertHelper.showAlert(Alert.AlertType.ERROR, null, "Error!",
                "Cannot add user to the database");
    } 


    try {
        connect.submitData(nameField.getText(), emailField.getText(),
                passwordField.getText());

        //here is where I trigger the refresh
        users.refreshTable();

        AlertHelper.showAlert(Alert.AlertType.INFORMATION,null, "Registration Successful!",
           "Successfully Registered "  + nameField.getText());



        Stage stage = (Stage) submitButton.getScene().getWindow();
        stage.close();
    } catch (Exception ex) {
         AlertHelper.showAlert(Alert.AlertType.ERROR, null, "Error!",
                "Cannot add user to the database");
        Logger.getLogger(RegistrationFormController.class.getName()).log(Level.SEVERE, null, ex);
    }
}
}

Вот класс базы данных на всякий случай, хотя, как я уже сказал, он отлично работает:

/*
* To change this license header, choose License Headers in Project 
Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package usermanagementsoftwere;

import java.sql.*;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.Alert;

/**
*
* @author JOSE FOUNDATION
*/
public class DBConnect {
private Connection con;
private Statement st;
private ResultSet rs;

public DBConnect() throws ClassNotFoundException, SQLException{

        Class.forName("com.mysql.cj.jdbc.Driver");

        //con = DriverManager.getConnection("jdbc:mysql://localhost:3306/UserManagementSystem","root","");
        con = DriverManager.getConnection("jdbc:mysql://localhost:3306/UserManagementSystem?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root","");
        st = con.createStatement();



}

public ObservableList<User> getUsersData() throws SQLException{
    ObservableList<User> users = FXCollections.observableArrayList();;

        String query = "select * from users";
        rs = st.executeQuery(query);
        while(rs.next()){

            User user = new User(Integer.parseInt(rs.getString("id")),
                    rs.getString("name"),rs.getString("email"));

            users.add( user);
        }



    return users;
}

public void submitData(String name, String email, String password) throws SQLException{
   // String query = "insert into users (name, email, password)"
         //   +" values("+name+","+email+","+password")";



        String query = "insert into users (name, email, password)"
            +" values(?,?,?)";

        PreparedStatement preparedStmt = con.prepareStatement(query);
        preparedStmt.setString(1, name);
        preparedStmt.setString(2, email);
        preparedStmt.setString(3, password);

        preparedStmt.execute();




}
}

Ваша помощь будет очень признательна.Я пытался решить это самостоятельно, но у меня ничего не получилось.

Ответы [ 2 ]

0 голосов
/ 20 марта 2019

Попробуйте изменить ObservableList на List.

public List<User> getUsersData() throws SQLException{
    List<User> users = new ArrayList();

        String query = "select * from users";
        rs = st.executeQuery(query);
        while(rs.next()){

            User user = new User(Integer.parseInt(rs.getString("id")),
                    rs.getString("name"),rs.getString("email"));

            users.add( user);
        }



    return users;
}

Затем при инициализации:

tableUsers.setItems(users);
try {
        connect = new DBConnect();
        users.addAll(connect.getUsersData());
} catch (Exception ex) {
        AlertHelper.showAlert(Alert.AlertType.ERROR, null, "Error!",
                "Cannot connect to the database");
} 

Тогда:

public void refreshTable(){
    try {
        connect = new DBConnect();
        users.addAll(connect.getUsersData());
    } catch (Exception ex) {
        AlertHelper.showAlert(Alert.AlertType.ERROR, null, "Error!",
       "Cannot connect to the database");
    } 
}

Также, если вы собираетесь звонить connect = new DBConnect(); во многих местах в пределах Controller, я лично думаю, что вам следует закрыть соединение после получения необходимой информации. Когда я программирую, я использую один из двух подходов. Я либо оставляю базу данных открытой до завершения программы, а затем закрываю базу данных; или я каждый раз открываю базу данных, получаю необходимую информацию и сразу же закрываю базу.

0 голосов
/ 20 марта 2019

Когда вы вызываете users = connect.getUsersData(); в вашем методе refreshTable(), вы заменяете список users новым списком.Так что теперь TableView ссылается на список, отличный от того, который вы обновляете.

Вместо этого используйте тот же список users и просто обновите его элементы:

public void refreshTable(){
    try {
        connect = new DBConnect();
        users.setAll(connect.getUsersData());
    } catch (Exception ex) {
        AlertHelper.showAlert(Alert.AlertType.ERROR, null, "Error!",
                "Cannot connect to the database");
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...