OK. You need to do several things.
1. Once you start runner, leave the runner variable alone until after it is done.
2, Get rid of the thisThread logic in run().
3. Create a new instance variable called "keepGoing", like this:
private volatile boolean keepGoing = false;
4. At the beginning of the run() method, set keepGoing = true.
5. You need one while loop:
while (keepGoing && !Thread.currentThread.isInterupted()) {
...
}
6. In your catch block, add the line
Thread.currentThread.interrupt();
7. When you want your thread to stop, set keepGoing = false;
The "volatile" keyword ensures that keepGoing holds the same value for both threads. The JVM is *allowed* (not required) to make copes of all variables for each thread. You have to use "synchronize" to update all of them, or you can just mark some of them volatile. In this case, volatile should be more efficient.
Using a flag to end a thread is generally more gentle than interrupt(), which can cause Exception's to be thrown and break things like streams and sockets.
It is a good idea to check if the thread was interrupted. You *cannot* assume you will get an Exception, since Exceptions are thrown only when the thread is blocking. If you do get an Exception, interrupt() the thread again to set its interrupted flag. It won't cause an Exception because the thread is active.
I also noticed that your thread is doing some painting. THAT IS A MAJOR NO-NO! All UI updates *must* be performed on the event dispatcher thread. You will get unpredictable results! Use a thread to prepare the UI update, but do the update on the EDT.
Google EventQueue.invokeLater().
|