I have a small app. With this app, I can add a new Employee record to a MySQL database and then display these records. buildData()
retrieves data from the database and displays it in the TableView, I also call this method every time a new record is added to "refresh" the TableView. This however isn't behaving as expected.
This is the view after the first record is added:
when I hit the button to add another record, this is what I get:
If I close the app and reopen it, the TableView is normal:
This is what the buildData()
method looks like (Method ignores Typechecking and all that.Probably the cause?)
private ObservableList<ObservableList> data;
public void buildData() {
Connection c;
TableColumn col;
data = FXCollections.observableArrayList();
try {
c = DataBaseConnection.connectToDatabase();
String SQL = "SELECT * FROM employees";
ResultSet rs = c.createStatement().executeQuery(SQL);
for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
final int j = i;
col = new TableColumn(rs.getMetaData().getColumnName(i + 1));
col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList, String>, ObservableValue<String>>() {
public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList, String> param) {
return new SimpleStringProperty(param.getValue().get(j).toString());
}
});
employeeTableView.getColumns().addAll(col);
}
while (rs.next()) {
ObservableList<String> row = FXCollections.observableArrayList();
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
row.add(rs.getString(i));
}
data.add(row);
}
employeeTableView.setItems(data);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
and then the method to add a new Employee Record to the database:
public void addEmployeeToDatabase() {
Employee employee = new Employee("Anne Droid", "Marketing", "Gender");
String query = "INSERT INTO employees (Employee_Name, Department, Gender) VALUES (?, ? , ?)";
try {
preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, employee.getEmployeeName());
preparedStatement.setString(2, employee.getDepartment());
preparedStatement.setString(3, employee.getGender());
preparedStatement.execute();
buildData();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
Finally, the Employee class:
public class Employee {
private StringProperty employeeName;
private StringProperty department;
private StringProperty gender;
public Employee() {
}
public Employee(String employeeName, String department, String gender) {
this.employeeName = new SimpleStringProperty(employeeName);
this.department = new SimpleStringProperty(department);
this.gender = new SimpleStringProperty(gender);
}
public String getEmployeeName() {
return employeeName.get();
}
public StringProperty employeeNameProperty() {
return employeeName;
}
...
Am using pure java, no FXML.I've searched for a solution, but none is available (As far as I can tell). Any pointers?
In the buildData
method you replace the items. However you add new TableColumn
s to the columns
list without removing any columns. This way the number of columns is increased every time you call the buildData
method.
Clear the columns
list before adding new columns to fix this:
...
ResultSet rs = c.createStatement().executeQuery(SQL);
employeeTableView.getColumns().clear();
for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
final int j = i;
col = new TableColumn(rs.getMetaData().getColumnName(i + 1));
...
employeeTableView.getColumns().add(col);
}
...