-1

Welcome, i am programming a simple RPG game in java applet. It is getting more and more complicated and many errors are thrown to my face. Today i have problem with .remove(); method.

Exception in thread "AWT-EventQueue-1" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.remove(Unknown Source)
    at rpg.main.paint(main.java:365)
    at rpg.main.update(main.java:331)
    at sun.awt.RepaintArea.updateComponent(Unknown Source)
    at sun.awt.RepaintArea.paint(Unknown Source)
    at sun.awt.windows.WComponentPeer.handleEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

That's how error log looks like. Code of program:

main.java

As we can see error appears in paint methid in the end of program, but i dont know maybe it is caused by wrong initiation in the beginning of program?

public void initLocatables()
public void initLocatables2()

And i have to admit that they are called in main while loop in run method. These is place where error apears, and below in comment i have included previous method that has also thrown error, both in remove();

for (Iterator i = locatablesArray.listIterator(); i.hasNext();) {
               Locatable l = (Locatable) i.next(); 
               l.draw(g);
               i.remove();
            }
/*while(itrLocatables.hasNext())
{
    Locatable l = itrLocatables.next();
    l.draw(g);
    l.remove();
}*/

Thank you for any reply.

Jonas
  • 121,568
  • 97
  • 310
  • 388
Tom Skiba
  • 72
  • 1
  • 2
  • 7

3 Answers3

1

You cannot remove objects from a list/map while you are iterating them. That's the cause of the ConcurrentModificationException

       i.remove();

If you will draw all the Locatable elements, and then clear the collection, maybe you should draw them all first, and then clear the collection, instead of removing them on the fly.

for (Iterator i = locatablesArray.listIterator(); i.hasNext();) {
               Locatable l = (Locatable) i.next(); 
               l.draw(g);
}

// Clear everything from the list
locatablesArray.clear();
Cristian Meneses
  • 4,013
  • 17
  • 32
  • `Iterator.remove()` is used to remove item from Collection your are iterating using `Iterator`. for your comment the right exception is `UnsupportedOperationException` – Luca Basso Ricci Aug 23 '13 at 21:12
  • You are both right, but you must remember that `ConcurrentModificationException` is unchecked, and if you check the `LinkedList` source code, you will find the throw on the `remove()` method – Cristian Meneses Aug 23 '13 at 21:25
  • 2
    from LinkedList javadoc: The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the Iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. You CAN do a `Iterator.remove()` from a backed-to-`LinkedList` iterator, but you will have a `ConcurrentModificationException` if someone modify `LinkedList` from extern. – Luca Basso Ricci Aug 23 '13 at 21:37
  • Ok guys, if you wondering i have found my mistake. it was in wile loop, where i was calling initiation for locatables and thats why array was modifying too fast, now i put method call just before the for loop with interactios. :) Thank you. – Tom Skiba Aug 24 '13 at 07:45
1

java.util.ConcurrentModificationException Another approach is to use a for loop through the locatablesArray starting at the end vs the beginning. That way any elements that are removed won't change the location of elements of the array that are yet to be scanned.

NormR
  • 336
  • 3
  • 12
1

Maybe when you call repaint() in run(), paint() is queued to EDT and called as soon as possible; while iterating locatablesArray a call to initLocatables2() in run() is done another time and the re-init of locatablesArray in the same time the code of paint() will produce the error.
My advice is to separate init operation in a specific init section and call it once, the run your main loop.

Just another thing: why are you init a Iterator (class field itrLocatables) in initLocatables2()? Use iterator when needed if possible.

Hope to be clear, English is not my native language.

Luca Basso Ricci
  • 17,829
  • 2
  • 47
  • 69