使用带有侦听器的 getSelectionModel().selectedItemProperty() 从historyTableView 获取行并使用其存储的Purchase 项目将信息添加到purchaseTableView 时,遇到ConcurrentModificationException。仅当从历史表视图中选择非最后一行的任何行时,才会出现此异常。
public void refreshStock() {
historyTableView.setItems(FXCollections.observableList(dao.getPurchaseList()));
historyTableView.refresh();
}
@Override
@FXML
public void initialize(URL location, ResourceBundle resources) {
historyTableView.refresh();
purchaseTableView.refresh();
// error on line below?
historyTableView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
log.debug("Clicked on: " + newValue.toString());
purchaseTableView.setItems(FXCollections.observableList(newValue.getSoldItemListStream()));
historyTableView.getSelectionModel().clearSelection();
purchaseTableView.refresh();
});
}
异常如下,当 log.debug 尝试 newValue.toString() 时抛出(据我所知)
Exception in thread "JavaFX Application Thread" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1415)
at java.base/java.util.ArrayList$SubList.size(ArrayList.java:1155)
at ee.ut.math.tvt.salessystem.dataobjects.Purchase.toString(Purchase.java:66)
at ee.ut.math.tvt.salessystem.ui.controllers.HistoryController.lambda$initialize$0(HistoryController.java:76)
at javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:181)
at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.base/javafx.beans.property.ReadOnlyObjectPropertyBase.fireValueChangedEvent(ReadOnlyObjectPropertyBase.java:80)
at javafx.base/javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:102)
at javafx.base/javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:113)
at javafx.base/javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147)
at javafx.controls/javafx.scene.control.SelectionModel.setSelectedItem(SelectionModel.java:105)
at javafx.controls/javafx.scene.control.MultipleSelectionModelBase.lambda$new$0(MultipleSelectionModelBase.java:67)
at javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:136)
at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
...
不同的监听器,创建 DAO 列表的 Collections.copy() 并在不同时刻清除/刷新选择没有区别。主要我想知道在这种情况下如何创建此异常,以及为什么最后一行不会抛出此异常(据我所知,单击最后一行会更改purchaseTableView,这不会发生,并且抛出异常其他历史表视图行)
你有一些清单
a
。您已经创建了它的一个子列表,并在整个地方使用这个子列表(具体来说,toString
的某个实例的Purchase
,无论它是什么,都有一个。然后您可以直接修改a
。这会使所有内容无效)您在修改之前所做的子列表 - 与它的任何交互,甚至询问其 size()
,都会给您带来此异常。不要分发您打算更改的内容的子列表。制作副本(new ArrayList<>(someList.subList(start, end))
,而不是 someList.subList(start, end)
.