Quando la mia applet si avvia per la prima volta da un ambiente pulito, le cose funzionano nel modo in cui mi aspetto che lo facciano. Creo due thread, uno per l'elaborazione generica e uno per la grafica. Faccio tutte le chiamate di manipolazione della GUI dal thread di invio dell'evento. Start/Stop viene gestito correttamente da appletviewer, ma Riavvia/Ricarica non lo è. Ho un Canvas chiamato drawCanvas
come l'unico componente nel riquadro del contenuto dell'applet, e utilizzo il double buffering per disegnarlo.Gestire correttamente un ricaricamento e il riavvio da AppletViewer
osservo il problema qui:
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 */
}
/* ... */
Dove setupDrawCanvas
si definisce in questo modo:
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);
}
Inoltre, ecco il codice rilevante 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 */
La prima volta , tutto funziona bene. Quando eseguo il riavvio da appletviewer
, viene chiamato prima il numero stop()
che fa entrare tutti i miei thread in stati di attesa. Quindi viene chiamato destroy()
che riattiva tutti i thread e li lascia uscire, così come fa e invokeAndWait()
sull'EDT per pulire i miei widget e fare un setVisible (false). Quindi, dopo la distruzione completa le chiamate appletviewer
init/start di nuovo e il processo si ripete esattamente come prima, eccetto che fallisce in start()
nella regione che ho annotato sopra.
Qualcosa che ho notato che ha reso molto poco senso per me era che se ho clonato l'applet utilizzando il appletviewer
e poi ricaricato il clone, tutto avrebbe funzionato come previsto quando ho tentato di riavviare o ricaricare il clone la prima volta, ma si bloccherebbe con un'eccezione la seconda volta.
Un'altra cosa che ho notato durante il tentativo di eseguire il debug di questo problema è che il appletviewer
e un browser funzionano come in modo diverso come come host della mia applet; non chiamano nemmeno lo init()
e lo start()
alle stesse condizioni. Inoltre, il riavvio e la ricarica sembrano essere nient'altro che una chiamata a stop()
->destroy()
->init()
->start()
ma con sottili modifiche all'ambiente di esecuzione.
Quindi la mia domanda è, qual è il significato delle operazioni di riavvio e ricarica (ad esempio, quando vengono utilizzate) ed è un problema che l'applet non riesce nell'appletviewer quando si verificano?