Hello all,
I'm continuing my foray into using [invokeLater()|http://forums.sun.com/thread.jspa?threadID=5410578] to perform GUI changes. I'm posting this in a new Thread because it's a separate question from the other one (which has been answered), plus I just love awarding duke stars.
Here's the basic question: Say I'm doing a bunch of GUI "stuff" in a call to
invokeLater() . But in the middle of all the GUI changes, I want to repaint a Component. I would have hoped that just putting the repaint where I wanted it to happen would do the trick, but it turns out that the call to repaint seemingly gets added
after the rest of my GUI code in the
invokeLater() call. I've created an SSCCE to demonstrate what I'm talking about:
import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.Graphics;
public class RepaintTest{
public RepaintTest(){
//create a Panel that tells us when it is being repainted
final JPanel repaintedPanel = new JPanel(){
public void paintComponent(Graphics g){
System.out.println("\nREPAINTING\n");
}
};
//put the repaintedPanel in a Frame
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(repaintedPanel);
frame.setSize(100,100);
frame.setVisible(true);
//this just makes sure repaintedPanel is visible
//otherwise repaint exits before paintComponent?
try{
Thread.sleep(2000);
}
catch(Exception e){}
try{
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
//do a bunch of pretend GUI stuff
longMethod("one");
//repaint the panel BEFORE continuing
//or at least repaint at the same time as the other stuff
repaintedPanel.repaint();
//do the rest of the long-lasting GUI stuff
longMethod("two");
}
});
}
catch(Exception e){
e.printStackTrace();
}
}
//pretend this is a method that does a bunch of GUI stuff
public void longMethod(String name){
for(int i = 0; i < 100; i++){
System.out.println(name + ": " + i);
}
}
public static void main(String [] args){
new Thread(new Runnable() {
public void run() {
new RepaintTest();
}
}).start();
}
}
I can see that
repaint() is called when the JFrame first pops up, but let's say I want it to be also called between the calls to
longMethod() inside
invokeLater() . Currently, the
repaint() always happens
after the other two methods are completed. I'm not sure exactly why, but I'm imagining that
repaint() uses another call to
invokeLater() , which adds the actual painting command to the EDT after the commands I've placed there?
If I take out the
invokeLater() , it does exactly what I'd want it to.
I hope I'm making sense, even if my question isn't a very smart one. I know I could probably use three separate calls to invokeLater(), but in my actual program that would require adding dozens (possibly hundreds) of those calls instead of using an all-encompassing call. So is there a way to make sure that the repaint happens before (or during) the code that comes after it?
Thanks again,
Kevin