如何制作小程序
原文: https://docs.oracle.com/javase/tutorial/uiswing/components/applet.html
本节介绍JApplet
- 一个允许 applet 使用 Swing 组件的类。 JApplet
是 java.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“里程碑”方法。因此,里程碑方法 - init
,start
,stop
和destroy
- 应使用SwingUtilities
方法invokeAndWait
(或者,如果适用,invokeLater
),以便引用的代码 Swing 组件在事件派发线程上执行。有关这些方法和事件派发线程的更多信息,请参见 Swin 中的 Concurrency。
以下是init
方法的示例:
public void init() {
//Execute a job on the event-dispatching thread:
//creating this applet's GUI.
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createGUI();
}
});
} catch (Exception e) {
System.err.println("createGUI didn't successfully complete");
}
}
private void createGUI() {
JLabel label = new JLabel(
"You are successfully running a 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();
//Execute a job on the event-dispatching thread:
//creating this applet's GUI.
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createGUI();
}
});
} catch (Exception e) {
System.err.println("createGUI didn't successfully complete");
}
//Set up the timer that will perform the animation.
timer = new javax.swing.Timer(speed, this);
timer.setInitialDelay(pause);
timer.setCoalesce(false);
timer.start(); //Start the animation.
//Background task for loading images.
SwingWorker worker = (new SwingWorker<ImageIcon[], Object>() {
public ImageIcon[] doInBackground() {
final ImageIcon[] innerImgs = new ImageIcon[nimgs];
...//Load all the images...
return imgs;
}
public void done() {
//Remove the "Loading images" label.
animator.removeAll();
loopslot = -1;
try {
imgs = get();
} ...//Handle possible exceptions
}
}).execute();
}
您可以在 TumbleItem.java
中找到 applet 的源代码。要查找 applet 所需的所有文件,请参阅示例索引。
Applet
类提供getImage
方法将图像加载到 applet 中。 getImage
方法创建并返回表示加载图像的Image
对象。因为 Swing 组件使用Icon
而不是Image
来引用图片,所以 Swing 小程序倾向于不使用getImage
。相反,Swing applet 创建ImageIcon
的实例 - 从图像文件加载的图标。 ImageIcon
具有节省代码的优点:它可以自动处理图像跟踪。有关更多信息,请参阅如何使用图标。
Duke 做车轮的动画需要 17 张不同的照片。小程序每张图片使用一个ImageIcon
并以init
方法加载它们。由于图像可能需要很长时间才能加载,因此图标将加载到由SwingWorker
对象实现的单独线程中。这是代码:
public void init() {
...
imgs = new ImageIcon[nimgs];
(new SwingWorker<ImageIcon[], Object>() {
public ImageIcon[] doInBackground() {
//Images are numbered 1 to nimgs,
//but fill array from 0 to 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; //Change this to the size of
//your biggest image, in bytes.
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("Couldn't read stream from file: " + path);
return null;
}
if (count <= 0) {
System.err.println("Empty file: " + path);
return null;
}
return new ImageIcon(Toolkit.getDefaultToolkit().createImage(buf));
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
loadImage
方法加载指定动画帧的图像。它使用getResourceAsStream
方法而不是通常的getResource
方法来获取图像。生成的代码并不漂亮,但getResourceAsStream
比getResource
更有效地将图像从 JAR 文件加载到使用 Java Plug-in™软件执行的 applet 中。有关详细信息,请参阅将图像加载到 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>A browser with Javascript enabled is required for this page to operate properly.</noscript>
有关更多信息,请参阅 Java Applets 课程中的部署小程序。
下表列出了JApplet
添加到 applet API 的有趣方法。它们使您可以访问根窗格提供的功能。您可能使用的其他方法由 Component
和 Applet
类定义。有关常用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 |
这一页 | 一个动画小程序 |