我与ListView
绑定ObservableList<Item>
。另外,我有一个ComboBox
我想在其中仅显示ListView
中选择的项目(意味着activeProperty
的{{1}}设置为Item
})。为实现此目的,我将true
与ComboBox
绑定,根据FilteredList
过滤ObservableList<Item>
。
当activeProperty
中的最后一个Item
被取消选中并再次被选中时,问题就开始了。在控制台中,您可以看到该项目已从ListView
中删除,但在您选择该项目时不会添加该项目。
此外,即使取消选择项目并且您无法在ComboBox中看到它们,您仍然可以看到它们的空间 - 这意味着,当您展开它时,看起来有一些&#39;不可见&# 39;项目
我偶然发现this question并更新了我的Java,但它并没有解决我的问题。我在build 1.8.0_66-b18上运行该程序。
我的MVCE:
FilteredList
输出(您可以看到第一个和第二个元素被删除并添加得很好,第三个元素被删除 - 如果您选择它没有任何反应,如果再次取消选择它会抛出异常):
import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListView;
import javafx.scene.control.cell.CheckBoxListCell;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class FilteredListTest2 extends Application {
ObjectProperty<ObservableList<Item>> baseList;
ObjectProperty<ObservableList<Item>> filteredList;
ListView<Item> listView;
ComboBox<Item> comboBox;
@Override
public void start(Stage primaryStage) {
initialize();
VBox root = new VBox();
root.getChildren().add(listView);
root.getChildren().add(comboBox);
Scene scene = new Scene(root, 160, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
public void initialize() {
listView = new ListView<>();
comboBox = new ComboBox<>();
baseList = new SimpleObjectProperty<>();
baseList.set(FXCollections.observableArrayList(item ->
new Observable[] {item.activeProperty()}));
filteredList = new SimpleObjectProperty<>();
filteredList.set(new FilteredList<>(baseList.get(), item -> item.getActive()));
listView.itemsProperty().bind(baseList);
listView.setCellFactory(CheckBoxListCell.forListView(
Item::activeProperty));
baseList.get().addListener(new ListChangeListener() {
@Override
public void onChanged(ListChangeListener.Change c) {
if (c.next()) {
if (c.wasAdded()) {
System.out.println("base list: added " +
(c.getAddedSubList()));
} else if (c.wasRemoved()) {
System.out.println("base list: removed " +
(c.getRemoved()));
}
}
}});
filteredList.get().addListener(new ListChangeListener() {
@Override
public void onChanged(ListChangeListener.Change c) {
if (c.next()) {
if (c.wasAdded()) {
System.out.println("filtered list: added " +
(c.getAddedSubList()));
} else if (c.wasRemoved()) {
System.out.println("filtered list: removed " +
(c.getRemoved()));
}
}
}});
comboBox.itemsProperty().bind(filteredList);
baseList.get().add(new Item("1"));
baseList.get().add(new Item("2"));
baseList.get().add(new Item("3"));
}
public static class Item {
private final StringProperty name = new SimpleStringProperty();
private final BooleanProperty active = new SimpleBooleanProperty(true);
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 activeProperty() {
return this.active;
}
public final boolean getActive() {
return this.activeProperty().get();
}
public final void setActive(final boolean active) {
this.activeProperty().set(active);
}
@Override
public String toString() {
return "name=" + getName() + ", active=" + getActive();
}
}}