Java学习day086 部署Java程序(三)(applet:一个简单的applet、applet HTML标记属性、使用参数向applet传递信息)

2022-09-08 12:17:54 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

使用的教材是java核心技术卷1,我将跟着这本书的章节同时配合视频资源来进行学习基础java知识。

day086 部署Java程序(三)(applet:一个简单的applet、applet HTML标记属性、使用参数向applet传递信息)


applet

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也不容易。


1.一个简单的applet

编写一个NotHelloWorld程序,这里把它写为一个applet。applet就是一个扩展了java.applet.Applet类的Java类。我们将使用Swing来实现applet。这里的所有applet都将扩展JApplet类,它是Swingapplet的超类。如图所示,JApplet是Applet类的一个直接子类。

下面的程序显示了applet版本“NotHelloWorld”的代码。

代码语言:javascript复制
/**
 *@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的大小。下面给出这个文件的内容:

代码语言:javascript复制
<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会自动显示。


2.applet HTML标记属性

下面是一个最简形式的 applet 标记示例:

代码语言:javascript复制
<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方法。


3.使用参数向applet传递信息

与应用可以使用命令行信息一样,applet可以使用内嵌在HTML文件中的参数。这是利用HTMLparam标记以及所定义的属性来完成的。例如,假设想让Web页面确定applet中使用的字体样式。可以使用以下HTML标记:

代码语言:javascript复制
〈applet code="FontParamApplet.class" ...>
<param name="font" value="Helvetica"/>
</applet>

然后使用 Applet 类的 getParameter 方法得到参数的值:

代码语言:javascript复制
public class FontParamApplet extends JApplet
{
    public void init()
    {
        String fontName = getParameter("font");
        ...
    }
    ...
}

参数总是作为字符串返回。如果需要数值类型,则需要将字符串转换为数值。可以调用适当的方法采用标准方式进行转换,如Integer类的parselnt。

除了要确保代码中的参数匹配之外,还要检查是否缺少size参数。可以简单地测试是否为null来达到目的。例如:

代码语言:javascript复制
int fontsize;
String sizeString= getParameter("size");
if (sizeString = null) fontSize = 12;
else fontSize = Integer.parseint(sizeString);

下面的程序十绘制直方图图表applet的源代码。需要说明,init方法读取了参数,并由paintComponent方法绘制图表。

代码语言:javascript复制
/**
 *@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

0 人点赞