Замена cellFactory
автоматически не приводит к замене ячеек столбца новой фабрикой.afaik нет способа заставить TableView
воссоздать его ячейки.Ячейки, возвращаемые вашей первоначальной cellFactory
, должны динамически изменяться в зависимости от текста поиска:
private final StringProperty searchText = new SimpleStringProperty();
TableView
создание / инициализация
tc_source.setCellFactory(column -> new TableCell<File, String>() {
private final ChangeListener<String> listener = (o, oldValue, newValue) -> {
updateContents(getItem(), newValue);
};
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
searchText.removeListener(listener);
if (item == null || empty) {
setGraphic(null);
setText(null);
} else {
updateContents(item, searchText.get());
searchText.addListener(listener);
}
}
private void updateContents(String item, String search) {
if (search == null || search.isEmpty() || !item.toLowerCase().contains(search.toLowerCase())) {
setText(item);
setTextFill(javafx.scene.paint.Color.BLACK);
setContentDisplay(ContentDisplay.TEXT_ONLY);
} else {
double rowHeight = this.getTableRow().getHeight();
setGraphic(buildTextFlow(item, search));
setHeight(rowHeight);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
}
private TextFlow buildTextFlow(String text, String filter) {
int filterLength = filter.length();
if (filterLength == 0) {
return new TextFlow(createNormalText(text));
} Font font = Font.font("Italic", 12);
java.awt.Color color= java.awt.Color.BLUE; // why are we using the awt class here?
TextFlow t = new TextFlow();
String lowerText = text.toLowerCase();
filter = filter.toLowerCase();
int index1 = 0;
int matchIndex=0;
while ((matchIndex = lowerText.indexOf(filter, index1)) != -1) {
if (index1 != matchIndex) {
t.getChildren().add(createNormText(text.substring(index1, matchIndex)));
}
index1 = matchIndex + filterLength;
t.getChildren().add(createText(text.substring(matchIndex, index1), color));
}
if (index1 != text.length()) {
t.getChildren().add(createNormText(text.substring(index1)));
}
return t;
}
});
public void onClickSearch(ActionEvent event) {
searchText.set(srep.getText());
}
Примечание.повторное использование TextFlow
, так как каждый раз, когда вы ищете или прокручиваете достаточно далеко, TextFlow
и все его дочерние элементы воссоздаются для каждой ячейки в вашем текущем коде.