大家好,又见面了,我是你们的朋友全栈君。
使用的教材是java核心技术卷1,我将跟着这本书的章节同时配合视频资源来进行学习基础java知识。
applet是包含在HTML页面中的Java程序。HTML页面必须告诉浏览器要加载哪些applet,另外每个applet要放在Web页面的什么位置。可以想见,需要使用applet的标记(tag)必须告诉浏览器从哪里得到类文件,以及这个applet在Web页面上如何定位(大小、位置等)。然后浏览器再从Internet(或者从用户机器上的某个目录)获取类文件,并自动运行applet。
最初开发applet时,必须使用Sun的RotJava浏览器才能査看包含applet的Web页面。很自然地,很少有用户愿意只是为了尝试一个新的Web特性去使用另一个浏览器。后来Netscape在它的Navigator浏览器中包含了一个Java虚拟机,那时Javaapplet才开始流行。Microsoft的InternetExplorer紧随其后。遗憾的是,InternetExplorer中的Java支持很快就落伍了,只能用于一些过期的Java版本,后来干脆取消了。
为了解决这个问题,SunMicrosystems开发了“JavaPlug-in”。通过使用浏览器扩展机制,可以把插件插人不同的浏览器,允许这些浏览器使用外部Java运行时环境执行Javaapplet。
多年来,这个解决方案都能满足要求,applet常用于教学工具、企业应用和一些游戏。遗憾的是,尽管不时会发现Java虚拟机的安全漏洞并被恶意利用,但SunMicrosystems和后来的Oracle在修补这些漏洞方面却动作迟缓,举措不力。由于不安全的JVM会置用户于危险当中,所以浏览器制造商让Java的使用更有难度。有些浏览器除了最新版本的Java插件外甚至完全禁用其他Java插件,另外一些浏览器则不再支持插件体系结构。Oracle的反应也很让人失望。它开始要求所有applet都有数字签名。
如今,开发人员要部署Javaapplet会很困难,用户运行applet也不容易。
编写一个NotHelloWorld程序,这里把它写为一个applet。applet就是一个扩展了java.applet.Applet类的Java类。我们将使用Swing来实现applet。这里的所有applet都将扩展JApplet类,它是Swingapplet的超类。如图所示,JApplet是Applet类的一个直接子类。
下面的程序显示了applet版本“NotHelloWorld”的代码。
/**
*@author zzehao
*/
import java.swt.*;
import javax.swing.*;
public class NotHelloWorld extends JApplet
{
public void init()
{
EventQueue.invokeLater(() -> {
JLabel label = new JLabel("Not a Hello,World applet",SwingConstants.CENTER);
add(label);
});
}
}
要执行applet,需要完成以下3个步骤:
1)将Java源文件编译为类文件
。2)将类打包到一个JAR文件中。
3)创建一个HTML文件,告诉浏览器首先加载哪个类文件,以及如何设定applet的大小。下面给出这个文件的内容:
<applet dass="applet/NotHel1olilorld.class" archive="NotHel1oWorld.jar" width="300",height="300">
</applet>
在浏览器中査看applet之前,最好先在JDK自带的appletviewer(applet查看器)程序中进行测试。要使用applet查看器测试我们的示例applet,可以在命令行输入:
appletviewer NotHelloWorldApplet.html
applet查看器程序的命令行参数是HTML文件名,而不是类文件。
很容易把一个图形化Java应用转换为可以嵌入在Web页面中的applet。基本上来说,所有用户界面代码都可以保持不变。下面给出具体的步骤:
1)建立4HTML页面,其中包含加载applet代码的适当标记。
2)提供JApplet类的一个子类。将这个类标记为public。否则applet将无法加载。
3)删去应用中的main方法。不要为应用构造框架窗口。你的应用将在浏览器中显示。
4)把所有初始化代码从框架窗口移至applet的init方法。不需要明确构造applet对象,浏览器会实例化applet对象并调用init方法。
5)删除setSize调用;对applet来说,用HTML文件中的width和height参数就可以指定大小。
6)删除setDefaultCloseOperation调用。applet不能关闭;浏览器退出时applet就会终止运行。
7)如果应用调用setTitle,则删除这个方法调用。applet没有标题栏。(当然,可以用HTMLtitle标记为Web页面本身指定标题。)
8)不要调用setVisible(true)。applet会自动显示。
下面是一个最简形式的 applet 标记示例:
<applet dass="applet/NotHel1olilorld.class" archive="NotHel1oWorld.jar" width="300",height="300">
</applet>
可以在applet标记中使用以下属性:
•width,height
这些属性是必要的,指定了applet的宽度和高度(单位为像素)。在applet查看器中,这是applet的初始状态。可以调整applet查看器创建的任何窗口的大小。但在浏览器中不能调整applet的大小。需要适当地猜测你的applet需要占据多大的空间,才能够让所有用户看到好的效果。
•align
这个属性指定了applet的对齐方式。属性值与HTMLimg标记的align属性值相同。
•vspace,hspace
这些属性是可选的,指定了applet上下的像素数(vspace)以及左右两边的像素数(hspace)。
•code
这个属性指定了applet的类文件名。路径名必须与applet类的包一致。例如,如果applet类在包com.mycompany中,那么这个属性就是code=”com/mycompany/MyApplet.class”,也可以是code=”com.mycompany.MyApplet.class”0code属性只指定包含applet类的类的名字。当然,你的applet可能包含其他类文件。一旦浏览器的类加载器加载了包含applet的类,它就会发现还需要更多类文件,并加载这些文件。
•archive
这个属性会列出包含applet的类以及其他资源的JAR文件(可能有多个JAR文件)。这些文件会在加载applet之前从Web服务器获取。
•codebase
这个属性是加载JAR文件(早期还可以加载类文件)的URL。
•object
这个属性已经过时,可以指定包含串行化applet对象的文件的文件名,这个文件用于持久存储applet状态。由于没有办法对一个串行化文件签名,所以这个特性已经没有用了。
•alt
Java禁用时,可以使用alt属性来显示一个消息。如果一个浏览器根本无法处理applet,它会忽略未知的applet和param标记。浏览器会显示记之间的所有文本。与之相反,支持Java的浏览器不会显示#记之间的任何文本。对于使用这些浏览器的人,可以在这些标记之间显示提示消息。
•name
编写脚本的人可以为applet指定一个name属性,用来指本所编写的applet。Netscape和InternetExplorer都允许通过JavaScript调用页面上的applet的方法。要从JavaScript访问一个applet,首先要指定一个名字。然后可以用document.applets.ap/7/e/wfl/we表示这个对象。例如:varrayApplet=document.applets.line;接下来就可以调用applet方法了:myApplet.initO;希望同一个页面上的两个applet相互直接通信时name属性也很重要。为每个当前applet实例指定一个名字,将这个字符串传递到AppletContext接口的getApplet方法。
与应用可以使用命令行信息一样,applet可以使用内嵌在HTML文件中的参数。这是利用HTMLparam标记以及所定义的属性来完成的。例如,假设想让Web页面确定applet中使用的字体样式。可以使用以下HTML标记:
〈applet code="FontParamApplet.class" ...>
<param name="font" value="Helvetica"/>
</applet>
然后使用 Applet 类的 getParameter 方法得到参数的值:
public class FontParamApplet extends JApplet
{
public void init()
{
String fontName = getParameter("font");
...
}
...
}
参数总是作为字符串返回。如果需要数值类型,则需要将字符串转换为数值。可以调用适当的方法采用标准方式进行转换,如Integer类的parselnt。
除了要确保代码中的参数匹配之外,还要检查是否缺少size参数。可以简单地测试是否为null来达到目的。例如:
int fontsize;
String sizeString= getParameter("size");
if (sizeString = null) fontSize = 12;
else fontSize = Integer.parseint(sizeString);
下面的程序十绘制直方图图表applet的源代码。需要说明,init方法读取了参数,并由paintComponent方法绘制图表。
/**
*@author zzehao
*/
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import javax.swing.*;
public class Chart extends JApplet
{
public void init()
{
EventQueue.invokeLater(() -> {
String v = getParameter("values");
if (v == null)
return;
int n = Integer.parseInt(v);
double[] values = new double[n];
String[] names = new String[n];
for (int i = 0;i<n;i++)
{
values[i] = Double.parseDouble(getParameter("value."+(i+1)));
name[i] = getParameter("name." + (i+1));
}
add(new ChartComponent(values,names,getParameter("title")));
});
}
}
//A component that draws a bar chart.
class ChartComponent extends JComponent
{
private double[] values;
private String[] names;
private String title;
public ChartComponent(double[] v, String[] n, String t)
{
values = v;
names = n;
title = t;
}
public void paintComponent(Graphics g)
{
Graphics2D g2 =(Graphics2D) g;
//compute the minimum and maximum values
if (values == null)
return;
double minValue = 0;
double maxValue = 0;
for (double v : values)
{
if (minValue>v) minValue = v;
if (maxValue< v) maxValue = v;
}
if (maxValue == minValue)
return;
int panelWidth = getWidth();
int panelHeight = getHeight();
Font titleFont = new Font("SansSerif", Font.BOLD, 20);
Font labelFont = new Font("SansSerif", Font.PLAIN, 10);
//compute the extent of the title
FontRenderContext context = g2.getFontRenderContext();
Rectangle2D titleBounds = titleFont.getStringBounds(title, context);
double titleWidth = titleBounds.getWidth();
double top = titleBounds.getHeight();
//draw the title
double y= -titleBounds.getY(); //ascent
double x = (panelWidth - titleWidth)/2;
g2.setFont(titleFont);
g2.drawString(title, (float)x, (float) y);
//compute the extent of the bar labels
LineMetrics labelMetrics = labelFont.getLineMetrics("", context);
double bottom = labelMetrics.getHeight();
y = panelHeight - labelMetrics.getDescent();
g2.setFont(labelFont);
//get the scale factor and width for the bars
double scale =(panelHeight - top - bottom)/(maxValue - minValue);
int barWidth =panelWidth /values.length;
//draw the bars
for (inti =0;i < values.length;i++)
{
//get the coordinates of the bar rectangle
double x1 = i * barWidth + 1;
double y1 = top;
double height = values[i] * scale;
if (values[i]>= 0)
y1 += (maxValue - values[i])*scale;
else
{
y1 += maxValue*scale;
height = -height;
}
//fill the bar and draw the bar outline
Rectangle2D rect = new Rectangle2D.Double(x1, y1, barWidth - 2, height);
g2.setPaint(Color.RED);
g2.fi11(rect);
g2.setPaint(Color.BLACK);
g2.draw(rect);
//draw the centered label below the bar
Rectangle2D labelBounds = labelFont.getStringBounds(names[i], context);
double labelWidth = labelBounds.getWidth();
x = x1 + (barWidth - labelWidth)/2;
g2.drawString(names[i], (float) x, (float) y);
}
}
}
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/156822.html原文链接:https://javaforall.cn