问题
I'm creating a simple game and I'd like to repaint the board after every move. So, after I call move(), what I would like to do is this: (by the way, a View is a JComponent that holds pieces; since the number of pieces has changed after the move, it needs to be repainted)
for(View v : views){
v.repaint();
}
It's not working. When I call repaint()
on a single View, it works fine. I tried using paintImmediately
, and revalidate
, and update
... nothing works within the loop.
Any ideas? Thanks in advance.
EDIT: I should add that repaint() does get called when the window is resized, so I know that View's paintComponent method is valid and works. It's just not being called from the loop. When the debugger steps through the loop, it does not enter repaint() and nothing happens to the screen.
回答1:
Everything related to the UI must be called in the Event Dispatching Thread (EDT):
SwingUtilities.invokeLater(new Runnable() {
public void run() {
for(View v : views){
v.repaint();
}
}
});
You can also use invokeAndWait instead of invokeLater. You should read on the EDT if you want a responsive application.
For example, if you add an actionListener to a button, the code executed in that actionListener is executed in the EDT thread, so you must limit the process or you UI will stop responding.
Also, take a look to SwingUtilities.isEventDispatchingThread()
回答2:
Sometimes revalidate does not work if the nearest validateRoot is a JScrollPane. Not sure why. Try calling revalidate on the frame itself to see if that works. If it does, you have a problem with a validateRoot not properly validating your components. You only need to call revalidate once when the loop is finished.
来源:https://stackoverflow.com/questions/4671692/repaint-components-in-a-loop