When my applet starts up the first time from a clean environment, things work the way I expect them to. I spawn two threads, one for generic processing, and one for graphics. I do all GUI manipulation calls from the event dispatching thread. Start/Stop is handled correctly from the appletviewer, but Restart/Reload is not. I have a Canvas called drawCanvas
as the only Component in my Applet's content pane, and I use double buffering to draw to it.
I observe the problem here:
public void start() {
/* ... some stuff */
executeOnEDTAndWait(
new Thread() {
@Override
public void run() {
/* ... more stuff ... */
setupDrawCanvas();
if( drawCanvas.isDisplayable() ) {
drawCanvas.createBufferStrategy(2);
/* ... some more stuff */
} else {
/* This is where it runs into difficulties */
}
/* ... */
Where setupDrawCanvas
is defined like this:
private void setupDrawCanvas() {
setVisible(false);
setIgnoreRepaint(true);
getContentPane().removeAll();
drawCanvas = new Canvas();
drawCanvas.setName("drawCanvas");
drawCanvas.setSize(
newDrawCanvasDimension.width,
newDrawCanvasDimension.height);
drawCanvas.setIgnoreRepaint(true);
getContentPane().add(drawCanvas);
getContentPane().setVisible(true);
drawCanvas.setVisible(true);
setVisible(true);
}
Also, here's the relevant code in destroy()
public void destroy() {
/* .. some stuff .. */
/* dispose of drawCanvas */
drawCanvas.setVisible(false);
if( drawCanvas.getBufferStrategy() != null ) {
drawCanvas.getBufferStrategy().dispose();
}
/* reset and disable the applet's GUI */
setVisible(false);
getContentPane().removeAll();
removeAll();
/* .. some more stuff */
The first time through, everything works fine. When I do a restart from the appletviewer
, first stop()
is called which causes all my threads to enter into wait states. Then destroy()
is called which wakes all my threads up again and lets them exit, as well as do and invokeAndWait()
on the EDT to clean up my widgets and do a setVisible(false). So after destroy completes the appletviewer
calls init/start again and the process repeats exactly as before, except it fails in start()
at the region I noted above.
Something that I noticed which made very little sense to me was that if I cloned the applet using the appletviewer
and then reloaded the clone, everything would work as expected when I attempted to restart or reload the clone the first time, but would crash with an exception the second time.
Something else I noticed while trying to debug this problem is that the appletviewer
and a browser act completely differently as hosts to my applet; they don't even call init()
and start()
under the same conditions. Also, restart and reload seem to be nothing more than a call to stop()
-> destroy()
-> init()
-> start()
but with subtle modifications to the execution environment.
So my question is, what is the significance of the restart and reload operations (i.e. when are they used) and is it a problem that my applet fails in the appletviewer when they occur?