将 Property<Predicate<MyObject>> 绑定到 ListView

我试图在一个ListView可以选择多个项目的地方和一个ObjectProperty. 当一个项目被选中时,我想相应地过滤一TableView列:

http://img.mukewang.com/60ee48e60001135e15960622.jpg

使用两个较低的过滤器(组件、详细信息),我进行如下绑定:


ObjectProperty<Predicate<Log>> detailsSearchFilter = new SimpleObjectProperty<>();

TextField detailsSearchField = new TextField();

detailsSearchField.setPromptText("e.g. finished initializing");

detailsSearchFilter.bind(Bindings.createObjectBinding(() ->


                    log -> log.getDetails().toLowerCase().contains(detailsSearchField.getText().toLowerCase()),

            detailsSearchField.textProperty()

    ));

然后稍后添加逻辑运算符方法and()以便能够组合所有过滤器:


logFilteredList.predicateProperty().bind(Bindings.createObjectBinding(() ->


                    detailsSearchFilter.get().and(componentSearchFilter.get()).and(sourceFilter.get()),

            detailsSearchFilter, componentSearchFilter, sourceFilter

    ));

对于其他两个ListView过滤器,我正在考虑做这样的事情:


private final static String[] sources = new String[]{"ECS","IISNode","PrismWebServer"};

ListView<String> sourceList = new ListView<>();

ObservableList sourceItems = FXCollections.observableArrayList(sources);


sourceList.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

sourceList.getItems().addAll(sources);

ListView<String> selected = new ListView<>();


sourceList.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {

        selected.setItems(sourceList.getSelectionModel().getSelectedItems());

        System.out.println(Arrays.toString(selected.getItems().toArray()));

    });

因此该selected列表现在包括当前选择的所有值。如何将sourceFilter与selected列表的所有值绑定?


我正在考虑遍历列表中的每个值并以这种方式绑定:


  sourceFilter.bind(Bindings.createObjectBinding(() ->


            log -> log.getSource().toLowerCase().contains(selected.getItems().get(i).toLowerCase()),

                sourceList.selectionModelProperty()


    ));

但这似乎不是很优雅,我不确定我是否selectionModelProperty以正确的方式使用。


温温酱
浏览 287回答 1
1回答

郎朗坤

的selectionModelProperty时候才会触发改变selectionModel被替换这通常不会发生。依赖关系应该是sourceList.getSelectionModel().getSelectedItems().此外,按照我的理解,您应该查询Log'ssource是否在所选项目中,而不是该source字符串是否在所选项目列表中的某个位置包含字符串的某些部分。另请注意,ListView应避免仅使用 a来存储数据,对于大型列表,contains对 aSet而不是 a进行检查效率更高List。你可以使用这样的代码:ObjectBinding<Predicate<Log>> binding = new ObjectBinding<Predicate<String>>() {&nbsp; &nbsp; private final Set<String> strings = new HashSet<>();&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; sourceList.getSelectionModel().getSelectedItems().addListener(new ListChangeListener<String>() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void onChanged(ListChangeListener.Change<? extends String> c) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; boolean changed = false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // modify set on selection change&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (c.next()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (c.wasRemoved()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; changed = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c.getRemoved().stream().map(String::toLowerCase).forEach(strings::remove);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (c.wasAdded()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; changed = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c.getAddedSubList().stream().map(String::toLowerCase).forEach(strings::add);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (changed) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; invalidate();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; protected Predicate<Log> computeValue() {&nbsp; &nbsp; &nbsp; &nbsp; return log -> strings.contains(log.getSource().toLowerCase());&nbsp; &nbsp; }};sourceFilter.bind(binding);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python