我试图用mysql数据库中的数据刷新tableView,但是即使我可以获取数据,tableview也没有更新。
这是我的应用程序的控制器类
/*
* 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刷新的应用程序的控制器。我正在尝试在SubmitData()方法中触发tableView刷新(当我提交用户表单时):
/*
* 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();
}
}
您的帮助将不胜感激。我已经尝试过自己解决它,但是没有任何进展。
答案 0 :(得分:0)
以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");
}
答案 1 :(得分:0)
尝试将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
,我个人认为您应该在获取所需信息后关闭连接。当我编程时,我采用两种方法之一。我要么保持数据库打开状态直到程序结束,然后关闭数据库;要么关闭数据库。或者我每次打开数据库,获取所需的信息,然后立即关闭数据库。