Java 约束性<;谓词<;MyObject>&燃气轮机;到ListView(使用SelectionMode.MULTIPLE)
我试图在可以选择多个项目的Java 约束性<;谓词<;MyObject>&燃气轮机;到ListView(使用SelectionMode.MULTIPLE),java,javafx,data-binding,Java,Javafx,Data Binding,我试图在可以选择多个项目的列表视图和对象属性之间进行绑定。选择项目时,我希望相应地过滤TableView列: 使用两个较低的过滤器(组件、详细信息),我按如下方式进行绑定: ObjectProperty<Predicate<Log>> detailsSearchFilter = new SimpleObjectProperty<>(); TextField detailsSearchField = new TextField(); detailsSearch
列表视图
和对象属性
之间进行绑定。选择项目时,我希望相应地过滤TableView
列:
使用两个较低的过滤器(组件、详细信息),我按如下方式进行绑定:
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()
));
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()));
});
ObjectBinding<Predicate<Log>> binding = new ObjectBinding<Predicate<String>>() {
private final Set<String> strings = new HashSet<>();
{
sourceList.getSelectionModel().getSelectedItems().addListener(new ListChangeListener<String>() {
@Override
public void onChanged(ListChangeListener.Change<? extends String> c) {
boolean changed = false;
// modify set on selection change
while (c.next()) {
if (c.wasRemoved()) {
changed = true;
c.getRemoved().stream().map(String::toLowerCase).forEach(strings::remove);
}
if (c.wasAdded()) {
changed = true;
c.getAddedSubList().stream().map(String::toLowerCase).forEach(strings::add);
}
}
if (changed) {
invalidate();
}
}
});
}
@Override
protected Predicate<Log> computeValue() {
return log -> strings.contains(log.getSource().toLowerCase());
}
};
sourceFilter.bind(binding);
对于另外两个ListView
过滤器,我正在考虑这样做:
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()
));
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()));
});
ObjectBinding<Predicate<Log>> binding = new ObjectBinding<Predicate<String>>() {
private final Set<String> strings = new HashSet<>();
{
sourceList.getSelectionModel().getSelectedItems().addListener(new ListChangeListener<String>() {
@Override
public void onChanged(ListChangeListener.Change<? extends String> c) {
boolean changed = false;
// modify set on selection change
while (c.next()) {
if (c.wasRemoved()) {
changed = true;
c.getRemoved().stream().map(String::toLowerCase).forEach(strings::remove);
}
if (c.wasAdded()) {
changed = true;
c.getAddedSubList().stream().map(String::toLowerCase).forEach(strings::add);
}
}
if (changed) {
invalidate();
}
}
});
}
@Override
protected Predicate<Log> computeValue() {
return log -> strings.contains(log.getSource().toLowerCase());
}
};
sourceFilter.bind(binding);
但它似乎不是很优雅,我不确定我是否正确使用了
selectionModel属性。只有在替换selectionModel
时才会触发更改,而这通常不会发生。依赖项应该是sourceList.getSelectionModel().getSelectedItems()
此外,根据我的理解,您应该查询日志
的源
是否在所选项目中,而不是源
字符串是否在所选项目列表的某个位置包含字符串的某个部分
还请注意,应避免仅使用列表视图
来存储数据,对于大型列表,在集合
上执行包含
检查要比在列表
上进行检查有效得多
您可以使用如下代码:
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()
));
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()));
});
ObjectBinding<Predicate<Log>> binding = new ObjectBinding<Predicate<String>>() {
private final Set<String> strings = new HashSet<>();
{
sourceList.getSelectionModel().getSelectedItems().addListener(new ListChangeListener<String>() {
@Override
public void onChanged(ListChangeListener.Change<? extends String> c) {
boolean changed = false;
// modify set on selection change
while (c.next()) {
if (c.wasRemoved()) {
changed = true;
c.getRemoved().stream().map(String::toLowerCase).forEach(strings::remove);
}
if (c.wasAdded()) {
changed = true;
c.getAddedSubList().stream().map(String::toLowerCase).forEach(strings::add);
}
}
if (changed) {
invalidate();
}
}
});
}
@Override
protected Predicate<Log> computeValue() {
return log -> strings.contains(log.getSource().toLowerCase());
}
};
sourceFilter.bind(binding);
ObjectBinding=newobjectbinding(){
私有最终集字符串=新HashSet();
{
sourceList.getSelectionModel().getSelectedItems().addListener(新ListChangeListener()){
@凌驾
更改后的公共void(ListChangeListener.Change