Java 从stage和ArrayList中删除元素时的ConcurrentModification异常
我正在试验JavaFX动画。我在屏幕上的任意位置生成矩形,它们随着我定义的球移动。每当屏幕左侧出现矩形时,我都会将其从场景和包含它的ArrayList中删除。这是我的密码:Java 从stage和ArrayList中删除元素时的ConcurrentModification异常,java,javafx,arraylist,concurrentmodification,Java,Javafx,Arraylist,Concurrentmodification,我正在试验JavaFX动画。我在屏幕上的任意位置生成矩形,它们随着我定义的球移动。每当屏幕左侧出现矩形时,我都会将其从场景和包含它的ArrayList中删除。这是我的密码: package UI; import javafx.animation.AnimationTimer; import javafx.fxml.FXML; import javafx.scene.control.Label; import javafx.scene.layout.AnchorPane; import java
package UI;
import javafx.animation.AnimationTimer;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Random;
public class UIController extends AnimationTimer {
@FXML
private Label fpsLbl;
@FXML
private Circle moveMeCircle;
@FXML
private AnchorPane root;
private ArrayList<Rectangle> rectangles = new ArrayList<>();
int fps = 0;
int deltaX = 5;
int deltaY = 0;
long start = 0;
@FXML
public void initialize() {
super.start();
}
@Override
public void handle(long l) {
if (start == 0) {
start = l;
} else {
if (l >= start + 1000000000) {
fpsLbl.setText("FPS: " + ((l - start) / 1000000000) * fps);
System.out.println(fps);
renderShape();
if (fps < 59) {
System.out.println(rectangles.size());
}
fps = 0;
start = l;
}
}
updateElements();
fps++;
}
private void renderShape() {
try{
for (Rectangle rectangle : rectangles) {
if (rectangle.getX()+rectangle.getWidth() < 0) {//this is the part
rectangles.remove(rectangle); //that causes the
root.getChildren().remove(rectangle); //exception
}
}}
catch(ConcurrentModificationException e){
e.printStackTrace();
}
Random rand = new Random();
int posX = rand.nextInt(1280);
int posY = rand.nextInt(720);
rectangles.add(new Rectangle(posX, posY, 100, 50));
for (Rectangle rect : rectangles) {
if (!root.getChildren().contains(rect)) {
rect.setWidth(rand.nextInt(300 + 650));
root.getChildren().add(rect);
}
}
}
private void updateElements() {
if ((moveMeCircle.getCenterX() >= 1280 && deltaX > 0) || (moveMeCircle.getCenterX() <= 0 && deltaX < 0)) {
deltaX = deltaX * -1;
}
if ((moveMeCircle.getCenterY() <= 0 && deltaY < 0) || (moveMeCircle.getCenterY() >= 720 && deltaY > 0)) {
deltaY = deltaY * -1;
}
for (Rectangle rect : rectangles) {
rect.setX(rect.getX() + deltaX);
rect.setY(rect.getY() + deltaY);
}
moveMeCircle.setCenterX(moveMeCircle.getCenterX() + deltaX);
moveMeCircle.setCenterY(moveMeCircle.getCenterY() + deltaY);
}
}
还有FXML文件,虽然它基本上是不相关的,但我只定义了锚烷和正在移动的球:
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.Circle?>
<?import javafx.scene.shape.Rectangle?>
<?import javafx.scene.control.Label?>
<AnchorPane fx:id="root" maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity" prefHeight="720.0"
prefWidth="1280.0" scaleShape="false" style="-fx-background-color:
#a4a4bd;"stylesheets="@css/main.css"
xmlns="http://javafx.com/javafx/10"
xmlns:fx="http://javafx.com/fxml/1"fx:controller="UI.UIController">
<children>
<Label fx:id="fpsLbl" prefWidth="200" AnchorPane.leftAnchor="0"
style="-fx-text-fill: blueviolet; -fx-font:20px 'Agency FB'"/>
<Circle radius="10" centerX="50" centerY="50" fx:id="moveMeCircle"/>
</children>
</AnchorPane>
与其他有关此异常和从ArrayList中删除的问题相同。使用迭代器来解决这个问题。有关详细信息,请参见类似问题的答案。@HovercraftFullOfEels那么是arraylist导致了这种情况?我假设这是因为我同时从arraylist和root的子元素中删除。谢谢如果您在遍历列表时从列表中删除,迭代器会变得混乱(它无法轻松跟踪哪个元素应该是“当前”元素)。@James_D Ah我明白了,所以我应该实现一个迭代器,而不是for:each?参见链接问题。。。
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.Circle?>
<?import javafx.scene.shape.Rectangle?>
<?import javafx.scene.control.Label?>
<AnchorPane fx:id="root" maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity" prefHeight="720.0"
prefWidth="1280.0" scaleShape="false" style="-fx-background-color:
#a4a4bd;"stylesheets="@css/main.css"
xmlns="http://javafx.com/javafx/10"
xmlns:fx="http://javafx.com/fxml/1"fx:controller="UI.UIController">
<children>
<Label fx:id="fpsLbl" prefWidth="200" AnchorPane.leftAnchor="0"
style="-fx-text-fill: blueviolet; -fx-font:20px 'Agency FB'"/>
<Circle radius="10" centerX="50" centerY="50" fx:id="moveMeCircle"/>
</children>
</AnchorPane>