Hi im writting a very simple game. Player can use mouse to move spaceship and every 200ms new beam is shoot. This beam is moved in while(true) loop and when its y is 0 or 400 (bounds of frame) i use break to end the loop (and thread). Every beam has its own thread. There are also stars which move in background. Every of them moves like beams and has its own thread. So as you can see there are often add and removes from arrayLists. Everything works but from time to time I get such errors:
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)
at spacecommander.MainPanel.paintComponent(MainPanel.java:50)
They doesnt make any problems in game but how can I eliminate them? Maybe I should use synchronization or something?
EDIT: HERE IS THE CODE
public class MainPanel extends JPanel {
private Player player = new Player(100, 100, 3, 3);
private Point2D targetPoint = new Point2D.Float(130, 350); //Poczatkowa pozycja statku
private ArrayList<Beam> beams = new ArrayList<Beam>();
private InputMap imap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
private ActionMap amap = getActionMap();
private Random rand = new Random();
public MainPanel() {
setPreferredSize(new Dimension(300, 400));
addMouseMotionListener(new MouseMotionHandler());
//Rozpoczynanie watkow
Thread t = new Thread(new PlayerMoveRunnable());
t.start();
Thread t2 = new Thread(new PlayerShootRunnable());
t2.start();
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.BLACK);
g2.fillRect(0, 0, 300, 400);
//Rysowanie gracza
g2.drawImage(player.getImage(), (int)player.getX(), (int)player.getY(), null);
//Rysowanie pociskow
for (Beam beam : beams) {
g2.drawImage(beam.getImage(), (int)beam.getX(), (int)beam.getY(), null);
}
}
public void makeShortcut(String name, String keys, AbstractAction action) {
imap.put(KeyStroke.getKeyStroke(keys), name);
amap.put(name, action);
}
//Watek dziala caly czas bo gracz i tak caly czas sie rusza
private class PlayerMoveRunnable implements Runnable {
public void run() {
try {
while (true) {
player.moveToPoint(targetPoint);
repaint();
Thread.sleep(15);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//Takze dziala caly czas. Dodaje nowy pocisk co 200ms
private class PlayerShootRunnable implements Runnable {
public void run() {
try {
while (true) {
//Wybranie pocisku do wystrzelenia w zaleznosci od mode gracza
Thread t;
switch (player.getBeamMode()) {
case 1:
t = new Thread(new BeamMoveRunnable(new Beam1(100, 100, 10, 10, 10)));
break;
}
t.start();
Thread.sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private class BeamMoveRunnable implements Runnable {
private Beam beam;
public BeamMoveRunnable(Beam beam) {
this.beam = beam;
}
public void run() {
Beam beam = this.beam;
beams.add(beam);
try {
while (true) {
if (beam.getY() <= 0) {
beams.remove(beam);
break;
}
beam.move();
repaint();
Thread.sleep(20);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private class MouseMotionHandler extends MouseAdapter {
public void mouseMoved(MouseEvent event) {
targetPoint = event.getPoint();
}
}
}