Подтвердить что ты не робот

Правильная обработка перезагрузки и перезапуска из 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, когда они происходят?

4b9b3361

Ответ 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

для вашего второго вопроса, апплет не гарантирует одинаковый вывод для разных ОС, сетевых и аппаратных компонентов.