Правильная обработка перезагрузки и перезапуска из AppletViewer

Когда мой апплет запускается в первый раз из чистой среды, все работает так, как я ожидал. Я создаю два потока, один для общей обработки, а другой для графики. Я делаю все вызовы манипуляций с графическим интерфейсом пользователя из потока диспетчеризации событий. Запуск / остановка выполняется правильно из программы просмотра апплетов, а перезапуск / перезагрузка - нет. У меня есть холст с именем drawCanvas в качестве единственного компонента на панели содержимого моего апплета, и я использую двойную буферизацию для его рисования.

Я наблюдаю здесь проблему:

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's GUI */
    setVisible(false);
    getContentPane().removeAll();
    removeAll();

    /* .. some more stuff */

Первый раз, все работает отлично. Когда я выполняю перезапуск из программы просмотра апплетов , сначала вызывается stop () , в результате чего все мои потоки переходят в состояния ожидания. Затем вызывается destroy () , который снова пробуждает все мои потоки и позволяет им выйти, а также do и invokeAndWait () в EDT, чтобы очистить мои виджеты и выполнить setVisible (ложный). Таким образом, после завершения уничтожения программа просмотра апплетов снова вызывает init / start, и процесс повторяется точно так же, как и раньше, за исключением того, что он терпит неудачу в start () в области, которую я отметил выше.

Я заметил, что для меня было очень мало смысла: если я клонировал апплет с помощью appletviewer , а затем перезагрузил клон, все будет работать должным образом, когда я попытаюсь перезапустить или перезагрузить клон. в первый раз, но во второй раз произойдет сбой, за исключением случаев.

Еще я заметил, пытаясь отладить эту проблему, что appletviewer и браузер действуют совершенно по-разному как хосты для моего апплета; они даже не вызывают init () и start () в одних и тех же условиях. Кроме того, перезапуск и перезагрузка кажутся не более чем вызовом stop () -> destroy () -> init () -> start () , но с небольшими изменениями в среде выполнения.

Итак, мой вопрос: каково значение операций перезапуска и перезагрузки (т.е. когда они используются) и проблема в том, что мой апплет не работает в программе просмотра апплетов, когда они происходят?

12
задан Lahiru Ashan 29 November 2016 в 08:23
поделиться