Reputation: 1832
At the moment, I am working on a version of Conway's Game of Life for my own amusement. Up to this point, everything has gone smoothly, but just as I was testing some of the final parts, I noticed an irritating error. The main body of the code takes place inside of a while loop that is controlled by the number of 'generations' of the game the user would like see. While this loop is executing, the JFrame's red X refuses to respond and I am at a loss as to why this is.
Area where I am encountering this issue:
public void run(int steps) throws InterruptedException{
int a = 0;
do{
step();
myDisp.update(myDisp.getGraphics());
Thread.sleep(delay);
a++;
}while(a < steps);
}
Upvotes: 1
Views: 373
Reputation: 72399
By default your while loop will be executing on the Event Dispatch Thread (EDT), which handles all GUI operations. You should never execute long running tasks on the EDT for this reason - the GUI will lock up, since you're not giving it any free time to handle user input! However, you must execute any code that touches the GUI on the EDT. There's a special method, SwingUtilities.invokeLater()
, that will do this (take a Runnable and invoke it on the EDT.)
So in your example you would create a new thread and execute it, this thread would contain your while loop, and the myDisp.update()
call would be wrapped in the above method to ensure it was still on the EDT. The alternative (neater) solution is to use a SwingWorker
, which provides a nicer interface for accomplishing the same thing.
Upvotes: 4
Reputation: 285450
Your long-running while loop is running on the Swing Event Dispatch Thread or EDT, typing it up, and preventing all Swing graphics and user interactions. Solution: use a background thread for your long-running tasks.
Please read: Lesson: Concurrency in Swing
for more details on this and for how to use a SwingWorker.
Upvotes: 3
Reputation: 1554
I would suggest you to put this kind of processing in a separate thread. As long as you keep it in the main body of your code, Swing components will not respond to any user interaction as long as the loop is running.
In this page you can find some good practices regarding asynchronous operations in Swing applications. I would like to highlight one of the topics:
Rule #2: do not run time-consuming operations on the event thread.
I'll keep repeating this: Swing uses a single thread for all GUI events. If your event handler is uploading a multi-megabyte file across the net, those events will be delayed until you're done. There is a balancing act involved with this rule: some operations (such as getting the size of a file) are so fast that they won't interrupt the user. However, that's not a reason to be cavalier, because some day your user will be getting the size of a file that resides on a fileserver that has an intermittent network connection.
This other page also shows an example of how to handle long-running tasks in a Swing application. You may also want to have a look at the SwingWorker class.
Upvotes: 6