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ą?