I am trying to do per-keystroke validation in a JavaFX TextFieldTableCell
but I do not know how to capture the text-changed events from the embedded TextField
control.
If the object in question were simply a TextField
, then textField.textProperty().addListener(myChangeListener)
would do the trick. TextFieldTableCell
also exposes textProperty()
, but this property behaves quite differently on TextFieldTableCell
. It does not generate change events on a per-keystroke basis. Rather, I see lots of events when the TableView
is first displayed, and I see one event each time I begin editing in a cell.
First of all, about textProperty().
Look here to see :
http://docs.oracle.com/javafx/2/api/index.html
TextProperty() is a property of labeled parent class, you will learn nothing from it, because it is not used. It is tricky thing : cell - inheritant of labeled control. TextField, which you see, when start editing, it is a graphic node of cell (graphicProperty()) (as far as I remember documentation).
And, this graphic node is assigned by a text field, only when editing starts.
AFAIK, there is no direct access to editable node.
The way to solve the issue - implement editable cell by your self.
Let me talk to developer, to learn more...
Supposing, you have DataItem class, which contains String, and supposing that TableView has encapsulated data type DataItem, and the only column has the same encapsulated data type, you may use this implementation as basis :
public class TextFieldTableCell extends TableCell<DataItem, DataItem> {
private TextField textField;
public TextFieldTableCell() {
}
@Override
public void startEdit() {
super.startEdit();
if (isEmpty()) {
return;
}
if (textField == null) {
createTextBox();
} else {
textField.setText(new CellCustomStringConverter().toString(getItem()));
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
textField.requestFocus();
textField.selectAll();
}
@Override
public void cancelEdit() {
super.cancelEdit();
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
@Override
public void updateItem(DataItem item, boolean empty) {
super.updateItem(item, empty);
if (!isEmpty()) {
if (textField != null) {
textField.setText(new CellCustomStringConverter().toString(item));
}
setText(item.toString());
}
}
private void createTextBox() {
textField = new TextField(new CellCustomStringConverter().toString(getItem()));
textField.setId(TABLE_EDIT_ID);
textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit(new DataItem(textField.getText()));
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
}
}