如何制作小程序

原文: https://docs.oracle.com/javase/tutorial/uiswing/components/applet.html

本节介绍JApplet - 一个允许 applet 使用 Swing 组件的类。 JAppletjava.applet.Applet 的子类, Java Applets 跟踪。如果您之前从未编写过常规小程序,我们建议您在继续本节之前阅读该小程序。该跟踪中提供的信息适用于 Swing 小程序,本节说明了一些例外情况。

任何包含 Swing 组件的 applet 必须使用 JApplet 的子类实现。这是一个帮助 Java 成名的小程序的 Swing 版本 - 一个动画小程序(以其最着名的配置)显示我们的吉祥物 Duke 做车轮:


Note: If you don’t see the applet running, you need to install at least the Java SE Development Kit (JDK) 7 release.


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

本节讨论以下主题:

提供的功能

因为JApplet是顶级 Swing 容器,所以每个 Swing applet 都有一个根窗格。根窗格存在的最显着效果是支持添加菜单栏以及需要使用内容窗格。

使用顶级容器中所述,每个顶级容器(如JApplet)都有一个内容窗格。内容窗格以下列方式使 Swing applet 与常规 applet 不同:

  • 您将组件添加到 Swing applet 的内容窗格,而不是直接添加到 applet。 向内容窗格添加组件向您展示如何操作。
  • 您可以在 Swing applet 的内容窗格上设置布局管理器,而不是直接在 applet 上。
  • Swing applet 的内容窗格的默认布局管理器是BorderLayout。这与Applet的默认布局管理器不同,后者是FlowLayout
  • 您不应将绘画代码直接放在JApplet对象中。有关如何在小程序中执行自定义绘制的示例,请参阅执行自定义绘画

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

以下是init方法的示例:

  1. public void init() {
  2. //Execute a job on the event-dispatching thread:
  3. //creating this applet's GUI.
  4. try {
  5. javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
  6. public void run() {
  7. createGUI();
  8. }
  9. });
  10. } catch (Exception e) {
  11. System.err.println("createGUI didn't successfully complete");
  12. }
  13. }
  14. private void createGUI() {
  15. JLabel label = new JLabel(
  16. "You are successfully running a Swing applet!");
  17. label.setHorizontalAlignment(JLabel.CENTER);
  18. label.setBorder(BorderFactory.createMatteBorder(1,1,1,1,Color.black));
  19. getContentPane().add(label, BorderLayout.CENTER);
  20. }

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

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

  1. private void createGUI() {
  2. ...
  3. animator = new Animator();
  4. animator.setOpaque(true);
  5. animator.setBackground(Color.white);
  6. setContentPane(animator);
  7. ...
  8. }
  9. public void init() {
  10. loadAppletParameters();
  11. //Execute a job on the event-dispatching thread:
  12. //creating this applet's GUI.
  13. try {
  14. javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
  15. public void run() {
  16. createGUI();
  17. }
  18. });
  19. } catch (Exception e) {
  20. System.err.println("createGUI didn't successfully complete");
  21. }
  22. //Set up the timer that will perform the animation.
  23. timer = new javax.swing.Timer(speed, this);
  24. timer.setInitialDelay(pause);
  25. timer.setCoalesce(false);
  26. timer.start(); //Start the animation.
  27. //Background task for loading images.
  28. SwingWorker worker = (new SwingWorker<ImageIcon[], Object>() {
  29. public ImageIcon[] doInBackground() {
  30. final ImageIcon[] innerImgs = new ImageIcon[nimgs];
  31. ...//Load all the images...
  32. return imgs;
  33. }
  34. public void done() {
  35. //Remove the "Loading images" label.
  36. animator.removeAll();
  37. loopslot = -1;
  38. try {
  39. imgs = get();
  40. } ...//Handle possible exceptions
  41. }
  42. }).execute();
  43. }

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

Applet类提供getImage方法将图像加载到 applet 中。 getImage方法创建并返回表示加载图像的Image对象。因为 Swing 组件使用Icon而不是Image来引用图片,所以 Swing 小程序倾向于不使用getImage。相反,Swing applet 创建ImageIcon的实例 - 从图像文件加载的图标。 ImageIcon具有节省代码的优点:它可以自动处理图像跟踪。有关更多信息,请参阅如何使用图标

Duke 做车轮的动画需要 17 张不同的照片。小程序每张图片使用一个ImageIcon并以init方法加载它们。由于图像可能需要很长时间才能加载,因此图标将加载到由SwingWorker对象实现的单独线程中。这是代码:

  1. public void init() {
  2. ...
  3. imgs = new ImageIcon[nimgs];
  4. (new SwingWorker<ImageIcon[], Object>() {
  5. public ImageIcon[] doInBackground() {
  6. //Images are numbered 1 to nimgs,
  7. //but fill array from 0 to nimgs-1.
  8. for (int i = 0; i < nimgs; i++) {
  9. imgs[i] = loadImage(i+1);
  10. }
  11. return imgs;
  12. }
  13. ...
  14. }).execute();
  15. }
  16. ...
  17. protected ImageIcon loadImage(int imageNum) {
  18. String path = dir + "/T" + imageNum + ".gif";
  19. int MAX_IMAGE_SIZE = 2400; //Change this to the size of
  20. //your biggest image, in bytes.
  21. int count = 0;
  22. BufferedInputStream imgStream = new BufferedInputStream(
  23. this.getClass().getResourceAsStream(path));
  24. if (imgStream != null) {
  25. byte buf[] = new byte[MAX_IMAGE_SIZE];
  26. try {
  27. count = imgStream.read(buf);
  28. imgStream.close();
  29. } catch (java.io.IOException ioe) {
  30. System.err.println("Couldn't read stream from file: " + path);
  31. return null;
  32. }
  33. if (count <= 0) {
  34. System.err.println("Empty file: " + path);
  35. return null;
  36. }
  37. return new ImageIcon(Toolkit.getDefaultToolkit().createImage(buf));
  38. } else {
  39. System.err.println("Couldn't find file: " + path);
  40. return null;
  41. }
  42. }

loadImage方法加载指定动画帧的图像。它使用getResourceAsStream方法而不是通常的getResource方法来获取图像。生成的代码并不漂亮,但getResourceAsStreamgetResource更有效地将图像从 JAR 文件加载到使用 Java Plug-in™软件执行的 applet 中。有关详细信息,请参阅将图像加载到 Applet

您可以使用applet标记部署一个简单的小程序。或者,您可以使用 Deployment Toolkit。以下是 cartwheeling Duke applet 的代码:

  1. <script src="https://www.java.com/js/deployJava.js" type="text/javascript">
  2. </script><script type="text/javascript">
  3. //<![CDATA[
  4. var attributes = { archive: 'https://docs.oracle.com/javase/tutorialJWS/samples/uiswing/TumbleItemProject/TumbleItem.jar',
  5. codebase: 'https://docs.oracle.com/javase/tutorialJWS/samples/uiswing/TumbleItemProject',
  6. code:'components.TumbleItem', width:'600', height:'95' };
  7. var parameters = { permissions:'sandbox', nimgs:'17', offset:'-57',
  8. img: 'images/tumble', maxwidth:'120' };
  9. deployJava.runApplet(attributes, parameters, '1.7');
  10. //]]>
  11. </script><noscript>A browser with Javascript enabled is required for this page to operate properly.</noscript>

有关更多信息,请参阅 Java Applets 课程中的部署小程序

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

方法 目的
void setContentPane(Container)

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

此表显示了 Swing applet 的示例以及描述这些示例的位置。

在哪里描述 笔记
TumbleItem 这一页 一个动画小程序