Kevin Gebhardt
Kevin Gebhardt

Reputation: 368

Is there more than one caret in JavaFX TextField?

I'm currently getting in touch with JavaFx. As a starter, I try to write a small calculator.

This calculator contains a TextField showing the expression to be calculated. I am able to put text in there via keyboard or via the buttons of the calculator. Clicking into the TextField with the mouse or navigating via keyboard results in a blinking caret at the right position as expected. But this caret is obviously not backed by the caret property of the TextField, as textField.getCaretPosition(); returns 0 no matter were the blinking "mouse/keyboard-caret" shows up. Moving the "intern" caret with textField.forward() or textField.backward() etc. works just fine.

Is there another property for the "mouse/keyboard-caret"? Please don't tell me I have to listen for mouseclicks and set the caret by myself. The same problem seems to occour for selections, textField.getSelection() returns (0,0), although text is selected(which means, it's blue).

Here's what I'm trying to do in my controller-class. textField.getText() works fine, so the TextField itself should not be the problem.

@FXML
private void onNumberButtonClicked(ActionEvent event){
    String formerText = textField.getText();
    int pos = textField.getCaretPosition(); //always returns 0, no matter were the cursor is
    String additionalText = ((Button)event.getSource()).getText();
    textField.setText(formerText.substring(0, pos) + 
    additionalText + 
    formerText.substring(pos));
}

Thank you for your help!

Upvotes: 1

Views: 1356

Answers (1)

fabian
fabian

Reputation: 82461

The caret position is set to 0 when the TextField looses focus. When you click a button, it gets the focus, therefore the TextField looses it. You can store the old carret position when the control looses focus to fix this:

private int oldCaretPosition;
textField.focusedProperty().addListener((observable, oldValue, newValue) -> {
    if (!newValue) {
        oldCaretPosition = textField.getCaretPosition();
    }
});
private void onNumberButtonClicked(ActionEvent event){
    String formerText = textField.getText();
    String additionalText = ((Button)event.getSource()).getText();
    textField.setText(formerText.substring(0, oldCaretPosition)
                        + additionalText
                        + formerText.substring(oldCaretPosition));
}

Alternatively you can set the focusTraversable property of the Button to false.

Upvotes: 4

Related Questions