title: JavaFX TableView with highlighted text
body: <p>I want to highlight parts of text displayed in a <code>JavaFX</code> <code>TableView</code>. Till now i'm using <code>Text</code> objects in <code>TextFlow</code> objects. To highlight specific parts in a text i am using tags to cut the text in parts (<code>javafx.scene.text</code> objects) to highlight or not to highlight with the following code.</p>
  
  <pre><code>col3.setCellValueFactory(new PropertyValueFactory&lt;RegexMatch, String&gt;("text"));
  col3.setCellFactory(new Callback&lt;TableColumn, TableCell&gt;() {
      @Override
      public TableCell call(TableColumn param) {
          TableCell cell = new TableCell() {
              @Override
              protected void updateItem(Object text, boolean empty) {
                  if (text != null &amp;&amp; text instanceof String) {
                      String str = (String) text;
                      TextFlow flow = new TextFlow();
                      if (txtSearchField.getText().length() &gt; 3 &amp;&amp; str.contains(HIGHLIGHT_START)) {
                          // Something to highlight
                          flow.getChildren().clear();
                          while (str.contains(HIGHLIGHT_START)) {
                              // First part
                              Text starttext = new Text(str.substring(0, str.indexOf(HIGHLIGHT_START)));
                              starttext.setWrappingWidth(Double.MAX_VALUE);
                              flow.getChildren().add(starttext);
                              str = str.substring(str.indexOf(HIGHLIGHT_START) + HIGHLIGHT_START.length(), str.length());
                              // Part to highlight
                              Text highlightedText = new Text(str.substring(0, str.indexOf(HIGHLIGHT_END)));
                              highlightedText.setStyle("-fx-text-background-color: yellow;");
                              highlightedText.setFill(Color.BLUE);
                              highlightedText.setWrappingWidth(Double.MAX_VALUE);
                              flow.getChildren().add(highlightedText);
                              // Last part
                              str = str.substring(str.indexOf(HIGHLIGHT_END) + HIGHLIGHT_END.length(), str.length());
                              if (!str.contains(HIGHLIGHT_START)) {
                                  Text endtext = new Text(str);
                                  endtext.setWrappingWidth(Double.MAX_VALUE);
                                  flow.getChildren().add(endtext);
                              }
                          }
                      }else if (txtSearchField.getText().length() &lt; 1) {
                          // Remove former highlightings and show simple text
                          str = str.replaceAll(HIGHLIGHT_START, "");
                          str = str.replaceAll(HIGHLIGHT_END, "");
                          flow.getChildren().clear();
                          Text textModule = new Text(str);
                          textModule.setWrappingWidth(Double.MAX_VALUE);
                          flow.getChildren().add(textModule);
                      } else {
                          // show simple text
                          flow.getChildren().clear();
                          Text textModule = new Text(str);
                          textModule.setWrappingWidth(Double.MAX_VALUE);
                          flow.getChildren().add(textModule);
                      }
                      flow.setPrefHeight(bigIcons ? BIG_SIZE : SMALL_SIZE);
                      setGraphic(flow);
                  }
              }
          };
          return cell;
      }
  });
  </code></pre>
  
  <p>Unfortunately the background highlighting does not work and i have strange linebreaks as shown in the picture. The text does not contain any linebreaks.</p>
  
  <p><img src="https://i.stack.imgur.com/Wo0HF.jpg" alt="scrennshot oft table"></p>
  
  <p>(Sorry for the picture quality, its a real screenshot :))</p>
  
  <p>Any help is appreciated.</p>
  
  <p><strong>Solution</strong><br>
  As @eckig suggested, using multiple <code>Labels</code> in a <code>HBox</code> is an good idea, because each 'Label' can have its own background color and you can use as much <code>Labels</code> in line in a <code>HBox</code> as needed:</p>
  
  <pre><code>  col3.setCellValueFactory(new PropertyValueFactory&lt;RegexMatch, String("excerptLineTable"));
    col3.setCellFactory(new Callback&lt;TableColumn, TableCell&gt;() {
      @Override
      public TableCell call(TableColumn param) {
          TableCell cell = new TableCell() {
              @Override
              protected void updateItem(Object text, boolean empty) {
                  if (text != null &amp;&amp; text instanceof String) {
                      HBox hbox = new HBox();
  
  
                      String str = (String) text;
                      if (txtSearchField.getText().length() &gt; 3 &amp;&amp; str.contains(HIGHLIGHT_START)) {
                          // Something to highlight
                          hbox.getChildren().clear();
                          while (str.contains(HIGHLIGHT_START)) {
                              // First part
                              Label label = new Label(str.substring(0, str.indexOf(HIGHLIGHT_START)));
                              hbox.getChildren().add(label);
                              str = str.substring(str.indexOf(HIGHLIGHT_START) + HIGHLIGHT_START.length(), str.length());
                              // Part to highlight
                              Label label2 = new Label(str.substring(0, str.indexOf(HIGHLIGHT_END)));
                              label2.setStyle("-fx-background-color: blue;");
                              hbox.getChildren().add(label2);
                              // Last part
                              str = str.substring(str.indexOf(HIGHLIGHT_END) + HIGHLIGHT_END.length(), str.length());
                              if (!str.contains(HIGHLIGHT_START)) {
                                  Label label3 = new Label(str);
                                  hbox.getChildren().add(label3);
                              }
                          }
                      } else if (txtSearchField.getText().length() &lt; 1) {
                          // Remove former highlightings and show simple text
                          str = str.replaceAll(HIGHLIGHT_START, "");
                          str = str.replaceAll(HIGHLIGHT_END, "");
                          hbox.getChildren().clear();
                          Label label = new Label(str);
                          hbox.getChildren().add(label);
                      } else {
                          // show simple text
                          hbox.getChildren().clear();
                          Label label = new Label(str);
                          hbox.getChildren().add(label);
                      }
                      setGraphic(hbox);
                  }
              }
          };
          return cell;
      }
  });
  </code></pre>