删除项目后,使用自定义单元工厂的 ListView 不会更新
ListView using custom cell factory doesn't update after items deleted
我正在学习 JavaFX,我想创建一个可以正常工作的单元工厂,直到我想从我的 ListView
:
中删除一行
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());
}
}
};
return cell;
}
});
我正在 ListView
中填充一些示例数据:
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));
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<Car> 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<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();
}
}
根据 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 的解决方案在主要情况下也应该可以正常工作。
我正在学习 JavaFX,我想创建一个可以正常工作的单元工厂,直到我想从我的 ListView
:
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());
}
}
};
return cell;
}
});
我正在 ListView
中填充一些示例数据:
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));
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<Car> 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<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();
}
}
根据 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 的解决方案在主要情况下也应该可以正常工作。