CodeArea selection does not work when changing style before text change
See original GitHub issueI am trying to write a matching bracket highlighter for CodeArea. I have managed to get it working in the following manner:
I have extended CodeArea into CustomCodeArea. There I have overridden the following method:
@Override
public void replaceText(int start, int end, String text) {
for (TextInsertionListener listener : insertionListeners) {
listener.codeInserted(start, end, text);
}
super.replaceText(start, end, text);
}
Here the listener is used to listen for text change just before the text is actually changed.
This is needed to clear old matching bracket highlights in the following manner:
this.tabData.getCodeArea().addTextInsertionListener((start, end, text) -> clearBracket());
Inside the clear bracket method, I am removing the style in the following manner:
this.tabData.getCodeArea().setStyle(pair.start, pair.start + 1, styleList);
this.tabData.getCodeArea().setStyle(pair.end, pair.end + 1, styleList);
I must perform the operation of clearing the bracket in the main UX thread because it must be done before the text has changed.
When this is done, however, selection fails to work (selection highlight is not started, and nothing is selected) on the first try. I have to click at the same position once more to start the selection highlight.
If there is some way to fix this (maybe fire event manually, or something else), or there is a better approach to matching bracket highlighting for CodeArea, could you please help me with that.
Thanks a lot!
Issue Analytics
- State:
- Created 3 years ago
- Comments:9 (4 by maintainers)
Top GitHub Comments
You’re welcome, thanks for PR.
First of all nice code and thanks for the code comments.
It turns out that the caretPositionProperty() listener, in the BracketHighlighter constructor, which calls highlightBracket( newVal ) somehow sabotages the area’s selection state. The simple solution is to just wrap that call in Platform.runLater like so:
codeArea.caretPositionProperty().addListener((obs,old,newVal) -> Platform.runLater(() -> highlightBracket(newVal)));
I took some time playing around with your code and also found that you don’t need to invoke
bracketHighlighter.highlightBracket()
in the Controller’scodeArea.setOnKeyTyped
event handler because it will be invoked in any case via BracketHighlighter’s caretPositionProperty() listener.Lastly I suggest an alternative to initializeBrackets which processes ALL the code area’s text every time an edit occurs. I think a better idea is to just search forward/backward from the current bracket to find it’s matching partner when needed. Here is my version of BracketHighlighter with some additional changes for you to assess and use if you like: