Когда мой апплет запускается в первый раз из чистой среды, все работает так, как я ожидал. Я создаю два потока, один для общей обработки, а другой для графики. Я делаю все вызовы манипуляций с графическим интерфейсом пользователя из потока диспетчеризации событий. Запуск / остановка выполняется правильно из программы просмотра апплетов, а перезапуск / перезагрузка - нет. У меня есть холст с именем 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 ()
, но с небольшими изменениями в среде выполнения.
Итак, мой вопрос: каково значение операций перезапуска и перезагрузки (т.е. когда они используются) и проблема в том, что мой апплет не работает в программе просмотра апплетов, когда они происходят?