问题描述:TreeView编辑行的时候存在这么一个问题:当某行处于编辑时,只有点击TreeItem(即有数据部分)才能够取消当前正在编辑的行,点击Treeview的空白处时编辑状态不取消。
主要思路是:开始编辑时让TextField获取焦点,然后监听textfield的焦点事件,当失去焦点时取消编辑。以下是重写TreeCell部分
TreeView<String> tree = new TreeView<>(rootClass);
tree.setEditable(true);
tree.setCellFactory((TreeView<String> p) -> new TextFieldTreeCellImpl());
tree.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
/**
* 重写树TreeCell,使得TreeCell可编辑
*
* @author user
*
*/
private final class TextFieldTreeCellImpl extends TreeCell<String> {
private TextField textField;
public TextFieldTreeCellImpl() {
}
@Override
public void startEdit() {
super.startEdit();
createTextField();
setText(null);
setGraphic(textField);
textField.selectAll();
textField.requestFocus(); //textFiled获取焦点
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setGraphic(getTreeItem().getGraphic());
textField = null;
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
setGraphic(getTreeItem().getGraphic());
}
}
}
private void createTextField() {
textField = new TextField(getString());
oldName = getString();
textField.setOnKeyReleased((KeyEvent t) -> {
if (t.getCode() == KeyCode.ENTER) {
commitEdit(textField.getText());
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
});
//textFiled失去焦点时取消编辑
textField.focusedProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
if (!textField.isFocused()) {
cancelEdit();
}
}
});
}
private String getString() {
String str = getItem() == null ? "" : getItem().toString();
return str;
}
}