When you resize the browser window in Netscape, it will always do the following to any applet running on the page:
1. Call its stop() method
2. Call both of its resize() methods (resize(int,int) and
resize (dimension) )
3. Call its start() method
If your program uses threads, you should be careful how you write your start and stop methods. In most sample applet code, the stop() method calls stop on any separate threads within the applet, and then sets them to null. This is because most people think of the stop() method as something called when the user leaves the page and wants to forget about it. But since Netscape calls stop() when you resize the window, your users would lose the applet's state when they thought they were only making a minor adjustment.
The solution is to always suspend threads, not stop them, in the stop method. In the start() method, you resume them. For example:
public void stop() {
if (extraThread != null && extraThread.isAlive() )
extraThread.suspend()
..........
}
public void start() {
if (extraThread == null)
extraThread = new Thread();
else
extraThread.resume();
......
}
We still have a problem: how to dispose of threads once the user really is done. We don't want all these suspended threads hanging around now, do we?
First, we need to distinguish when stop() is being called by leaving the page, and when it's being called by resizing. The problem is that there is no way to do this. Recall that when Netscape does resizing, it calls stop() before it calls any resize() methods, not after, so the state is the same.
There are probably better solutions to this problem than my hack. But here it is anyway: create a new thread called killThread, a subclass of Thread whose run() body kills off all extra threads by calling the applet's destroy() method. The thread will wait 5 seconds (more or less) before it does this. Here's such a thread:
class KillThread extends Thread {
Applet parent;
final int KILLTHREADINTERVAL = 5000; // 5 seconds
public KillThread (Applet p) {
super("killThread");
parent = p;
}
public void run () {
try {
sleep(KILLTHREADINTERVAL);
} catch (InterruptedException e) {}
parent.destroy();
}
}
Meanwhile, make sure your applet's destroy() method is written to kill off extraThread, and this killThread:
public void destroy() {
if (extraThread != null) {
extraThread.stop();
extraThread = null;
}
if (killThread != null) {
killThread.stop();
killThread = null;
}
}
How do we use this killThread? We instantiate and run it at the beginning of the applet's stop() method. We stop and kill it at the beginning of the applet's start() method. In this way, we solve the problem of figuring out whether we were resizing or not. The sequence of events is:
1. Netscape calls the stop() method, and a killThread starts.
2. If 5 seconds elapse without the start() method being called, then the user has probably left the page. killThread calls destroy(), which terminates all the applet's extant threads.