It's a bit late, but here is my solution (sure it's not "Best practice", but works for me and I haven't found anything better so far) in case someone steel need it. It's only some parts: I think so it's easier to understand in such case. Note that the column isn't editable. In order to make it editable you need to owervrite methods "startEdit", "cancelEdit" and "commitEdit" in "return new TableCell()" (it's out of this question theme).
@FXML private TableView<YourEntity> table;
@Override
@SuppressWarnings("unchecked")
public void initialize(URL location, ResourceBundle resources) {
TableColumn column1 = new TableColumn(resources.getString("YourShowedColumnName"));
column1.setCellValueFactory(new PropertyValueFactory<>("YourDBColumnName"));
table.getColumns().setAll(column1, ..., .......);
table.setFixedCellSize(20.0); //To not change it in "graphic" with TextFlow
column1.setCellFactory(column -> {
return new TableCell<Mandant, String>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setGraphic(null);
setText(null);
setStyle("");
} else {
setGraphic(null);
if (!searchField.getText().isEmpty() && item.toLowerCase().contains(searchField.getText().toLowerCase())) {
Double rowHeight = this.getTableRow().getHeight();
setGraphic(buildTextFlow(item, searchField.getText()));
setHeight(rowHeight);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
} else {
setText(item);
setTextFill(Color.BLACK);
setStyle("");
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
}
};
table.setEditable(true);
/**
* Build TextFlow with selected text. Return "case" dependent.
*
* @param text - string with text
* @param filter - string to select in text
* @return - TextFlow
*/
private TextFlow buildTextFlow(String text, String filter) {
int filterIndex = text.toLowerCase().indexOf(filter.toLowerCase());
Text textBefore = new Text(text.substring(0, filterIndex));
Text textAfter = new Text(text.substring(filterIndex + filter.length()));
Text textFilter = new Text(text.substring(filterIndex, filterIndex + filter.length())); //instead of "filter" to keep "case"
textFilter.setFill(Color.ORANGE);
textFilter.setFont(Font.font("Helvetica", FontWeight.BOLD, 12));
return new TextFlow(textBefore, textFilter, textAfter);
}
Hope it would be helpful for someone.
