加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

JavaFX FilteredList,基于列表中项目的属性进行过滤

发布时间:2020-12-15 04:28:20 所属栏目:Java 来源:网络整理
导读:我有一个案例,我需要过滤一个ObservableList Item基于项目的某些属性(即条件是内部的而不是外部的).我发现 javafx有FilteredList所以我试了一下.我可以设置谓词和过滤工作,直到确定过滤的属性值发生变化.设置谓词现在完成如下: list.setPredicate(t - !t.fi
我有一个案例,我需要过滤一个ObservableList< Item>基于项目的某些属性(即条件是内部的而不是外部的).我发现 javafx有FilteredList所以我试了一下.我可以设置谓词和过滤工作,直到确定过滤的属性值发生变化.设置谓词现在完成如下:

list.setPredicate(t -> !t.filteredProperty().get())

由于谓词返回boolean而不是BooleanProperty,因此对该属性的更改不会反映在列表中.

这有什么简单的解决方案吗?我可以尝试做一些解决方法,例如创建一个单独的列表并同步,或者每次属性在一个项目中更改时重置谓词,希望重新触发过滤,但我首先想问一下,如果有人知道一个漂亮的解决方案,因为这些变通办法当然不是.

解决方法

使用 extractor创建基础列表.这将使基础列表在任何元素的filteredProperty()发生更改时触发更新事件. FilteredList将观察这些事件,因此将相应更新:

ObservableList<Item> baseList = FXCollections.observableArrayList(item -> 
    new Observable[] {item.filteredProperty()});
FilteredList<Item> list = new FilteredList<>(baseList,t -> ! t.filteredProperty().get());

快速演示:

import java.util.stream.IntStream;

import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;


public class DynamicFilteredListTest {

    public static void main(String[] args) {

        ObservableList<Item> baseList = FXCollections.observableArrayList(item -> 
                new Observable[] {item.filteredProperty()});

        FilteredList<Item> list = new FilteredList<>(baseList,t -> ! t.isFiltered());

        list.addListener((Change<? extends Item> c) -> {
            while (c.next()) {
                if (c.wasAdded()) {
                    System.out.println(c.getAddedSubList()+ " added to filtered list");
                }
                if (c.wasRemoved()) {
                    System.out.println(c.getRemoved()+ " removed from filtered list");
                }
            }
        });

        System.out.println("Adding ten items to base list:n");

        IntStream.rangeClosed(1,10).mapToObj(i -> new Item("Item "+i)).forEach(baseList::add);

        System.out.println("nFiltered list now:n"+list);

        System.out.println("nSetting filtered flag for alternate items in base list:n");

        IntStream.range(0,5).map(i -> 2*i).mapToObj(baseList::get).forEach(i -> i.setFiltered(true));

        System.out.println("nFiltered list now:n"+list);
    }


    public static class Item {
        private final StringProperty name = new SimpleStringProperty() ;
        private final BooleanProperty filtered = new SimpleBooleanProperty() ;

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

        public final StringProperty nameProperty() {
            return this.name;
        }

        public final String getName() {
            return this.nameProperty().get();
        }

        public final void setName(final String name) {
            this.nameProperty().set(name);
        }

        public final BooleanProperty filteredProperty() {
            return this.filtered;
        }

        public final boolean isFiltered() {
            return this.filteredProperty().get();
        }

        public final void setFiltered(final boolean filtered) {
            this.filteredProperty().set(filtered);
        }

        @Override
        public String toString() {
            return getName();
        }
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读