从ListView中删除项奇怪的行为

从ListView中删除项奇怪的行为,listview,javafx,Listview,Javafx,我正在使用ListView。向ListView添加一个新项目很容易,但是如何删除一个呢 我通过以下方式构建我的ListView: public Node buildListView() { ObservableList<String> myList = FXCollections.observableArrayList(); int counter = 0; for(int i=0; i<10; i++) {

我正在使用ListView。向ListView添加一个新项目很容易,但是如何删除一个呢

我通过以下方式构建我的ListView:

public Node buildListView() {
        ObservableList<String> myList =  FXCollections.observableArrayList();
        int counter = 0;
        for(int i=0; i<10; i++) {
            myList.add("Number " + new Integer(i+1).toString());
        }
        ListView<String> listView = new ListView<>();
        listView.setItems(myList);

        listView.setCellFactory(new Callback<ListView<String>, ListCell<String>> (){
            @Override
        public ListCell<String> call(ListView<String> arg0) {
                return new listcells.ListcellY(listView);

            }

        });
        return listView;
}
public节点buildListView(){
ObservableList myList=FXCollections.observableArrayList();
int计数器=0;
对于(int i=0;i{
System.out.println(“单击:+项”);
对于(字符串s:listView.getItems()){
系统输出打印项次(“+s”);
}
listView.getItems().remove(item);//这里我从列表中删除了该项。
System.out.println(“列表大小:+listView.getItems().size());
});
设置图形(标签);
} 
}
}
虽然这段代码通过从ObservableList中删除每个单击的项来工作,但listView的行为却很奇怪。每次单击标签时,它都会成功地从我的ListView中消失,但是会在该ListView的末尾自动添加一个新项目,显示最后一个标签文本的名称(但它不是可单击的标签)。 它不断重复,直到我的观察列表为空。那么ListView不会显示任何内容

我只是希望我点击的标签消失,而不会在我的树视图中得到任何新的“视觉副本”。如果将索引参数设置为ObservableList的原始大小,则ListView将复制最后一个元素,直到获得正确数量的元素。但我不明白这是怎么做到的


我能做什么,首先发生了什么事?

好吧,似乎写你的问题能让你的大脑工作得更好!我有正确的直觉: 在扩展的ListCell类中,我检查被重写的update方法中的项是否为null。但是当它为null时,我不会处理这种情况,在这种情况下,我必须将图形设置为null!我仍然不明白到底为什么,但它是有效的! 以下是更新的类:

public class ListcellY extends ListCell<String> {
    Label label;
    HBox hbox;
    ListView<String> listView;

    public ListcellY( ListView<String> listView ) {
        super();
        this.listView = listView; // Here I pass the reference to my list. Is it a gd way to do that? 
    }
    @Override
    protected void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);
        if(item!=null){
            label = new Label(item);

            label.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> { 
                System.out.println("CLicked on : " + item);
                for(String s : listView.getItems()) {
                    System.out.println("  " + s);
                }

                listView.getItems().remove(item);  // Here I remove the item form my list.
                System.out.println("list size : " + listView.getItems().size());
            });
            setGraphic(label);

        }
        else {
            setGraphics(null);
        } 

    }
}
公共类ListcellY扩展了ListCell{
标签;
HBox-HBox;
列表视图列表视图;
公共ListcellY(ListView ListView){
超级();
this.listView=listView;//我在这里传递对列表的引用。这是一种gd方法吗?
}
@凌驾
受保护的void updateItem(字符串项,布尔值为空){
super.updateItem(项,空);
如果(项!=null){
标签=新标签(项目);
label.addEventHandler(MouseEvent.MOUSE_单击,e->{
System.out.println(“单击:+项”);
对于(字符串s:listView.getItems()){
系统输出打印项次(“+s”);
}
listView.getItems().remove(item);//这里我从列表中删除了该项。
System.out.println(“列表大小:+listView.getItems().size());
});
设置图形(标签);
}
否则{
设置图形(空);
} 
}
}

是否有任何原因导致您不通过将changelistener附加到list.getSelectionModel().selectedItemProperty()来删除项目?是的!这是因为我对javafx非常陌生,不熟悉这种做法。我怎么能做到呢?“我仍然不知道确切的原因”:假设你的清单上有五个项目;五个显示在单元格中。当您删除一个单元格时,显然现在有四个项目,但您仍然可以看到所有五个单元格(可能还有一些其他单元格)。其中一个单元格将通过使用参数
updateItem(null,true)
调用其
updateItem
方法进行更新。您需要该单元格来删除它显示的图形。如果没有足够的项目,ListView将使用空单元格填充视口。调用
updateItem(/*item=*/null,/*empty=*/true)
后,该单元格被视为空的,用于填充剩余区域。感谢您的回复。对于空单元格,我得到了它,但是如何解释不将图形设置为null会使这些空单元格显示最后一项的内容这一事实呢?这里我只检查(item==null)。布尔值“empty”能为我带来什么信息?如果您不将图形设置为
null
,单元格将在不为空的情况下继续显示以前的图形。布尔标志
empty
用于区分
null
是项的有效值时的情况。有
null
项是不好的做法,但这并不是禁止的。
public class ListcellY extends ListCell<String> {
    Label label;
    HBox hbox;
    ListView<String> listView;

    public ListcellY( ListView<String> listView ) {
        super();
        this.listView = listView; // Here I pass the reference to my list. Is it a gd way to do that? 
    }
    @Override
    protected void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);
        if(item!=null){
            label = new Label(item);

            label.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> { 
                System.out.println("CLicked on : " + item);
                for(String s : listView.getItems()) {
                    System.out.println("  " + s);
                }

                listView.getItems().remove(item);  // Here I remove the item form my list.
                System.out.println("list size : " + listView.getItems().size());
            });
            setGraphic(label);

        }
        else {
            setGraphics(null);
        } 

    }
}