从ListView中删除项奇怪的行为
我正在使用ListView。向ListView添加一个新项目很容易,但是如何删除一个呢 我通过以下方式构建我的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++) {
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);
}
}
}