Harald K
Harald K

Reputation: 27054

JavaFX TableView Cell editor

I've implemented a cell editor similar to EditingCell in Example 12-11 Alternative Solution Of Cell Editing from the JavaFX TableView tutorial (the issue I'm describing can be reproduced, using that example as an SSCCE).

However, it comes along with a very annoying bug, and that is that every mouse click (either for moving the caret, or selecting text) inside the TextEdit control used as the editor will cause a focus change, and thus commit and end the edit.

The code responsible for committing:

textField.focusedProperty().addListener(new ChangeListener<Boolean>(){
    @Override
    public void changed(ObservableValue<? extends Boolean> arg0,
                        Boolean arg1, Boolean arg2) {
        if (!arg2) {
            commitEdit(textField.getText());
        }
    }
});

I've been trying for hours looking through this with the debugger and reading source code, and I've found that the focus is temporary given to the TableView's VirtualFlow and then quickly back to the TextEdit again (not sure why this focus change happens, feel free to shed some light on that too). This happens faster than the UI updates, so users will not experience this quick focus change. Unfortunately, the change listener will...

How can I create a cell editor that does not have this issue?

Requirements:

PS: The solution mentioned in this blog post (and its update) shows the exact same issue.

Upvotes: 4

Views: 2267

Answers (1)

James_D
James_D

Reputation: 209225

This problem appears fixed in 1.8b123.

If you need it to work in FX 2.2, try this super-ugly hack:

            public void changed(ObservableValue<? extends Boolean> arg0, 
                Boolean arg1, Boolean arg2) {
                    if (!arg2) {
                        final PauseTransition wait = new PauseTransition(Duration.millis(20));
                        wait.setOnFinished(new EventHandler<ActionEvent>() {
                            @Override
                            public void handle(ActionEvent event) {
                                if (! textField.isFocused()) {
                                    commitEdit(textField.getText());          
                                }
                            }
                        });
                        wait.play();
                    }
            }

Upvotes: 1

Related Questions