2011-09-09 12 views
12

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?

risposta

6

Bella domanda. Per rispondere a questa domanda, dobbiamo prima capire i blocchi del codice java. abbiamo un blocco statico anonimo prima del costrutore che verrà eseguito.

package com.test; 

import java.applet.Applet; 
import java.awt.*; 

public class AppletTest extends Applet { 
    { 
     System.out.println("I m Anonymous block"); 
    } 

    static { 
     System.out.println("I m static block"); 
    } 

    public AppletTest() 
    { 
     System.out.println("I m constructor"); 
    } 

    public void init() 
    { 
     System.out.println("init"); 
    } 

    public void start() 
    { 
     System.out.println("start"); 
    } 

    public void stop() 
    { 
     System.out.println("stop"); 
    } 

    public void destroy() 
    { 
     System.out.println("destory"); 
    } 

    public void paint(Graphics g) 
    { 
     g.drawString("test Applet",10,10); 
    } 
} 

invocazione:

<applet code="AppletTest.class" height=300 width=300></applet> 

durante l'esecuzione di questa classe secondo i appletviewer si può notare la differenza. Applet in esecuzione per la prima volta si aprirà

I m static block 
    I m Anonymous block 
    I m constructor 
    init 
    start 

mentre si fa applet riavvio -

stop 
destory 
init 
start 

e applet reload

stop 
destory 
I m Anonymous block 
I m constructor 
init 
start 

riguarda la seconda domanda, applet non garantisce la stesso output su diversi SO, componenti di rete e hardware.

Problemi correlati