1

我正在尝试在 JavaFX 中进行每次击键验证,TextFieldTableCell但我不知道如何从嵌入式控件中捕获文本更改事件。TextField

如果有问题的对象只是 a TextField,那么textField.textProperty().addListener(myChangeListener)就可以了。 TextFieldTableCell也暴露textProperty()了,但是这个属性在TextFieldTableCell. 它不会在每次击键的基础上生成更改事件。相反,当第一次显示时我会看到很多事件TableView,并且每次我开始在单元格中编辑时都会看到一个事件。

4

1 回答 1

1

首先,关于 textProperty()。

看这里看看:

http://docs.oracle.com/javafx/2/api/index.html

TextProperty() 是标记父类的属性,你不会从中学到任何东西,因为它没有被使用。这是一件棘手的事情:单元格 - 标记控件的继承者。您看到的TextField,当开始编辑时,它是单元格的图形节点(graphicProperty())(据我记得文档)。

而且,该图形节点仅在编辑开始时由文本字段分配。

AFAIK,无法直接访问可编辑节点。

解决问题的方法 - 自己实现可编辑单元格。

让我与开发人员交谈,以了解更多...

假设你有一个包含String的DataItem类,并且假设TableView封装了数据类型DataItem,并且唯一的列具有相同的封装数据类型,你可以使用这个实现作为基础:

    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();
                    }
                }
            });
        }
    }
于 2013-04-19T20:07:59.150 回答