Exception in thread when refreshing the GUI
My problem is simple, the code is complex and the answer is not so easy to find, so I'm asking for help.
I'm programming a multi threaded application, here's how it works:
1) One thread is reading a file and parsing information from a textfile (every 500 milliseconds tries to reach the end of the file)
2) When relevant information is found, the thread stores it and notifies the controller which is an observer
3) When controller is notified it notifies the other thread (the GUI) which updates the information I'd like to show to the user.
Except if I call revalide()
or validate()
or repaint()
there's an exception because the GUI is too often updated.
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: No such child: 7
at java.awt.Container.getComponent(Container.java:323)
at javax.swing.JComponent.rectangleIsObscured(JComponent.java:4393)
at javax.swing.JComponent.paint(JComponent.java:1052)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5206)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1493)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1424)
at javax.swing.RepaintManager.paint(RepaintManager.java:1217)
at javax.swing.JComponent._paintImmediatel开发者_运维百科y(JComponent.java:5154)
at javax.swing.JComponent.paintImmediately(JComponent.java:4964)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:781)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:739)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:688)
at javax.swing.RepaintManager.access$700(RepaintManager.java:59)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1632)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:660)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
I thought about running another thread which every 500 ms might try to revalidate()
the GUI but may be there's a better alternative.
Is there something I should worry about, like stopping the GUI thread before I call revalidate()
and then resume it or something like that ?
Yes indeed I remove components (JLabels) from the panel, to replace them with those with the new data. I'll try what you said.
By the way is there a big difference between the invokelater and start like another thread ?
Solution :
I created a method which looks like this:
protected void updateGUI(final Param param1, final Param param2){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//write your code
param1.validate();
param1.repaint();
}
});
The exception seems to me like something happening to the GUI outside the EDT which messes all up: more specifically, a component seems to be removed while the GUI wants to repaint it.
Try to have the code that adds / removes components as a Runnable
passed to SwingUtilities.invokeLater()
to make sure everything that changes the GUI in any way is synchronized.
精彩评论