How to do per-keystroke validation of TextFieldTab

2019-08-12 01:28发布

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.

1条回答
乱世女痞
2楼-- · 2019-08-12 01:44

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();
                    }
                }
            });
        }
    }
查看更多
登录 后发表回答