2011-09-09 13 views
12

Kiedy mój aplet uruchamia się po raz pierwszy w czystym środowisku, wszystko działa tak, jak tego oczekuję. Tworzę dwa wątki, jeden do generycznego przetwarzania, a drugi do grafiki. Wykonuję wszystkie wywołania manipulacyjne GUI z wątku wysyłającego zdarzenia. Start/Stop jest obsługiwany poprawnie z appletviewer, ale Restart/Reload nie jest. Mam Canvas o nazwie drawCanvas jako jedyny komponent w okienku zawartości mojego apletu i używam podwójnego buforowania, aby go narysować.Prawidłowa obsługa ponownego ładowania i ponowne uruchamianie z AppletViewer

Obserwuję problem tutaj:

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 */ 
       } 
    /* ... */ 

Gdzie setupDrawCanvas jest zdefiniowany następująco:

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); 
} 

Również tutaj jest odpowiedni kod w 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 */ 

za pierwszym razem , wszystko dziala. Kiedy wykonuję restart od appletviewer, wywoływane jest najpierw stop(), co powoduje, że wszystkie moje wątki przechodzą w stan oczekiwania. Następnie wywoływana jest destroy(), która budzi wszystkie moje wątki ponownie i pozwala im wyjść, a także zrobić i invokeAndWait() na EDT, aby wyczyścić moje widżety i zrobić ustawienie setVisible (false). Tak więc po zniszczeniu ponownie uruchamia się inicjowanie/inicjowanie appletviewer, a proces powtarza się dokładnie tak, jak poprzednio, z tym, że nie powiedzie się w start() w regionie, który zaznaczyłem powyżej.

Zauważyłem, że gdybym sklonował aplet przy użyciu appletviewer, a następnie ponownie załadowałem klon, wszystko działałoby zgodnie z oczekiwaniami, gdy próbowałem ponownie uruchomić klon po raz pierwszy, ale za drugim razem ulegnie awarii z wyjątkiem.

Coś innego, co zauważyłem podczas próby usunięcia tego problemu, to że appletviewer i przeglądarka działają jako zupełnie inaczej jako hosty mojego apletu; oni nawet nie wywołują init() i start() w tych samych warunkach. Ponadto ponowne uruchomienie i ponowne ładowanie wydają się być niczym więcej niż wywołaniem stop() ->destroy() ->init() ->start(), ale z subtelnymi modyfikacjami środowiska wykonawczego.

Moje pytanie brzmi: jakie jest znaczenie operacji ponownego uruchamiania i ponownego ładowania (tj. Kiedy są one używane) i czy jest to problem, że mój applet kończy się niepowodzeniem w aplikacji appletviewer, kiedy się pojawią?

Odpowiedz

6

Ładne pytanie. Aby odpowiedzieć na to pytanie, musimy najpierw zrozumieć bloki kodu Java. mamy anonimowe, statyczne bloki przed construtorem, które zostaną wykonane.

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); 
    } 
} 

inwokacja:

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

podczas uruchamiania tej klasy przy użyciu appletviewer można zauważyć różnicę. Aplet działa po raz pierwszy, otworzy się

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

robiąc apletu restart -

stop 
destory 
init 
start 

i na apletu reload

stop 
destory 
I m Anonymous block 
I m constructor 
init 
start 

do drugiego pytania, aplet nie gwarantuje ten sam wynik na różnych systemach operacyjnych, sieci i składnikach sprzętowych.

Powiązane problemy