У меня есть TableView, который содержит наблюдаемый список из Person
элементов. Каждая строка отображает объект Person
, а также отображается его атрибут name
.Javafx: Неправильное использование метода setPredicate отфильтрованного списка
Я хочу передать это наблюдаемое в отфильтрованный список и установить предикат на атрибут имени.
То, что я хочу добиться того, что: Если я дважды нажмите любую одну строку в TableView, который содержит Person
элементов, я смог бы извлечь names
атрибуты выбранного Person
объекта и установить предикат отфильтрованных чтобы быть выбранным именем.
Таким образом, отфильтрованный список будет содержать только Person
элементов с выбранным именем.
Следующий код почти достигает всего, что я хочу. Тем не менее, есть краевой кейс, где он не работает должным образом. Это когда, например, я дважды нажимаю на человека с именем «Name = John». Отфильтрованный список будет фильтровать всех людей с именем «Джон». Теперь, если я изменил одно из имен человека в отфильтрованном списке на «Тим». Этот человек по-прежнему сохраняется в отфильтрованном списке. В идеале, я хочу, чтобы его удаляли автоматически. Но я не могу этого сделать.
Я считаю, что я не использую setPredicate
правильно, как я чувствую, что я пишу избыточные коды и должны быть более эффективный способ сделать это и будет автоматически удалить человека с другим именем сразу после Edit.
В моем Person
классе
private StringProperty Name;
private final BooleanProperty filteredName = new SimpleBooleanProperty() ;
public final boolean getFilteredName(){
return filteredNameProperty().getValue();
}
public final BooleanProperty filteredNameProperty(){
return this.filteredName;
}
public final void setFilteredName(String name){
if(getName().equals(name)){
this.filteredNameProperty().set(true);
} else{
this.filteredNameProperty().set(false);
}
}
В моем контроллере, у меня есть:
private ObservableList<Person> observableListOfPerson = FXCollections.observableArrayList(p->
new Observable[]{
p.nameProperty(),
p.filteredNameProperty()
}
);
private FilteredList<Person> filterListOfPerson= new FilteredList<>(observableListOfPerson, p-> p.filteredNameProperty().get());
public void initializeFilteredTable(){
filteredTab.setText("Filtered History");
filterTable.setItems(filterListOfPerson);
filterListOfPerson.addListener(new ListChangeListener<Person>(){
@Override
public void onChanged(ListChangeListener.Change change) {
filterTable.setItems(filterListOfPerson);
}
});
filterTable.setItems(filterListOfPerson);}
В моем AnimatedRow
классе, у меня есть:
public class AnimatedRow<T> extends TableRow<T> {
private TabPane fxTabPaneLower;
/**
* The data as an observable list of Person.
*/
private ObservableList<Person> observableListOfPerson;
private FilteredList<Person> filterListOfPerson;
public AnimatedRow(Function<T, StringExpression> nameExtractor, ObservableList<Person> observableListOfPerson, FilteredList<Person> filterListOfPerson, TabPane fxTabPaneLower) {
setOnMouseClicked(event -> {
if (event.getClickCount() == 2 && (!isEmpty())) {
final StringExpression nameBE = nameExtractor.apply(getItem());
for(Person t : observableListOfPerson){
t.setFilteredName(nameBE.get());
}
filterListOfPerson.setPredicate(p-> p.filteredNameProperty().get());
fxTabPaneLower.getSelectionModel().select(1);
((TableView<Person>)fxTabPaneLower.getTabs().get(1).getContent()).setItems(filterListOfPerson);
}
});
}
}
Вам не нужно было бы фильтровать список при фиксации обновления имени? –
@purringpigeon Нет, вам просто нужно убедиться, что основной список запускает обновления при изменении свойств. –
Я рассмотрел этот вопрос, прежде чем я разместил этот вопрос, и я сделал все, что было в ответе, который вы отправили на вопрос. Я добавил 'new ObservableList [] {p -> p.NameProperty() ....} ' – mynameisJEFF