当我的applet第一次从干净的环境启动时,事情就像我期望的那样。我产生了两个线程,一个用于通用处理,一个用于图形。我从事件调度线程执行所有GUI操作调用。从appletviewer正确处理启动/停止,但不重启/重新加载。我有一个名为drawCanvas
的Canvas作为我Applet内容窗格中唯一的Component,我使用双缓冲来绘制它。
我在这里观察到问题:
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 */
第一次,一切正常。当我从appletviewer
重新启动时,会调用第一个stop()
,这会导致我的所有线程进入等待状态。然后调用destroy()
,它再次唤醒我的所有线程并让它们退出,以及在EDT上执行invokeAndWait()
以清理我的小部件并执行setVisible(false)。因此,在销毁完成之后,appletviewer
再次调用init / start,并且该过程与之前完全重复,除非它在我上面提到的区域start()
中失败。
我注意到的对我来说没什么意义的是,如果我使用appletviewer
克隆applet然后重新加载克隆,当我尝试重新启动或重新加载克隆时,一切都会按预期工作时间,但第二次会因异常而崩溃。
我在尝试调试此问题时注意到的其他事项是appletviewer
和浏览器完全作为我的applet的主机;他们甚至不会在相同的条件下拨打init()
和start()
。此外,重新启动和重新加载似乎只是对stop()
- >的调用。 destroy()
- > init()
- > start()
但对执行环境进行了微妙的修改。
所以我的问题是,重启和重新加载操作的重要性是什么(即它们何时使用),并且当appletview出现时我的applet在appletviewer中失败是一个问题吗?
答案 0 :(得分:6)
好问题。 要回答这个问题,我们首先需要了解java代码块。 我们在construtor之前有一个匿名的静态块,将被执行。
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运行此类时,您可以注意到差异。 Applet第一次运行
I m static block
I m Anonymous block
I m constructor
init
start
在执行applet重启时 -
stop
destory
init
start
和applet重新加载
stop
destory
I m Anonymous block
I m constructor
init
start
对于第二个问题,applet不保证在不同的操作系统,网络和硬件组件上输出相同的输出。