首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaFX在FlowPane儿童上使用FilteredList

JavaFX在FlowPane儿童上使用FilteredList
EN

Stack Overflow用户
提问于 2020-06-16 10:17:47
回答 2查看 429关注 0票数 0

Im有FlowPane,它包含各种元素。我希望能够使用FilteredList<MyElement>,以便用户能够进行搜索,但是FlowPane只有getChildren()方法。如何过滤FlowPane中显示的节点

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-16 12:15:06

假设MyElementNode的子类,您可以简单地

代码语言:javascript
复制
FlowPane flowPane = ... ;
FilteredList<MyElement> someFilteredList = ... ;
Bindings.bindContent(flowPane.getChildren(), someFilteredList)

这里是一个非常快速和肮脏的例子,它创建100个以整数值作为文本的标签。文本字段更新筛选列表中的筛选器,以便只显示其值为输入值的倍数的标签。

代码语言:javascript
复制
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;


/**
 * JavaFX App
 */
public class App extends Application {

    @Override
    public void start(Stage stage) {

        FlowPane flow = new FlowPane();

        ObservableList<Label> labels = FXCollections.observableArrayList();
        for (int i = 1 ; i <= 100 ; i++) {
            Label label = new Label(Integer.toString(i));
            label.setPadding(new Insets(1,5,0,0));
            labels.add(label);
        }

        FilteredList<Label> filtered = new FilteredList<>(labels);

        TextField filter = new TextField();
        filter.setTextFormatter(new TextFormatter<String>(change -> 
            change.getControlNewText().matches("[0-9]*") ? change : null
        ));

        filter.textProperty().addListener((obs, oldFilter, newFilter) -> {
            String f = newFilter.trim();
            if (f.isEmpty()) {
                filtered.setPredicate(l -> true);
            } else {
                Integer divisor = Integer.parseInt(f);
                filtered.setPredicate(label -> Integer.parseInt(label.getText()) % divisor == 0);
            }
        });

        Bindings.bindContent(flow.getChildren(), filtered);

        BorderPane root = new BorderPane(flow);
        root.setTop(filter);

        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }

}
票数 2
EN

Stack Overflow用户

发布于 2020-06-16 12:01:15

您只能操作FlowPane子列表的项目。无法设置要处理控制子控件的列表的任何实现。

正如@James_D所提到的,您可以使用Bindings.bindContent。只有当筛选器更改时才更新谓词(或者您可以将其编辑为bind)。

代码语言:javascript
复制
public class Controller {

    @FXML
    FlowPane flowPane;
    @FXML
    ComboBox<Class> filterCbx;

    FilteredList<Node> filteredList;

    @FXML
    void initialize() {
        // Set of all the controls classes in flow pane children classes
        ObservableList<Node> flowChildren = flowPane.getChildren();

        filterCbx.getItems().addAll(flowChildren
                .stream()
                .map(Node::getClass)
                .collect(Collectors.toSet()));
        // Node will be treated as show all children functionality
        filterCbx.getItems().add(Node.class);
        filterCbx.setOnAction(this::onFilterChanged);

        // Source need to be an another FXCollection, cant use directly flowChildren
        filteredList = new FilteredList<Node>(FXCollections.observableArrayList(flowChildren));
        Bindings.bindContent(flowChildren, filteredList);
    }

    private void onFilterChanged(ActionEvent actionEvent) {
        ObservableList<Node> flowChildren = flowPane.getChildren();
        Class selectedItem = filterCbx.getSelectionModel().getSelectedItem();
        // Update predicate on selection change
        filteredList.setPredicate(n -> Node.class.equals(selectedItem) || n.getClass().equals(selectedItem));
    }
}

意见如下:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
      prefHeight="400.0"
      prefWidth="600.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1"
      fx:controller="so.q62406187.Controller">
    <ComboBox fx:id="filterCbx"/>
    <FlowPane fx:id="flowPane">
        <Pane prefHeight="200.0" prefWidth="200.0"/>
        <Button mnemonicParsing="false" text="Button"/>
        <Label text="Label"/>
        <ComboBox prefWidth="150.0"/>
        <HBox prefHeight="100.0" prefWidth="200.0"/>
        <CheckBox mnemonicParsing="false" text="CheckBox"/>
        <VBox prefHeight="200.0" prefWidth="100.0"/>
        <CheckBox mnemonicParsing="false" text="CheckBox"/>
        <Label text="Label"/>
    </FlowPane>
</VBox>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62406187

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档