public class FocusLostTextFieldTableCell<S, T> extends TableCell<S, T> {
private TextField textField;
private final StringConverter<T> converter;
public FocusLostTextFieldTableCell(StringConverter<T> converter) {
this.converter = converter;
}
public static <S> Callback<TableColumn<S, String>, TableCell<S, String>> forTableColumn() {
return forTableColumn(new DefaultStringConverter());
}
public static <S, T> Callback<TableColumn<S, T>, TableCell<S, T>> forTableColumn(StringConverter<T> converter) {
return param -> new FocusLostTextFieldTableCell<>(converter);
}
```
@Override
public void startEdit() {
if (!isEditable() || !getTableView().isEditable() || !getTableColumn().isEditable()) {
return;
}
super.startEdit();
if (textField == null) {
createTextField();
}
setText(null);
setGraphic(textField);
textField.selectAll();
textField.requestFocus();
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText(converter.toString(getItem()));
setGraphic(null);
}
@Override
public void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(converter.toString(getItem()));
}
setText(null);
setGraphic(textField);
} else {
setText(converter.toString(getItem()));
setGraphic(null);
}
}
}```
private void createTextField() {
textField = new TextField(converter.toString(getItem()));
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
textField.setOnAction(event -> commitEdit(converter.fromString(textField.getText())));
textField.setOnKeyPressed(event -> {
if (event.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
});
textField.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
if (!isNowFocused) {
System.out.println("单元格失去焦点" + !isNowFocused);
commitEdit(converter.fromString(textField.getText()));
}
});
}```
@Override
public void commitEdit(T newValue) {
if (isEditing()) {
super.commitEdit(newValue);
} else if (!newValue.equals(getItem())) {
TableColumn<S, T> column = getTableColumn();
if (column != null) {
TableColumn.CellEditEvent<S, T> event = new TableColumn.CellEditEvent<>(getTableView(), new TablePosition<>(getTableView(), getIndex(), column), TableColumn.editCommitEvent(), newValue);
Event.fireEvent(column, event);
}
}
setText(converter.toString(newValue));
setGraphic(null);
}