与问题相关联:JavaFX 2: Save edit in TableCell
建立可编辑的tableview似乎需要分配管道 - 即为每个textField捕获所有事件(获得/失去焦点,从textField中删除,从textField提交编辑到底层数据模型),并覆盖TableCell中的几个方法。
建立编辑的默认行为 - 在单元格中双击 - 对我或标准表格控件的用户来说似乎并不熟悉。我只想点击进入单元格并开始输入,大部分都是。
那里有没有完全实施的例子?请添加你的或评论来设计这样的生物。
答案 0 :(得分:22)
而不是响应TableCell
和TableColumn
级别的多个事件来启动单元格的编辑,并成功更新单元格的基础数据 - 而是提供自定义单元格工厂并覆盖{{ 1}}单元格中的方法,将textField的textProperty直接“绑定”到updateItem()
数据模型中的属性(在本例中为TableView
)。我添加了其他美学,使单元格内的textField看起来无缝,并响应悬停和聚焦状态。
所有的魔法都发生在StringProperty
方法中。你必须跟踪textField及其绑定的内容 - TableView API'回收'TableCells以减少内存消耗:
updateItem()
以下是包含4列的表的完整示例,所有列都绑定到基础textField。只要键入textField,Observable列表中的基础数据模型就会更新:
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(!empty) {
// Show the Text Field
this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
// Retrieve the actual String Property that should be bound to the TextField
// If the TextField is currently bound to a different StringProperty
// Unbind the old property and rebind to the new one
ObservableValue<String> ov = getTableColumn().getCellObservableValue(getIndex());
SimpleStringProperty sp = (SimpleStringProperty)ov;
if(this.boundToCurrently==null) {
this.boundToCurrently = sp;
this.textField.textProperty().bindBidirectional(sp);
}
else {
if(this.boundToCurrently != sp) {
this.textField.textProperty().unbindBidirectional(this.boundToCurrently);
this.boundToCurrently = sp;
this.textField.textProperty().bindBidirectional(this.boundToCurrently);
}
}
System.out.println("item=" + item + " ObservableValue<String>=" + ov.getValue());
//this.textField.setText(item); // No longer need this!!!
}
else {
this.setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}