JavaFX TableView能否无需setOnEditCommit自动提交泛型字段修改?
JavaFX TableView 自动提交编辑值到对象字段的实现方法
可以实现无需手动编写setOnEditCommit的自动提交,但前提是你的实体类(如示例中的User)需要使用JavaFX的Property类型(而非普通的String/Integer)来定义字段。这样TableView的编辑单元格可以直接与Property双向绑定,编辑完成后自动同步到对象中。
核心原理
当单元格的cellValueFactory返回的是一个可写的JavaFX Property(如StringProperty)时,TextFieldTableCell会自动建立双向绑定:编辑单元格时,新值会直接写入对应的Property,无需手动调用setter或编写setOnEditCommit逻辑。
步骤1:修改实体类为JavaFX Property字段
将User类的普通字段替换为JavaFX Property类型,并保留标准的getter/setter以及Property访问方法:
public class User { private final StringProperty username = new SimpleStringProperty(); private final IntegerProperty age = new SimpleIntegerProperty(); // Username相关方法 public String getUsername() { return username.get(); } public void setUsername(String username) { this.username.set(username); } public StringProperty usernameProperty() { return username; } // Age相关方法 public int getAge() { return age.get(); } public void setAge(int age) { this.age.set(age); } public IntegerProperty ageProperty() { return age; } }
步骤2:简化TableColumn初始化代码
无需编写setOnEditCommit,直接将cellValueFactory绑定到实体类的Property即可:
@FXML TableColumn<User, String> _tableStateUsername; @FXML TableColumn<User, Integer> _tableStateAge; @Override public void initialize(URL location, ResourceBundle resources) { // 用户名列:TextFieldTableCell + 绑定到usernameProperty _tableStateUsername.setCellFactory(TextFieldTableCell.<User, String>forTableColumn(new DefaultStringConverter())); _tableStateUsername.setCellValueFactory(cellData -> cellData.getValue().usernameProperty()); // 年龄列:TextFieldTableCell + 绑定到ageProperty(使用IntegerConverter) _tableStateAge.setCellFactory(TextFieldTableCell.<User, Integer>forTableColumn(new DefaultIntegerConverter())); _tableStateAge.setCellValueFactory(cellData -> cellData.getValue().ageProperty().asObject()); }
为什么你之前的尝试未成功?
你使用Bindings.select(cellData.getValue(), "username")的方式,返回的是一个只读的包装对象,并非可写的JavaFX Property。这种情况下,单元格无法将编辑后的新值反向写入到对象字段中,因此必须返回实体类中直接定义的可写Property才能实现自动提交。
替代方案(不修改实体类)
如果无法将实体类字段改为JavaFX Property,仍需保留setOnEditCommit,但可以用Lambda表达式简化代码:
_tableStateUsername.setOnEditCommit(event -> event.getRowValue().setUsername(event.getNewValue()));
内容的提问来源于stack exchange,提问作者Stanislav Orlov
相关产品推荐
相关产品推荐

