编辑单元格时,树视图中显示错误

时间:2015-03-01 16:24:46

标签: java javafx treeview

当我使用treeview时,我有两个错误,这里发生了什么:

BUG 1 :未验证更改

如何创建错误: 让我们假设我想编辑单元格" Id"在我的面试中。picture 1

我输入其他内容:

picture 2

但是我改变主意,我不想编辑这个项目,所以不要点击输入并验证,我点击左边的其他内容,一切似乎都好,我回到了图片一,但如果我点击编辑" Id"再一次,我直接回到图片2," Id-Edit"对我来说,这意味着编辑的取消并没有奏效......

BUG 2 :价值变动

它很少发生,但是当我点击一个celle进行编辑时,这个单元格会接收另一个单元格的文本,这是一个例子:

picture 3

" Id"当我编辑它时,取出另一个单元格的文本,但如果我取消编辑,eveything将再次恢复正常,如图1所示。

这是我用于树视图的代码

    public class DatabaseStructureView extends TreeView<Object> {

    TreeItem<Object> root;

    public DatabaseStructureView() {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("DatabaseStructureView.fxml"));

        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);
        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }

        this.setEditable(true);
        this.setCellFactory((TreeView<Object> param) -> new TextFieldTreeCellImpl());
        root = new TreeItem<>();
        this.setRoot(root);
        setShowRoot(false);
        root.setExpanded(true);
    }

    private final class TextFieldTreeCellImpl extends TreeCell<Object> {

        private TextField textField;

        @Override
        public void startEdit() {
            super.startEdit();

            if (textField == null) {
                createTextField();
            }
            setText(null);
            setGraphic(textField);
            textField.selectAll();
        }

        @Override
        public void cancelEdit() {
            super.cancelEdit();
            setText(getString());
            setGraphic(getTreeItem().getGraphic());
        }

        @Override
        public void updateItem(Object 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());
            textField.setOnKeyReleased(new EventHandler<KeyEvent>() {

                @Override
                public void handle(KeyEvent t) {
                    if (t.getCode() == KeyCode.ENTER) {
                        commitEdit(getDatabase(textField.getText()));
                    } else if (t.getCode() == KeyCode.ESCAPE) {
                        cancelEdit();
                    }
                }
            });
        }

        private Database getDatabase(String text) {
            return new Database(text);
        }

        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }
    }

    /**
     *
     * @param db
     */
    public void setDatabase(Database db) {
        TreeItem<Object> dbRoot = new TreeItem<>(db);
        dbRoot.setExpanded(true);

        db.getVariables().stream().forEach((var) -> {
            dbRoot.getChildren().add(new TreeItem<>(var));
        });

        if (!root.getChildren().contains(dbRoot)) {
            root.getChildren().add(dbRoot);
        }
    }

    /**
     *
     * @param dbs
     */
    public void setDatabases(List<Database> dbs) {
        dbs.stream().forEach((db) -> {
            setDatabase(db);
        });
    }
}

正如您所看到的,我的树视图未填充String但是我创建的对象是Database,这就是我使用Object类型的原因。我认为我的问题来自更新功能,但不知道为什么。

感谢阅读:)

1 个答案:

答案 0 :(得分:2)

startEdit()方法中,您需要将文本字段的文本设置为正确的值:

    @Override
    public void startEdit() {
        super.startEdit();

        if (textField == null) {
            createTextField();
        }

        textField.setText(getString());

        setText(null);
        setGraphic(textField);
        textField.selectAll();
    }