JavaFx 2.1, 2.2 TableView update problem

My application uses JPA read data in a TableView, then modifies and displays them. The table updated the modified entry in JavaFx 2.0.3. In JavaFx 2.1, 2.2, the table no longer updates the update. I found that other people have similar problems. My plan was to keep using 2.0.3 until someone fixes the problem in 2.1 and 2.2. Now I know that this is not a mistake and will not be fixed. Well, I don’t know how to deal with it. Below are the codes modified from the demo to show the problem. If I add a new record or delete an old record from the table, the table will update perfectly. If I modify a record, the table does not update the changes until the add, delete, or sort action is performed. If I delete the modified entry and add it again, the table will be updated. But the modified entry is put on the table button. Well, if I delete the modified record, add the same record, and then move the record to its original location, the table will no longer be updated. Below is the full code, please highlight this.

import javafx.application.Application; import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.HPos; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.text.Font; import javafx.stage.Modality; import javafx.stage.Stage; import javafx.stage.StageStyle; public class Main extends Application { private TextField firtNameField = new TextField(); private TextField lastNameField = new TextField(); private TextField emailField = new TextField(); private Stage editView; private Person fPerson; public static class Person { private final SimpleStringProperty firstName; private final SimpleStringProperty lastName; private final SimpleStringProperty email; private Person(String fName, String lName, String email) { this.firstName = new SimpleStringProperty(fName); this.lastName = new SimpleStringProperty(lName); this.email = new SimpleStringProperty(email); } public String getFirstName() { return firstName.get(); } public void setFirstName(String fName) { firstName.set(fName); } public String getLastName() { return lastName.get(); } public void setLastName(String fName) { lastName.set(fName); } public String getEmail() { return email.get(); } public void setEmail(String fName) { email.set(fName); } } private TableView<Person> table = new TableView<Person>(); private final ObservableList<Person> data = FXCollections.observableArrayList( new Person("Jacob", "Smith", "jacob.smith@example.com"), new Person("Isabella", "Johnson", "isabella.johnson@example.com"), new Person("Ethan", "Williams", "ethan.williams@example.com"), new Person("Emma", "Jones", "emma.jones@example.com"), new Person("Michael", "Brown", "michael.brown@example.com")); public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { Scene scene = new Scene(new Group()); stage.setTitle("Table View Sample"); stage.setWidth(535); stage.setHeight(535); editView = new Stage(); final Label label = new Label("Address Book"); label.setFont(new Font("Arial", 20)); TableColumn firstNameCol = new TableColumn("First Name"); firstNameCol.setCellValueFactory( new PropertyValueFactory<Person, String>("firstName")); firstNameCol.setMinWidth(150); TableColumn lastNameCol = new TableColumn("Last Name"); lastNameCol.setCellValueFactory( new PropertyValueFactory<Person, String>("lastName")); lastNameCol.setMinWidth(150); TableColumn emailCol = new TableColumn("Email"); emailCol.setMinWidth(200); emailCol.setCellValueFactory( new PropertyValueFactory<Person, String>("email")); table.setItems(data); table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); //--- create a edit button and a editPane to edit person Button addButton = new Button("Add"); addButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { fPerson = null; firtNameField.setText(""); lastNameField.setText(""); emailField.setText(""); editView.show(); } }); Button editButton = new Button("Edit"); editButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { if (table.getSelectionModel().getSelectedItem() != null) { fPerson = table.getSelectionModel().getSelectedItem(); firtNameField.setText(fPerson.getFirstName()); lastNameField.setText(fPerson.getLastName()); emailField.setText(fPerson.getEmail()); editView.show(); } } }); Button deleteButton = new Button("Delete"); deleteButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { if (table.getSelectionModel().getSelectedItem() != null) { data.remove(table.getSelectionModel().getSelectedItem()); } } }); HBox addEditDeleteButtonBox = new HBox(); addEditDeleteButtonBox.getChildren().addAll(addButton, editButton, deleteButton); addEditDeleteButtonBox.setAlignment(Pos.CENTER_RIGHT); addEditDeleteButtonBox.setSpacing(3); GridPane editPane = new GridPane(); editPane.getStyleClass().add("editView"); editPane.setPadding(new Insets(3)); editPane.setHgap(5); editPane.setVgap(5); Label personLbl = new Label("Person:"); editPane.add(personLbl, 0, 1); GridPane.setHalignment(personLbl, HPos.LEFT); firtNameField.setPrefWidth(250); lastNameField.setPrefWidth(250); emailField.setPrefWidth(250); Label firstNameLabel = new Label("First Name:"); Label lastNameLabel = new Label("Last Name:"); Label emailLabel = new Label("Email:"); editPane.add(firstNameLabel, 0, 3); editPane.add(firtNameField, 1, 3); editPane.add(lastNameLabel, 0, 4); editPane.add(lastNameField, 1, 4); editPane.add(emailLabel, 0, 5); editPane.add(emailField, 1, 5); GridPane.setHalignment(firstNameLabel, HPos.RIGHT); GridPane.setHalignment(lastNameLabel, HPos.RIGHT); GridPane.setHalignment(emailLabel, HPos.RIGHT); Button saveButton = new Button("Save"); saveButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { if (fPerson == null) { fPerson = new Person( firtNameField.getText(), lastNameField.getText(), emailField.getText()); data.add(fPerson); } else { int k = -1; if (data.size() > 0) { for (int i = 0; i < data.size(); i++) { if (data.get(i) == fPerson) { k = i; } } } fPerson.setFirstName(firtNameField.getText()); fPerson.setLastName(lastNameField.getText()); fPerson.setEmail(emailField.getText()); data.set(k, fPerson); table.setItems(data); // The following will work, but edited person has to be added to the button // // data.remove(fPerson); // data.add(fPerson); // add and remove refresh the table, but now move edited person to original spot, // it failed again with the following code // while (data.indexOf(fPerson) != k) { // int i = data.indexOf(fPerson); // Collections.swap(data, i, i - 1); // } } editView.close(); } }); Button cancelButton = new Button("Cancel"); cancelButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { editView.close(); } }); HBox saveCancelButtonBox = new HBox(); saveCancelButtonBox.getChildren().addAll(saveButton, cancelButton); saveCancelButtonBox.setAlignment(Pos.CENTER_RIGHT); saveCancelButtonBox.setSpacing(3); VBox editBox = new VBox(); editBox.getChildren().addAll(editPane, saveCancelButtonBox); Scene editScene = new Scene(editBox); editView.setTitle("Person"); editView.initStyle(StageStyle.UTILITY); editView.initModality(Modality.APPLICATION_MODAL); editView.setScene(editScene); editView.close(); final VBox vbox = new VBox(); vbox.setSpacing(5); vbox.getChildren().addAll(label, table, addEditDeleteButtonBox); vbox.setPadding(new Insets(10, 0, 0, 10)); ((Group) scene.getRoot()).getChildren().addAll(vbox); stage.setScene(scene); stage.show(); } } 
+3
javafx-2
Jun 30 2018-12-12T00:
source share
7 answers

See the answer for Updating Rows in Tableview . Add these getters and it just works.
In addition, since data is an ObservableList that is defined as tableView elements, any changes to this data list will also be displayed in table.getItems() . Namely, table.setItems(data) not needed again.

+5
Jun 30 2018-12-12T00:
source share

I found a simple workaround to start updating TableView in JavaFX 2.1 TableView refresh items . This solved the problem for me.

Add this to your code:

 tableView.getColumns().get(0).setVisible(false); tableView.getColumns().get(0).setVisible(true); 
+5
Feb 21 '14 at 11:50
source share

looking at the code of TableView.java, there is a private refresh () that just executes

 getProperties().put(TableViewSkinBase.REFRESH, Boolean.TRUE); 

Finally, the code worked for me (Java8). (be careful, the permanent name is not REFRESH, but RECREATE)

 tableView.getProperties().put(TableViewSkinBase.RECREATE, Boolean.TRUE); 

(reading javafx code, this will force cell re-creation)

+5
Mar 29 '15 at 7:07
source share

Notification-based JavaFX control updates typically require that the data model object properties that support your GUI meet the minimum definition for a JavaFX Bean.

The following is an example of the minimum code required for a JavaFX property to satisfy the following requirements:

 public class Client extends DB { private IntegerProperty id = new SimpleIntegerProperty(); private StringProperty lastName = new SimpleStringProperty(); private StringProperty firstName = new SimpleStringProperty(); public final int getID() {return this.id.get(); } void setID(int id) { this.id.set(id); } public final IntegerProperty idProperty() { return this.id; } public final String getLastName() { return this.lastName.get(); } public final void setLastName(String ln) { this.lastName.set(ln); } public final StringProperty lastNameProperty() { return this.lastName; } public final String getFirstName() { return this.firstName.get(); } public final void setFirstName(String fn) { this.firstName.set(fn); } public final StringProperty firstNameProperty() { return this.firstName; } : : } 

Having a look at your code, it does not seem that your properties satisfy the requirements for JavFX Bean. Thus, automatic updates based on notifications will not be performed.

+1
Sep 04 '13 at 0:46
source share

I have the same problem and I cannot add SimpleStringProperty to the POJO used by JPA, which is a bit problematic. But it seems to me that this should be a fix problem, because I noticed the following behavior:

  • In my application, clicking on a row in a table fills in some text fields on the screen that the user can edit.
  • At this point, the user can save the data or create a new item with the same or modified data. If the user creates a new item, which is then inserted into the observed list, which is displayed in the tableview, this change is immediately reflected in the table contents. However, if the user simply saves the changes, the new data is not reflected in the table. To put new data into a list, I just do

     trialList.set(currentIndex, tempTrial); 
  • And here is what, in my opinion, points to this as a fixable problem: if I scroll the affected line out of sight and then scroll it back, new values ​​now appear.

Hope this can be fixed. Sorry, this is not an answer, so to speak, but may provide some insight for a fix.

0
Jul 10 2018-12-12T00:
source share

it worked for me

 @FXML private void refreshTableView() { firstNameCol.setVisible(false); lastNameCol.setVisible(false); emailCol.setVisible(false); firstNameCol.setVisible(true); lastNameCol.setVisible(true); emailCol.setVisible(true); } 
0
Aug 01 '13 at 18:02
source share

I had the same problem and after some searching this was my workaround. I found that if the columns are deleted and then added again, the table is updated.

 public static <T,U> void refreshTableView(final TableView<T> tableView, final List<TableColumn<T,U>> columns, final List<T> rows) { if (tableView == null) { throw new NullPointerException(); } if (columns == null) { throw new NullPointerException(); } if (rows == null) { throw new NullPointerException(); } tableView.getColumns().clear(); tableView.getColumns().addAll(columns); ObservableList<T> list = FXCollections.observableArrayList(rows); tableView.setItems(list); } 


Usage example:

 refreshTableView(myTableView, Arrays.asList(col1, col2, col3), rows); 
0
Sep 04 '13 at 0:20
source share



All Articles