Hi!

I'm writing a Java simulation of a physical system. I wrote the whole simulation without any problems and later decided to add very simple GUI to paint the current sate of the system after each iteration.

This is where the first problem occurred. After creating my JFrame and JPanel I called the repaint() method after each iteration. The program seemed to work but Exceptions kept coming up:

Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.TreeMap$PrivateEntryIterator.nextEntry(TreeMap.java:1100)
at java.util.TreeMap$KeyIterator.next(TreeMap.java:1154)
at SimulationPanel.paintComponent(SimulationPanel.java:65)
at javax.swing.JComponent.paint(JComponent.java:1029)
at javax.swing.JComponent._paintImmediately(JComponent.java:5098)
at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:811)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:633)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)


When I replaced the repaint() method with paintImmediately(x,y,width,length) the problem no longer occurs but it makes the simulation quite slow...


And I have an analogical problem with a text field.
I crated a JTextField in my panel and call the setTest(String s) after each iteration. And here again I get the same errors... These errors don't crash my simulation but obviously I doing something wrong. Thanks for any tips =)

Edited 6 Years Ago by trelek2: n/a

Have you read the API doc for the ConcurrentModificationException?
Did any of that make sense?
Are you using Swing components and threads in a way that could cause the error?
There is a section in the Java Tutorial about how to update Swing components safely.
Sorry, I don't have its address handy. Some research could help you see the problem and fix it.

Yeah, I have an iterator over my tree set at each simulation step and the in the PaintComponent(graphics g) method. But I don't really understand this. Why does the repaint() cause Exceptions and PaintImmediately() doest? And why would trying to set the text in a JTextField cause this exception as well.
I'm doing physics here and I don't know Java well enough to solve this problem. Is it okay to just leave the exceptions coming up and let the simulation run like that?

If you're a weak programmer, probably the only way for any of us to help is if you could post the code and let us work with it.

Swing is not thread safe and there are recommended ways to go about updating components. See the SwingUtilities class's invoke... methods. Also read up in the Java Tutorial on how to use them and why.

repaint() sends a request to the internals to call the paint method at a later time on a special thread to draw the components. There could be problem here if the current thread is updating components while the drawing thread is working.
paintImmediately() sounds like it uses the current thread to do the painting. That would mean that the current thread could NOT be updating anything while the drawing was going on.

If you're a weak programmer, probably the only way for any of us to help is if you could post the code and let us work with it.

I attached my compressed code as an attachment. The main is Cludi. The simulation steps is preformed in Square. SimulationPanel is my JPanel.

Maybe it will be a simple thing for you. I recently came to a different college and here everyone uses C++ instead of Java and no one knows how to help me.

Attachments

The error happens in paintComponent() in the following line:

currentCluster = iterator.next();

In the Square class the code must be changing the TreeSet while paintComponent() is iterating thru it.
Too much logic here to wade thru right now.


Also you are using absolute placement of components vs using a layout manager.
Clock.setLocation(801, 0);

Move the Clock component to Cludi and use something like this to position it:

Clock = new JTextField("time: "+ Square.time, 10);
		simulationframe.getContentPane().add(simulationpanel, BorderLayout.CENTER);
		simulationframe.getContentPane().add(Clock, BorderLayout.EAST);

Okay, I did some more work. Yeah, that line was the problem. If I commented it out the clock or repaint methods worked.

So I decided not to use an iterator in the SimulationPanel.
Instead in Square, during each call of SumilationStep() I use the toArray() method of my tree set and access the array of clusters from my SimulationPanel in a static way and use a for loop to paint them.
This resulted in more or less the same problem as I had before: calling paintImmediately() causes no problems but repaint() and setText() for Clock caused a nullPointerException this time. (probably something wrong with my array of clusters).
And if I use the code you posted to position the Clock, I can then call that method to SetText() for the clock without getting that many exceptions but the clock is no longer visible. So I'm still stuck...
I attached the new code with my new changes. Maybe a nullPointerException is easier to deal with than that previous one?

Attachments

Here's my modified version.
I've tried various things. One was to make a copy of the TreeSet before calling repaint() so that the main thread is NOT updating it while the GUI thread is using an iterator on it.

Also moved setText() to execute on the GUI thread by using invokeLater().

Moved Clock to BorderLayout.SOUTH

Thank You Thank You so much!! I've never seen these things before but I'll read around...

This question has already been answered. Start a new discussion instead.