Правильная обработка перезагрузки и перезапуска из AppletViewer
Когда мой апплет запускается в первый раз из чистой среды, все работает так, как я их ожидаю. Я создаю два потока, один для общей обработки и один для графики. Я выполняю все вызовы манипуляции графическим интерфейсом из потока диспетчеризации событий. Пуск/Стоп обрабатывается правильно из appletviewer, но Restart/Reload - нет. У меня есть Canvas, называемый drawCanvas
как единственный компонент в моей области содержимого Applet, и я использую двойную буферизацию для рисования.
Я вижу здесь проблему:
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 */
}
/* ... */
Где setupDrawCanvas
определяется следующим образом:
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);
}
Кроме того, здесь соответствующий код в destroy()
public void destroy() {
/* .. some stuff .. */
/* dispose of drawCanvas */
drawCanvas.setVisible(false);
if( drawCanvas.getBufferStrategy() != null ) {
drawCanvas.getBufferStrategy().dispose();
}
/* reset and disable the applet GUI */
setVisible(false);
getContentPane().removeAll();
removeAll();
/* .. some more stuff */
В первый раз все работает нормально. Когда я перезапускаю из appletviewer
, вызывается первый stop()
, который заставляет все мои потоки входить в состояния ожидания. Затем вызывается destroy()
, который снова пробуждает все мои потоки и позволяет им выйти, а также сделать и invokeAndWait()
в EDT, чтобы очистить мои виджеты и сделать setVisible (false). Таким образом, после уничтожения завершает appletviewer
вызовы init/start again, и процесс повторяется точно так же, как и раньше, за исключением того, что он не работает в start()
в области, отмеченной выше.
Что-то, что я заметил, что для меня было очень мало смысла, было то, что если бы я клонировал апплет с помощью appletviewer
, а затем перезагрузил клон, все будет работать так, как ожидалось, когда я попытаюсь перезапустить или перезагрузить клон в первый раз, но во второй раз произойдет сбой с исключением.
Что-то еще, что я заметил при попытке отладки этой проблемы, состоит в том, что appletviewer
и браузер действуют по-разному как хосты для моего апплета; они даже не вызывают init()
и start()
при тех же условиях. Кроме того, перезагрузка и перезагрузка кажутся не чем иным, как вызовом stop()
→ destroy()
→ init()
→ start()
, но с незначительными изменениями в среде выполнения.
Итак, мой вопрос в том, каково значение операций перезагрузки и перезагрузки (т.е. когда они используются), и является ли проблема, что мой апплет не работает в appletviewer, когда они происходят?
Ответы
Ответ 1
Хороший вопрос.
Чтобы ответить на этот вопрос, нам нужно сначала понять блоки java-кода.
у нас есть анонимные, статические блоки перед конструктором, которые будут выполнены.
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);
}
}
мольба:
<applet code="AppletTest.class" height=300 width=300></applet>
при запуске этого класса с помощью appletviewer вы можете заметить разницу.
Апплет работает в первый раз, когда вы получите
I m static block
I m Anonymous block
I m constructor
init
start
при перезапуске апплета -
stop
destory
init
start
и перезагрузка апплета
stop
destory
I m Anonymous block
I m constructor
init
start
для вашего второго вопроса, апплет не гарантирует одинаковый вывод для разных ОС, сетевых и аппаратных компонентов.