CaretListener.caretPositionChanged() gets called before selection data is updated
I am writing a plugin processing current user actions in open editors. For this purpose, I am trying to access the current selection and caret position in all open editors and react to changes.
Previously, I was using a SelectionListener to do this. However, this listener is not informed for caret position changes without a selection (i.e. just moving the caret). To also cover this case, I wanted to switch over to using the CaretListener, in particular the method CaretListener.caretPositionChanged().
My code looks as follows:
EditorFactory.getInstance()
.getEventMulticaster()
.addCaretListener(caretListener, ApplicationManager.getApplication());
private final CaretListener caretListener =
new CaretListener() {
@Override
public void caretPositionChanged(@NotNull CaretEvent event) {
...
Caret caret = event.getCaret();
...
int selectionStart = caret.getSelectionStart();
int selectionEnd = caret.getSelectionEnd();
// selection model returns the same values
SelectionModel selectionModel = event.getEditor().getSelectionModel();
int modelSelectionStart = selectionModel.getSelectionStart();
int modelSelectionEnd = selectionModel.getSelectionEnd();
...
}
};
When implementing the new listener logic, I ran into an issue regarding the timeliness of the selection data. It seems to me like the caret listener is called before the selection information for the caret/editor is updated, leading to a situation where the retrieved information is always "one step behind".
This can be observed by registering both a SelectionListener and a CaretListener. The CaretListener is always called first and does not reflect the correct state: If I, for example, drop the current selection by moving the caret to another line (e.g. by clicking it), the caret listener is triggered first in a state where the caret and selection model will still return the (now outdated) selection offsets. The selection listener is called second in a state where the correct selection offsets are reported.
INFO 04:34:37,656 [AWT-EventQueue-0] (LocalTextSelectionChangeHandler.java:164) caret listener - selection start: 144, selection end: 491, has selection: true
INFO 04:34:37,658 [AWT-EventQueue-0] (LocalTextSelectionChangeHandler.java:93) selection listener - selection start: 521, selection end: 521, resulting offset: 0
It doesn't matter whether the selection offsets are read from the caret or from the SelectionModel of the corresponding editor. Both return the same, outdated information.
Am I using the caret listener incorrectly, is this a bug (if so, should I create a bugtracker entry for it?), or is it just a consequence of the implementation (i.e. working as intended, meaning it wont be changed)?
Are there any alternatives that would allow me to react to all selection/caret updates while always reading the correct state?
Please sign in to leave a comment.
I am still very much interested in an answer to this question.
Any chance of having someone take a look at this?