3

I read since JavaFX 8 you can make use of TextFlow to highlight text. But I don't know how to use it for my TableView. In my controller class I've got this:

TableView<Person> tvPerson;
TableColumn<Person, String> tcName;
ObservableList<Person> personList;

tcName.setCellValueFactory(new PropertyValueFactory<Person, String>("name"));
tvPerson.setItems(personList);

and this is the content class:

public class Person {
    private final SimpleStringProperty name = new SimpleStringProperty("");

    public Person(String name) {
        setName(name);
    }

    public String getName() {
        return name.getValue();
    }
    public void setName(String t) {
        name.set(t);
    }
}

Thanks for help!

cody
  • 5,377
  • 13
  • 47
  • 69
  • Why text flow? That can put multiple styles (text nodes) in one pane. If you just want one style per cell, you can style cells individually. http://stackoverflow.com/a/10698420/2855515 – brian May 22 '14 at 23:16
  • Thanks for the comment. I need to highlight just a search string found inside the table cells...so not the whole content – cody May 23 '14 at 22:30

1 Answers1

8

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.

enter image description here

Ruslan Gabbazov
  • 666
  • 7
  • 18