使用自定义单元格工厂的ListView在删除项目后不会更新

我正在学习JavaFX,我想创建一个正常工作的单元工厂,直到我想从ListView删除一行:

 plateList.setCellFactory(new Callback<ListView, ListCell>() { @Override public ListCell call(ListView param) { ListCell cell = new ListCell() { @Override protected void updateItem(Car item, boolean empty) { super.updateItem(item, empty); if (item != null) { setText(item.getPlate()); } } }; return cell; } }); 

我正在使用一些示例数据填充ListView

 ObservableList sample = FXCollections.observableArrayList(); sample.add(new Car("123-abc", "opel", "corsa", 5.5)); sample.add(new Car("123-cba", "vw", "passat", 7.5)); plateList.setItems(sample); 

现在我将看到我期望ListView将如下:

  • 123-ABC
  • 123-CBA

如果删除行ex:第一行(123-abc), ListView将如下所示:

  • 123-CBA
  • 123-CBA

这是删除部分:

 @FXML private void deleteBtnAction() { plateList.getItems().remove(plateList.getSelectionModel().getSelectedItem()); ObservableList t = plateList.getItems(); plateList.setItems(t); } 

如果我删除单元工厂,程序按预期工作。 任何帮助是极大的赞赏。

尝试更改为以下内容,这是必需的,因为JavaFX重用了列表单元格,因此updateItem()在传递null时也需要清空未使用的列表单元格

 super.updateItem(item, empty); if (item != null) { setText(item.getPlate()); } else { setText(""); // <== clear the now empty cell. } 

完整的SSCCE

 import javafx.application.Application; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ListCell; import javafx.scene.control.ListView; import javafx.scene.layout.VBox; import javafx.stage.Stage; import javafx.util.Callback; public class JavaFxListView extends Application { private static class Car { private String plate; public Car(String plate, String string2, String string3, double d) { this.plate = plate; } public String getPlate() { return plate; } } public static void main(String[] args) { launch(args); } @Override public void start(Stage arg0) throws Exception { ListView plateList = new ListView(); plateList.setCellFactory(new Callback, ListCell>() { @Override public ListCell call(ListView param) { ListCell cell = new ListCell() { @Override protected void updateItem(Car item, boolean empty) { super.updateItem(item, empty); if (item != null) { setText(item.getPlate()); } else { setText(""); } } }; return cell; } }); Button delete = new Button("Delete"); ObservableList sample = FXCollections.observableArrayList(); sample.add(new Car("123-abc", "opel", "corsa", 5.5)); sample.add(new Car("123-cba", "vw", "passat", 7.5)); delete.setOnAction((e) -> { plateList.getItems().remove(plateList.getSelectionModel().getSelectedItem()); ObservableList t = plateList.getItems(); plateList.setItems(t); }); plateList.setItems(sample); arg0.setScene(new Scene(new VBox(plateList, delete))); arg0.show(); } } 

根据Cell updateItem方法的Java文档,推荐的用法与接受的用法略有不同:

  protected void updateItem(T item, boolean empty) { super.updateItem(item, empty); if (empty || item == null) { setText(null); setGraphic(null); } else { setText(item.toString()); } } 

不同之处在于参数为empty的用法。 但@Adam的溶剂也应该在重大案例中正常工作。