我的应用程序中有changeTableView
方法。该方法使用一组新内容重新加载TableView
。它的目的是处理分页。它将重置一个表并用另一个页面的行加载它。
public void changeTableView(int index, int limit) {
System.out.println("index: " + index + ", limit: " + limit);
int newIndex = index * limit;
List<Product> productSubList = allProducts.subList(Math.min(newIndex, allProducts.size()), Math.min(allProducts.size(), newIndex + limit));
productListTable.getItems().clear();
productListTable.setItems(null);
ObservableList<Product> products = FXCollections.observableList(productSubList);
productListTable.setItems(products);
}
首次使用index = 0
初始化时调用该方法,然后通过以下方法调用该方法。
pagination.currentPageIndexProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, Number newValue) {
changeTableView(newValue.intValue(), limit.get());
System.out.println("new value: " + newValue.intValue() + ", limit: " + limit.get());
}
});
当用户请求不同的页面时,会调用 changed
方法。
但是,更改页面会引发以下异常。
java.util.ConcurrentModificationException
at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1169)
at java.util.ArrayList$SubList.size(ArrayList.java:998)
at com.sun.javafx.collections.ObservableListWrapper.size(ObservableListWrapper.java:335)
at com.sun.javafx.scene.control.skin.TableViewSkin.getItemCount(TableViewSkin.java:325)
at com.sun.javafx.scene.control.skin.TableViewSkin.updatePlaceholderRegionVisibility(TableViewSkin.java:561)
at com.sun.javafx.scene.control.skin.TableViewSkin.updateRowCount(TableViewSkin.java:623)
at com.sun.javafx.scene.control.skin.TableViewSkin.layoutChildren(TableViewSkin.java:426)
at javafx.scene.Parent.layout(Parent.java:1018)
at javafx.scene.Parent.layout(Parent.java:1028)
at javafx.scene.Parent.layout(Parent.java:1028)
at javafx.scene.Scene.layoutDirtyRoots(Scene.java:524)
at javafx.scene.Scene.doLayoutPass(Scene.java:495)
at javafx.scene.Scene.access$3900(Scene.java:173)
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2205)
at com.sun.javafx.tk.Toolkit$5.run(Toolkit.java:363)
at com.sun.javafx.tk.Toolkit$5.run(Toolkit.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:361)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:384)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:463)
at com.sun.javafx.tk.quantum.QuantumToolkit$9.run(QuantumToolkit.java:332)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76)
我怀疑这里的罪魁祸首是java.util.ConcurrentModificationException at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1169)
如何在不影响应用程序性能的情况下阻止这种情况发生?
答案 0 :(得分:3)
根据文档,sublist()
会返回view
的{{1}}。由于它是List
,因此保持它并多次迭代是不安全的。
相反,您应该在传递之前复制子列表。