Highlighting Strings in JavaFX TextArea
We are using JavaFX's TextArea
control in our application, and trying to integrate it with Jazzy Spell Check API - as in, when a user enters a wrong word that is not in the dictionary, such word would be highlighted.
Is there a way to highlight a word in said control? I've seen no options for that in the JavaDocs, so if someone could suggest an approach?
It could be possible, I guess, to use the HTMLEditor
component and color the words diferently with <font face="red=>wrongWord</font>
. This, however, brings a whole lot of different problems with the spell checking, such as the html tags and words count.
Solution 1:
RichTextFX allows you to add style to text ranges.
Solution 2:
The JavaFX TextArea control (as of 2.0.2) does not support rich text editing where text styles (fonts, etc) are mixed.
You can highlight contiguous strings of characters in the TextArea by manipulating the TextArea's selectRange, as in the following example:
public class TextHighlight extends Application {
public static void main(String[] args) { Application.launch(args); }
@Override public void start(Stage stage) {
final TextArea text = new TextArea("Here is some textz to highlight");
text.setStyle("-fx-highlight-fill: lightgray; -fx-highlight-text-fill: firebrick; -fx-font-size: 20px;");
text.setEditable(false);
text.addEventFilter(MouseEvent.ANY, new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent t) { t.consume(); }
});
stage.setScene(new Scene(text));
stage.show();
Platform.runLater(new Runnable() {
@Override public void run() { text.selectRange(13, 18); }
});
}
}
You could use the above code as a basis to switch the TextArea to read-only mode while spell checking is happening. Implement prompting to find and fix each word in turn until the spell check is complete. Perform the prompting in a separate dialog or panel. The Jazzy demo seems to work this way http://jazzy.sourceforge.net/demo.html, so it should be fairly easy to convert its Swing UI to JavaFX.
Alternately, you could use a JavaFX WebView control to wrap any of the many javascript/html based spell checkers (e.g. http://www.javascriptspellcheck.com/) using a technique similar to what is demonstrated here: http://jewelsea.wordpress.com/2011/12/11/codemirror-based-code-editor-for-javafx/.
Solution 3:
With JavaFX 8 you can use TextFlow
You can define certain style classes for bold, red, green or any type of Texts and arrange them in TextFlow while assigning desired style class to each Text
Solution 4:
It is possible... sort of
I know this question is resolved, but I found a way to fix the issue and thought I'd post it for other people who also stumble upon this post. This is a little hacky, but it works in a pinch if you need to highlight text in a TextArea and don't want to accept the unsatisfactory "impossible" answer.
- Retrieve the background color of the TextArea and the foreground color of the text font
- Calculate the bin of highest contrast between the foreground and background color
- Place a rectangle around the desired text
- Set the color of the rectangle to the background color
- Set the blendmode of the rectangle to the bin of highest contrast
- Disable the rectangle
The rectangle will now blend perfectly with the background but change the color of the text. Disabling the rectangle means that it won'y appear as anything more than ascetic to the user - e.g actions like clicking on the rectangle will have no surprise effect.
You can slightly tweak this method if a variety of colors are desired.
I can post the implementation details if people are interested, skeptical, or if it's tricky to get working.