文档

Java™教程
隐藏目录
如何制作Applet
路径:使用Swing创建GUI
课程:使用Swing组件
章节:如何使用各种组件

如何制作小程序

本节介绍了 JApplet —— 一个使applet能够使用Swing组件的类。 JAppletjava.applet.Applet 的子类,该类在 Java Applets 部分有详细介绍。如果您以前从未编写过普通的applet,请在阅读本节之前阅读该部分。该部分提供的信息适用于Swing applet,但也有一些例外情况,本节会进行解释。

包含Swing组件的任何applet必须使用 JApplet 的子类来实现。下面是一个Swing版本的帮助Java走红的applet之一 —— 一个动画applet,最著名的配置是显示我们的吉祥物Duke做空翻:


注意:  如果您看不到applet在运行,您需要安装至少 Java SE Development Kit (JDK) 7 版本。

您可以在 TumbleItem.java 中找到该applet的主要源代码。

本节讨论以下主题:

JApplet提供的功能

由于JApplet是一个顶级的Swing容器,每个Swing applet都有一个根窗格。根窗格的最明显的特点是支持添加一个 菜单栏,以及使用内容窗格的需求。

在使用顶层容器中所描述的,每个顶层容器,如JApplet,都有一个单独的内容窗格。内容窗格使得Swing applet与普通applet有以下不同之处:

Applet中的线程

Swing组件应该在事件调度线程上创建、查询和操作,但浏览器不会从该线程调用applet的“里程碑”方法。因此,里程碑方法initstartstopdestroy应该使用SwingUtilitiesinvokeAndWait方法(或者如果适用的话,invokeLater),以便引用Swing组件的代码在事件调度线程上执行。有关这些方法和事件调度线程的更多信息,请参见Swing中的并发

下面是一个init方法的示例:

public void init() {
    //在事件调度线程上执行一个任务:
    //创建这个applet的GUI。
    try {
        javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
                createGUI();
            }
        });
    } catch (Exception e) {
        System.err.println("createGUI没有成功完成");
    }
}

private void createGUI() {
    JLabel label = new JLabel(
                       "您正在成功运行一个Swing applet!");
    label.setHorizontalAlignment(JLabel.CENTER);
    label.setBorder(BorderFactory.createMatteBorder(1,1,1,1,Color.black));
    getContentPane().add(label, BorderLayout.CENTER);
}

这个实现中invokeLater方法不适用,因为它允许init在初始化完成之前返回,这可能会导致难以调试的applet问题。

如下所示,TumbleItem中的init方法更复杂。与第一个示例类似,这个init方法实现使用SwingUtilities.invokeAndWait在事件调度线程上执行GUI创建代码。此init方法设置了一个Swing定时器来触发更新动画的动作事件。此外,init使用javax.swing.SwingWorker创建一个后台任务,用于加载动画图像文件,让applet立即呈现GUI,而不需要等待所有资源加载完成。

private void createGUI() {
    ...
    animator = new Animator();
    animator.setOpaque(true);
    animator.setBackground(Color.white);
    setContentPane(animator);
    ...
}

public void init() {
    loadAppletParameters();

    //在事件调度线程上执行一个任务:创建此小程序的GUI。
    try {
        javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
                createGUI();
            }
        });
    } catch (Exception e) { 
        System.err.println("createGUI没有成功完成");
    }

    //设置执行动画的计时器。
    timer = new javax.swing.Timer(speed, this);
    timer.setInitialDelay(pause);
    timer.setCoalesce(false);
    timer.start(); //启动动画。

    //用于加载图像的后台任务。
    SwingWorker worker = (new SwingWorker<ImageIcon[], Object>() {
            public ImageIcon[] doInBackground() {
                final ImageIcon[] innerImgs = new ImageIcon[nimgs];
            ...//加载所有图像...
            return imgs;
        }
        public void done() {
            //移除“正在加载图像”的标签。
            animator.removeAll();
            loopslot = -1;
            try {
                imgs = get();
            } ...//处理可能的异常
        }

    }).execute();
}

你可以在TumbleItem.java中找到小程序的源代码。要找到小程序所需的所有文件,请参阅示例索引

在Swing小程序中使用图像

Applet类提供了getImage方法来加载图像到小程序中。 getImage方法创建并返回表示加载的图像的Image对象。因为Swing组件使用Icon而不是Image来引用图片,所以Swing小程序往往不使用getImage。相反,Swing小程序创建ImageIcon的实例 - 从图像文件加载的图标。 ImageIcon自动处理图像跟踪,这是它的一个节省代码的好处。请参阅如何使用图标以获取更多信息。

杜克做手脚的动画需要17张不同的图片。小程序使用每张图片一个ImageIcon,并在其init方法中加载它们。由于图像可能需要很长时间来加载,这些图标是在由SwingWorker对象实现的单独线程中加载的。以下是代码:

public void init() {
    ...
    imgs = new ImageIcon[nimgs];
    (new SwingWorker<ImageIcon[], Object>() {
        public ImageIcon[] doInBackground() {
            //从1到nimgs编号的图像,
            //但将数组从0到nimgs-1填充。
            for (int i = 0; i < nimgs; i++) {
                imgs[i] = loadImage(i+1);
            }
            return imgs;
        }
        ...
    }).execute();

}
...
protected ImageIcon loadImage(int imageNum) {
    String path = dir + "/T" + imageNum + ".gif";
    int MAX_IMAGE_SIZE = 2400;  //将此值更改为最大图像的大小(以字节为单位)。
    int count = 0;
    BufferedInputStream imgStream = new BufferedInputStream(
       this.getClass().getResourceAsStream(path));
    if (imgStream != null) {
        byte buf[] = new byte[MAX_IMAGE_SIZE];
        try {
            count = imgStream.read(buf);
            imgStream.close();
        } catch (java.io.IOException ioe) {
            System.err.println("无法从文件读取流:" + path);
            return null;
        }
        if (count <= 0) {
            System.err.println("空文件:" + path);
            return null;
        }
        return new ImageIcon(Toolkit.getDefaultToolkit().createImage(buf));
    } else {
        System.err.println("找不到文件:" + path);
        return null;
    }
}

loadImage 方法加载指定动画帧的图像。它使用 getResourceAsStream 方法而不是通常的 getResource 方法来获取图像。由于使用 Java Plug-in™ 软件在 JAR 文件中加载图像的 applet 中,getResourceAsStream 方法比 getResource 方法更高效。有关详细信息,请参阅 将图像加载到 Applet 中

将 Applet 嵌入 HTML 页面

您可以使用 applet 标签部署简单的 applet。或者,您可以使用 Deployment Toolkit。这是 cartwheeling Duke applet 的代码:

<script src="https://www.java.com/js/deployJava.js" type="text/javascript">
</script><script type="text/javascript">
//<![CDATA[
    var attributes = { archive: 'https://docs.oracle.com/javase/tutorialJWS/samples/uiswing/TumbleItemProject/TumbleItem.jar',
                       codebase: 'https://docs.oracle.com/javase/tutorialJWS/samples/uiswing/TumbleItemProject',
                       code:'components.TumbleItem', width:'600', height:'95' };
    var parameters = { permissions:'sandbox', nimgs:'17', offset:'-57',
                       img: 'images/tumble', maxwidth:'120' };
    deployJava.runApplet(attributes, parameters, '1.7');
//]]>
</script><noscript>启用 JavaScript 的浏览器才能正常运行此页面。</noscript>

要获取更多信息,请参阅部署小程序课程中的Java小程序

JApplet API

下表列出了JApplet在小程序API中添加的有趣方法。它们使您能够访问根窗格提供的功能。您可能会使用的其他方法由ComponentApplet类定义。有关常用Component方法的列表,请参阅组件方法,有关使用Applet方法的帮助,请参阅Java小程序

方法 用途
void setContentPane(Container)
Container getContentPane()
设置或获取小程序的内容窗格。内容窗格包含小程序的可见GUI组件,并应该是不透明的。
void setRootPane(JRootPane)
JRootPane getRootPane()
创建、设置或获取小程序的根窗格。根窗格管理小程序的内部,包括内容窗格、玻璃窗格等。
void setJMenuBar(JMenuBar)
JMenuBar getJMenuBar()
设置或获取小程序的菜单栏,以管理一组菜单。
void setGlassPane(Component)
Component getGlassPane()
设置或获取小程序的玻璃窗格。您可以使用玻璃窗格拦截鼠标事件。
void setLayeredPane(JLayeredPane)
JLayeredPane getLayeredPane()
设置或获取小程序的分层窗格。您可以使用小程序的分层窗格将组件放在其他组件的上方或下方。

Applet示例

这个表格展示了Swing applet的示例以及这些示例的描述。

示例 描述位置 注释
TumbleItem 本页 一个动画applet

上一页:如何使用各种组件
下一页:如何使用按钮、复选框和单选按钮