(Searching on stackoverflow, I've seen this question addressed for Javascript but not for JavaFX)
I have a TextArea that is effectively the primary text editor in a word-processor-like application (i.e., I intend the user to spend a lot of time working inside this TextArea). When the user tabs into the TextArea, I would like the cursor to be placed at the end of the TextArea so that the user can continue editing from the end of what they last typed.
I've implemented this using a ChangeListener (code below) and it has the desired behavior. However, since the cursor is placed at the end of the TextArea every time the focus is gained, then if I were to switch applications and then switch back, the cursor gets moved. This is inconvenient if, for instance, the user is typing a sentence somewhere in the middle of the TextArea, switches over to read an email, then switches back to find that their cursor has moved.
Is there a focus traversal policy that does this or some other way to implement this so that the cursor is moved to the end only when the user tabs into the TextArea? It seems to me that this would be commonly desired behavior: to have the cursor always appear at the end of a TextArea whenever the TextArea is tabbed into, but otherwise leave the cursor unmoved.
TextArea passageTextArea;
passageTextArea.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue)
{
if (newValue.booleanValue()) {
passageTextArea.positionCaret(passageTextArea.getText().length());
}
}
});
You can add an EventHandler
for KeyEvent
which moves the caret to the end of the text, when you press the Tab
key:
EventHandler<KeyEvent> tabListener = evt -> {
if (evt.getCode() == KeyCode.TAB && !evt.isShiftDown()) {
evt.consume();
passageTextArea.requestFocus();
passageTextArea.end();
}
};
node.addEventHandler(KeyEvent.ANY, tabListener);
You can simply use Platform.runLater() to move the marker to the end of the textArea. that way it will go in to the UI tasks queue, and will be executed only after the focus event ends. this is how you do it:
TextArea passageTextArea;
passageTextArea.focusedProperty().addListener((observable, oldValue, newValue) ->
{
if(newValue)
{
Platform.runLater(() -> passageTextArea.end());
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With