JavaFX:FilteredList最后一项更新错误

时间:2015-12-13 10:59:12

标签: java listview javafx

我与ListView绑定ObservableList<Item>。另外,我有一个ComboBox我想在其中仅显示ListView中选择的项目(意味着activeProperty的{​​{1}}设置为Item })。为实现此目的,我将trueComboBox绑定,根据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();
    }
}}

0 个答案:

没有答案