-
Bug
-
Resolution: Fixed
-
P4
-
7-pool, 8, 8u5
-
Windows 7 64bit, JDK 1.8.0 64 bit, JavaFX 8 64bit, NetBeans 8.
When using a CheckBoxTableCell in a TableColumn, the onEditCommit callback of that column is not called.
The following code set an onEditCommit callback on :
- A column "active" that shows a boolean value and uses a CheckBoxTableCell
- A column "name" that shows a string value and uses TextFieldTableCell
In this example, as we do not use JavaFX properties or JavaBeans observable values.
So it is important that we can use the onEditCommit calback to track edition of the values in order to modify back the source object.
Upon value edition in respective columns:
- The onEditCommit of the column "active" is never called.
- The onEditCommit callback of the column "name" is always called, as expected.
class Foo {
public boolean active;
public String name;
}
final TableView<Foo> tableView = new TableView<>();
tableView.setEditable(true);
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
////////////////////////////////////////////////////////////////////////
final TableColumn<Foo, Boolean> activeColumn = new TableColumn<>("active");
activeColumn.setCellValueFactory((TableColumn.CellDataFeatures<Foo, Boolean> p) -> {
final Foo f = p.getValue();
return new SimpleBooleanProperty(f.active);
});
activeColumn.setCellFactory(CheckBoxTableCell.forTableColumn(activeColumn));
activeColumn.setOnEditCommit((TableColumn.CellEditEvent<Foo, Boolean> event) -> {
System.out.printf("active: %b -> %b", event.getOldValue(), event.getNewValue()).println();
final Foo f = event.getRowValue();
f.active = event.getNewValue();
});
activeColumn.setEditable(true);
////////////////////////////////////////////////////////////////////////
final TableColumn<Foo, String> nameColumn = new TableColumn<>("name");
nameColumn.setCellValueFactory((TableColumn.CellDataFeatures<Foo, String> p) -> {
final Foo f = p.getValue();
return new SimpleStringProperty(f.name);
});
nameColumn.setCellFactory(TextFieldTableCell.<Foo>forTableColumn());
nameColumn.setOnEditCommit((TableColumn.CellEditEvent<Foo, String> event) -> {
System.out.printf("name: %s -> %s", event.getOldValue(), event.getNewValue()).println();
final Foo f = event.getRowValue();
f.name = event.getNewValue();
});
nameColumn.setEditable(true);
////////////////////////////////////////////////////////////////////////
final StackPane root = new StackPane();
root.getChildren().add(tableView);
final Scene scene = new Scene(root, 500, 150);
primaryStage.setTitle("TableView");
primaryStage.setScene(scene);
final Foo f = new Foo();
f.active = true;
f.name = "Foo";
tableView.getItems().add(f);
tableView.getColumns().setAll(activeColumn, nameColumn);
primaryStage.show();
A workaround for this issue is to change the definition of the cellValueFactory of the activeColumn so we can add a ChangeListener<Boolean> to the returned property. This listener is used to track changes in the property so the source object can be updated correctly:
activeColumn.setCellValueFactory((TableColumn.CellDataFeatures<Foo, Boolean> p) -> {
final Foo f = p.getValue();
BooleanProperty property = new SimpleBooleanProperty(f.active);
property.addListener((ObservableValue<? extends Boolean> observableValue, Boolean oldValue, Boolean newValue) -> {
System.out.printf("active: %b -> %b", oldValue, newValue).println();
f.active = newValue;
});
return property;
});
The following code set an onEditCommit callback on :
- A column "active" that shows a boolean value and uses a CheckBoxTableCell
- A column "name" that shows a string value and uses TextFieldTableCell
In this example, as we do not use JavaFX properties or JavaBeans observable values.
So it is important that we can use the onEditCommit calback to track edition of the values in order to modify back the source object.
Upon value edition in respective columns:
- The onEditCommit of the column "active" is never called.
- The onEditCommit callback of the column "name" is always called, as expected.
class Foo {
public boolean active;
public String name;
}
final TableView<Foo> tableView = new TableView<>();
tableView.setEditable(true);
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
////////////////////////////////////////////////////////////////////////
final TableColumn<Foo, Boolean> activeColumn = new TableColumn<>("active");
activeColumn.setCellValueFactory((TableColumn.CellDataFeatures<Foo, Boolean> p) -> {
final Foo f = p.getValue();
return new SimpleBooleanProperty(f.active);
});
activeColumn.setCellFactory(CheckBoxTableCell.forTableColumn(activeColumn));
activeColumn.setOnEditCommit((TableColumn.CellEditEvent<Foo, Boolean> event) -> {
System.out.printf("active: %b -> %b", event.getOldValue(), event.getNewValue()).println();
final Foo f = event.getRowValue();
f.active = event.getNewValue();
});
activeColumn.setEditable(true);
////////////////////////////////////////////////////////////////////////
final TableColumn<Foo, String> nameColumn = new TableColumn<>("name");
nameColumn.setCellValueFactory((TableColumn.CellDataFeatures<Foo, String> p) -> {
final Foo f = p.getValue();
return new SimpleStringProperty(f.name);
});
nameColumn.setCellFactory(TextFieldTableCell.<Foo>forTableColumn());
nameColumn.setOnEditCommit((TableColumn.CellEditEvent<Foo, String> event) -> {
System.out.printf("name: %s -> %s", event.getOldValue(), event.getNewValue()).println();
final Foo f = event.getRowValue();
f.name = event.getNewValue();
});
nameColumn.setEditable(true);
////////////////////////////////////////////////////////////////////////
final StackPane root = new StackPane();
root.getChildren().add(tableView);
final Scene scene = new Scene(root, 500, 150);
primaryStage.setTitle("TableView");
primaryStage.setScene(scene);
final Foo f = new Foo();
f.active = true;
f.name = "Foo";
tableView.getItems().add(f);
tableView.getColumns().setAll(activeColumn, nameColumn);
primaryStage.show();
A workaround for this issue is to change the definition of the cellValueFactory of the activeColumn so we can add a ChangeListener<Boolean> to the returned property. This listener is used to track changes in the property so the source object can be updated correctly:
activeColumn.setCellValueFactory((TableColumn.CellDataFeatures<Foo, Boolean> p) -> {
final Foo f = p.getValue();
BooleanProperty property = new SimpleBooleanProperty(f.active);
property.addListener((ObservableValue<? extends Boolean> observableValue, Boolean oldValue, Boolean newValue) -> {
System.out.printf("active: %b -> %b", oldValue, newValue).println();
f.active = newValue;
});
return property;
});