带有GridPane.get ... Index()的JavaFX ConcurrentModificationException

时间:2018-10-13 17:11:42

标签: javafx java-8

我需要编辑chunkLarge的内容,因此我试图将它们移动到重复的GridPane中:

chunkLarge2 = new GridPane();
for (Node n : chunkLarge.getChildren()) {
    chunkLarge2.add(n, GridPane.getColumnIndex(n), GridPane.getRowIndex(n));
}

这将引发ConcurrentModificationException。我认为是因为GridPane.get...Index(n)

我做了一些在线搜索,发现了一些东西。 一个是我可以使用Iterator在列表之间循环,但是我不确定如何在这里应用它。 接下来是我可以尝试使用.getChildrenUnmodified()代替您的标准.getChildren(),但这只是扔了NoSuchElementException

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

抛出

ConcurrentModificationException是因为您要遍历chunkLarge的子级列表并同时从中删除元素。

在尝试将子节点添加到chunkLarge2时发生删除-javafx节点只能有一个父节点,因此将子节点n从{{ 1}}的子级列表,然后将其添加到chunkLarge的子级列表中。

正如您已经说过的,您可以使用迭代器来解决问题:

chunkLarge2

或者,没有迭代器:

Iterator<Node> it = chunkLarge.getChildren().iterator();

while (it.hasNext()) {
    // get the next child node
    Node node = it.next();

    int column = GridPane.getColumnIndex(node);
    int row = GridPane.getRowIndex(node);

    // remove method is used to safely remove element from the list          
    it.remove();  

    // node is already removed from chunkLarge, 
    // so you can add it to chunkLarge2 without any problems       
    chunkLarge2.add(node, column, row); 
}

答案 1 :(得分:0)

节点实例只能用作单个父级的子级或单个场景的根。如果将节点添加为新父节点的子节点,则会从旧父节点中删除该节点。这意味着您的循环实际上与以下循环相同(无需设置网格索引,因为您要保留这些索引):

for (Node n : chunkLarge.getChildren()) {
    chunkLarge.getChildren().remove(n);
    chunkLarge2.getChildren().add(n);
}

由于您正在修改要遍历的列表,因此可以使用Iterator以外的其他方式来获取ConcurrentModificationException

您需要为第二个GridPane创建新节点,以同时显示两个GridPane中的节点。