ListView using custom cell factory doesn't update after items deleted

后端 未结 2 1555
南笙
南笙 2020-12-16 22:48

I\'m learning JavaFX and i wanted to create a cell factory which is working properly until i want to delete a row from my ListView:



        
相关标签:
2条回答
  • 2020-12-16 23:19

    According to the Java doc of Cell updateItem method, there is slightly different recomended usage than the accepted one:

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

    The difference is in the usage of parameter empty. But the sollution from @Adam should work correctly in major cases too.

    0 讨论(0)
  • 2020-12-16 23:35

    Try changing to the following, This is required as JavaFX reuses the list cells, so the updateItem() needs to blank unused ones too when passed null

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

    Full 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<Car> plateList = new ListView<Car>();
            plateList.setCellFactory(new Callback<ListView<Car>, ListCell<Car>>() {
    
                @Override
                public ListCell<Car> call(ListView<Car> param) {
                    ListCell<Car> cell = new ListCell<Car>() {
    
                        @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<Car> 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<Car> t = plateList.getItems();
                plateList.setItems(t);
            });
    
            plateList.setItems(sample);
            arg0.setScene(new Scene(new VBox(plateList, delete)));
            arg0.show();
        }
    }
    
    0 讨论(0)
提交回复
热议问题