Reputation: 79
I'm trying to make a Brick Breaker game, but I'm getting a ConcurrentModificationException
in this area.
I use Netbeans. This is in my BlockBreakerPanel
class and it has the main information for getting my code to actually work properly. Exception location has ** around it.
I don't know why I get this exception and I'm wondering if it has to do with the Arraylist
and if I somehow implemented it wrong.
public class BlockBreakerPanel extends JPanel implements KeyListener {
ArrayList<Block> blocks;
Block ball;
Block paddle;
JFrame mainFrame, startScreen;
Thread thread;
void reset() {
blocks = new ArrayList<Block>();
ball = new Block(237, 435, 35, 25, "ball.png");
paddle = new Block(175, 480, 150, 25, "paddle.png");
for (int i = 0; i < 8; i++) {
blocks.add(new Block((i * 60 + 2), 0, 60, 25, "blue.png"));
}
for (int i = 0; i < 8; i++) {
blocks.add(new Block((i * 60 + 2), 25, 60, 25, "green.png"));
}
for (int i = 0; i < 8; i++) {
blocks.add(new Block((i * 60 + 2), 50, 60, 25, "yellow.png"));
}
for (int i = 0; i < 8; i++) {
blocks.add(new Block((i * 60 + 2), 75, 60, 25, "red.png"));
}
addKeyListener(this);
setFocusable(true);
}
BlockBreakerPanel(JFrame frame, JFrame startScreen) {
this.mainFrame = frame;
this.startScreen = startScreen;
reset();
thread = new Thread(() -> {
while (true) {
update();
try {
Thread.sleep(10);
} catch (InterruptedException err) {
err.printStackTrace();
}
}
});
thread.start();
}
**public void paintComponent(Graphics g) {
super.paintComponent(g);
blocks.forEach(block -> {
block.draw(g, this);
});
ball.draw(g, this);
paddle.draw(g, this);
}**
public void update() {
ball.x += ball.movX;
if (ball.x > (getWidth() - 25) || ball.x < 0) {
ball.movX *= -1;
}
if (ball.y < 0 || ball.intersects(paddle)) {
ball.movY *= -1;
}
ball.y += ball.movY;
if (ball.y > getHeight()) {
thread = null;
reset();
mainFrame.setVisible(false);
startScreen.setVisible(true);
}
blocks.forEach(block -> {
if (ball.intersects(block) && !block.destroyed) {
block.destroyed = true;
ball.movY *= -1;
}
});
repaint();
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT && paddle.x < (getWidth() - paddle.width)) {
paddle.x += 15;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT && paddle.x > 0) {
paddle.x -= 15;
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
Upvotes: 2
Views: 79
Reputation: 53694
I suspect that the crux of your problem is that you are using a separate thread to interact with GUI elements. That is a no-no in Java, the AWT/Swing UI elements are not thread-safe. You must do all UI interactions on the event dispatch thread. Generally, this is very straightforward for normal interactive situations. In your case, however, you need a UI task to happen periodically. When you need a periodic update to UI elements in Java, you should use a swing timer. This will ensure that your updates happen in a UI thread-safe manner.
Upvotes: 1