Highlighting Strings in JavaFX TextArea

30,181

Solution 1

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 2

RichTextFX allows you to add style to text ranges.

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.

  1. Retrieve the background color of the TextArea and the foreground color of the text font
  2. Calculate the bin of highest contrast between the foreground and background color
  3. Place a rectangle around the desired text
  4. Set the color of the rectangle to the background color
  5. Set the blendmode of the rectangle to the bin of highest contrast
  6. 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.

Share:
30,181
Marcelo
Author by

Marcelo

To infinity, and beyond!

Updated on July 09, 2022

Comments

  • Marcelo
    Marcelo almost 2 years

    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.

  • Adam Jensen
    Adam Jensen over 9 years
    I would like to know more about this solution. Especially #3. How do you know where to place the rectangle; what happens when the window/TextArea moves; how do you deal with exceptions like half-obscured or hidden text; what happens when the TextArea scrolls?
  • lmat - Reinstate Monica
    lmat - Reinstate Monica about 6 years
    Whoa, dude, that's hacky! kudos! ;-)
  • lmat - Reinstate Monica
    lmat - Reinstate Monica about 6 years
    How do you decide where to put this rectangle? For instance, say I want to highlight characters 7-13 (and I don't know if that includes a line break!!), how can I decide where the top left of the rectangle goes?