JavaFX ConcurrentModificationException с GridPane.get...Index()
Мне нужно отредактировать содержимое chunkLarge
поэтому я пытаюсь переместить их в дубликат GridPane:
chunkLarge2 = new GridPane();
for (Node n : chunkLarge.getChildren()) {
chunkLarge2.add(n, GridPane.getColumnIndex(n), GridPane.getRowIndex(n));
}
Это кидает ConcurrentModificationException
, Я думаю, что это из-за GridPane.get...Index(n)
,
Я немного поискал в интернете и нашел несколько вещей. Во-первых, я мог использовать итератор для циклического перемещения по спискам, но я не уверен, как его применить здесь. Следующим было то, что я мог попробовать .getChildrenUnmodified()
вместо вашего стандарта .getChildren()
, но это только что бросил NoSuchElementException
вместо.
Есть идеи?
2 ответа
ConcurrentModificationException
брошен, потому что вы перебираете chunkLarge
список детей и удаление элементов из него одновременно.
Удаление происходит, когда вы пытаетесь добавить дочерний узел в chunkLarge2
- узел javafx может иметь только одного родителя, поэтому дочерний узел n
удаляется из 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);
}
Или без итератора:
// transfer children from chunkLarge to chunkLarge2
chunkLarge2.getChildren().addAll(chunkLarge.getChildren());
// note that you're not iterating over chunkLarge's children list
// (addAll method will make a copy and work with it),
// so it's safe to let the children be automatically deleted
Экземпляр узла может использоваться только как дочерний элемент одного родителя или как корень одной сцены. Если вы добавляете узел в качестве потомка нового родителя, он удаляется из старого родителя. Это означает, что ваш цикл фактически делает то же самое, что и следующий цикл (установка индексов сетки не требуется, поскольку вы хотите сохранить эти индексы):
for (Node n : chunkLarge.getChildren()) {
chunkLarge.getChildren().remove(n);
chunkLarge2.getChildren().add(n);
}
Поскольку вы изменяете список, по которому вы перебираете, другими способами, кроме Iterator
вы получаете ConcurrentModificationException
,
Вам нужно создать новые узлы для второго GridPane
для отображения узлов в обоих GridPane
s.