JBuilder 2005开拓Applet游戏全打仗
副标题#e#
引言
一张湘绣搜集了湘女累月的心血,我们称之为劳动麋集型,一块芯片集聚着浩瀚高新的科技,我们称之为技能麋集型,一个实例承载了富厚的常识点,是否可以称为常识麋集型呢:)?用一张网捞到更多的鱼是渔夫的追求,通过一个实例学到更多的常识点则是我们这些开拓人员的企盼。
本文拟通过一个耳熟能详的指法操练游戏讲授如安在JBuilder 2005下开拓Applet应用措施,通过本文,你将可以进修到图形用户界面开拓、动画处理惩罚、声音播放、事件处理惩罚、多线程、I/O读写、Applet打包、Applet安详模子、数字签名、JRE插件建造、JDK5.0等方面的常识,并当令先容笔者一些开拓履历。
指法操练Applet游戏先容
1、界面及成果
指法操练的Applet游戏的界面如下图所示:
图 1 指法操练的用户界面
如上图所示,这个Applet共由11个组件构成,左边的主界面是画布Canvas组件,被脱离为10个栏。措施会随机在这些栏中发生下落的字母,用户按下匹配的字母键盘按键后,即为击中,相应的字母将消失,正确数递增1;字母落到画布底端后,还没有被击中,失败数递增1;每发生一个下落的字母,总数递增1。
游戏提供了3个JButton的按钮,别离用于节制游戏的开始/暂停、竣事以及生存游戏后果。在未启动游戏前第一个按钮显示为三角箭头的图标,点击后启动游戏,随后按钮图标切换为暂停的图标。而第二个为遏制按钮,其上显示竣事的图标,当游戏处于运行或暂停的状态时,点击该按钮将遏制游戏以便从头开始。而第三个按钮生存游戏的后果到客户端的D:\result.txt文件中。
整个界面回收BorderLayout机关打点器,画布位于BorderLayout.CENTER区,而右边的节制台JPanel位于BorderLayout.EAST区。节制台的JPanel回收GridLayout机关打点器。
2、措施构成
每个下落的字母对应一个线程实例,称为DropCharThread线程,它由一个发生器按时发生出来,这个发生器也是一个线程称为GenerateDropThread线程,下面是这个Applet的类图:
图 2 Applet类图
#p#副标题#e#
TypeTrainApplet类担任了JApplet,是游戏的主类,DropCharThread和GenerateDropThread都是其内部类,后两者都担任Thread,以线程的方法运行,下面临这3个类重要的成员变量和成员要领举办说明。
1).TypeTrainApplet
担任JApplet的Applet主类,认真结构用户界面、响应用户操纵事件、更新游戏统计数据等。
· 重要成员变量
统计数据变量
volatile int totalCount = 0;//出产下落字母的总数。
volatile int rightCount = 0;//正确击中的字母数。
volatile int errorCount = 0;//未被击中且达到画布底部的字母数。
这3个变量用volatile作了修饰,这是因为这3个变量会被每个字母下落线程变动,为防备各个线程通过各自的缓存变动变量值造成线程间值的差异步,需要将这3个变量配置为volatile的范例,这样这些变量的变动值对付其他线程顿时可见。
字母下落速率节制变量
private static int stepLen = 2; //每次下落的步长,即字母每移一步的象素。
private static int stepInterval = 50; //每两步之间的时距离断,以毫秒为单元。
private static int columnCount = 10; //画布被脱离为多个栏
private static int generateInterval = 500; //建设一个新的下落字母线程的时距离断,以毫秒为单元
Applet通过通过这4个变量到达节制发生字母的快慢和字母下落的速度及栏数,可以进一步筹划这些值,以形成游戏的难度级别。有鉴于此,我们特地将这些参数的值通过HTML的<Applet>参数传入。这样,只需要变动HTML的<applet>参数值就可以到达节制游戏难度级此外方针,而不需变动Applet措施。
其他
int colWidth; //下落字母每栏的宽度,在运行期才获取这个变量值,它由画布的宽度和栏数抉择。
volatile char pressKeyChar; //记录当前按键对应的字母。
int statusCode = 0; //记录游戏所处的状态,个中1:运行态、,2:暂停态 0:遏制态。
· 重要成员要领
private void drawResult()//将统计功效写到界面的对应JLabel中。
private void resetGame()//重置游戏现场
2) DropCharThread
是一个线程,将一个随机的字母在画布的特定栏中往下落下,并及时检测是否被击中,假如击中顿时消失,不然一直落到画布的底部。
·重要成员变量
char c; //对应的字母
int colIndex; //对应画布的栏序号,第一栏为1,第二栏为2,以此类推
int x, y; //当前字母在画布中的坐标
·行动范例常量
private static final int ACTION_DRAW_FONT = 1; //暗示画字符
private static final int ACTION_CLEAR_FONT = 2; //暗示排除字符
不应当直接用1或2暗示行动的范例,而应该界说一个更有意义的常量,这样不单于领略,也便于今后的维护。
·重要成员要领
public DropCharThread(char c, int colIndex)//结构函数,传入特定的字母和栏序号
private void draw(int actionType)//在画布中特写的位置上画字母
3) GenerateDropThread
·重要成员变量
Random random = new Random(); //认真发生随机数
·重要成员要领
private char getRandomChar()//获取一个随机的字母
认真按时发生一个DropCharThread线程实例,通过generateInterval成员变量节制发生DropCharThread线程实例的频率。
#p#分页标题#e#
当游戏玩家点击Applet的开始按钮后,Applet将启动游戏,这3个类之间的交互干系可以通过以下的顺序图来描写,如下图所示:
图 3 开始游戏的顺序图
1)当用户按下Applet的开始按钮后引发一个事件。
2) Applet响应这个事件,挪用事件响应要领,在要领中实例化一个GenerateDropThread线程,并启动这个线程。
3) GenerateDropThread线程按时发生一个DropCharThread线程,并让赋予一个随机的字母和栏序号。
4)DropCharThread线程启动,将字母在特定的栏中从上至下落下。
措施框架
1、操作领导生成Applet
首先建设一个工程(File->New…->Project->双击Project页中的Project图标),我们将工程名取为game,然后操作下面的步调,挪用Applet领导生成TypeTrainApplet。
1) 启动Applet领导
File->New…->Web->双击Web页中Applet的图标启动共4步的Applet领导。
2) 领导第1步,填写Applet的具体信息。
图 4 Applet领导第1步
·ClassName:Applet的类名,填入TypeTrainApplet
·Package:包名,接管默认值
·Base Class:父类,有两个选项,一个是java.applet.Applet,另一个是javax.swing.JApplet。前者以AWT为基本,尔后者以Swing为基本。假如客户端欣赏器的JRE版本很低,且你不但愿客户下载特另外插件,则需要思量用java.applet.Applet,且不能应用高版本JDK中的特性,这里我们用javax.swing.JApplet。
·Generate header comments:在发生Applet代码时,发生类标题头的注释说明,你大可不必生成这些注释。
·Can run standalone:是否将Applet配置为可独立运行,假如勾选,JBuilder为其生成了一个main函数,这样就可以在离开欣赏器或AppletViewer的环境下,像一般可运行类一样运行这个Applet中的成果,我们不勾选它。
·Generate standard methods:是否生成Applet的尺度函数,各人都知道Applet通过4个函数打点着Applet的生命周期,它们别离是init()、start()、stop()、destroy()。假如不勾选这个选项,领导只会生成init()要领,而其他3个要领不会生成。在我们的例子中,需要用到其他3个要领,所以需要勾选。
按Next到下一步。
3) 界说Applet的参数
Applet的参数是指通过网页中<applet>标签的<param>指定的参数值,这些值可以在Applet类中引用到。这样就答允在不改变Applet措施的环境下,仅通过网页中<applet>属性值的变动节制Applet的表示。我们在这一步中为Applet配置4个节制变量参数,如下图所示:
图 5 为Applet配置参数
这一步的配置,不单为网页生成了参数声明,还为Applet措施生成了从网页获取参数值的要领,在Applet初始化时,即将网页中的参数值赋给Applet的成员变量。
点击Add Parameter新增一行,声明一个新的参数,个中Name*为网页中参数的名字,而Variable*为Applet类成员变量名,通过Type*栏配置成员变量的数据范例。你还可觉得参数在Default栏中指定一个默认的值,在Desc中给出描写说明信息,个中带*的栏是必填的栏。
点击Next到下一步。
4) 配置包括这个Applet的网页
在这一步里,我们指定包括这个Applet网页的<applet>标签的一些属性,如下图所示:
图 6 配置引用Applet的网页
JBuilder会生成一个引用Applet的HTML网页,网页名字和Applet的类名沟通,网页通过<applet>标签引用Applet,网页的标题及<applet>属性值在这一步中配置。
我们除将Height从默认的300调解为400,其他的都保持稳定。按Next到最后一步。
5) 建设运行设置项
#p#分页标题#e#
在这一步里JBuilder答允你抉择是否为Applet生成一个运行设置项,运行设置项是答允你设置运行时的有关属性,如运行的进口类,在运行时是否从头编译等,你也可以通过Project->Project Properties…->Run来维护运行设置项。
图 7 配置Applet运行设置信息
点击Finish完成Applet的建设领导。此时JBuilder为这个Applet生成了两个文件,一个是TypeTrainApplet.java措施文件,而另一个是引用这个Applet的TypeTrainApplet.html网页。我们来看这两个文件的主要布局。
代码清单 1 TypeTrainApplet.html 引用Applet的网页表
1. <html>
2. <head>
3. <meta http-equiv="Content-Type" content="text/html; charset=GBK">
4. <title>
5. HTML Test Page
6. </title>
7. </head>
8. <body>
9. game.TypeTrainApplet will appear below in a Java enabled browser.<br>
10. <applet
11. codebase = "."
12. code = "game.TypeTrainApplet.class"
13. name = "TestApplet"
14. width = "400"
15. height = "400"
16. hspace = "0"
17. vspace = "0"
18. align = "middle"
19. >
20. <param name = "stepLen" value = "2">
21. <param name = "stepInterval" value = "50">
22. <param name = "columnCount" value = "10">
23. <param name = "generateInterval" value = "500">
24. </applet>
25. </body>
26. </html>
在领导第2步所配置的Applet参数悉数在网页中界说(第20~23行),在领导第3步中配置的Applet属性反应在第11~18行中。
Applet类的TypeTrainApplet.java文件代码如下所示:
代码清单 2 TypeTrainApplet.java
1. package game;
2.
3. import java.awt.*;
4. import java.awt.event.*;
5. import java.applet.*;
6. import javax.swing.*;
7.
8. public class TypeTrainApplet1 extends JApplet {
9. boolean isStandalone = false;
10. BorderLayout borderLayout1 = new BorderLayout();
11. int stepLen;
12. int stepInterval;
13. int columnCount;
14. int generateInterval;
15.
16. //Get a parameter value
17. public String getParameter(String key, String def) {
18. return isStandalone ? System.getProperty(key, def) :
19. (getParameter(key) != null ? getParameter(key) : def);
20. }
21.
22. //Construct the applet
23. public TypeTrainApplet1() {
24. }
25.
26. //Initialize the applet
27. public void init() {
28. try {
29. stepLen = Integer.parseInt(this.getParameter("stepLen", "2"));
30. } catch (Exception e) {
31. e.printStackTrace();
32. }
33. try {
34. stepInterval = Integer.parseInt(this.getParameter("stepInterval",
35. "50"));
36. } catch (Exception e) {
37. e.printStackTrace();
38. }
39. try {
40. columnCount = Integer.parseInt(this.getParameter("columnCount",
41. "10"));
42. } catch (Exception e) {
43. e.printStackTrace();
44. }
45. try {
46. generateInterval = Integer.parseInt(this.getParameter(
47. "generateInterval", "500"));
48. } catch (Exception e) {
49. e.printStackTrace();
50. }
51. try {
52. jbInit();
53. } catch (Exception e) {
54. e.printStackTrace();
55. }
56. }
57.
58. //Component initialization
59. private void jbInit() throws Exception {
60. this.setSize(new Dimension(400, 300));
61. this.getContentPane().setLayout(borderLayout1);
62. }
63.
64. //Get Applet information
65. public String getAppletInfo() {
66. return "Applet Information";
67. }
68.
69. //Get parameter info
70. public String[][] getParameterInfo() {
71. java.lang.String[][] pinfo = { {
72. "stepLen", "int", "每次下落的步长"}, {
73. "stepInterval", "int", "每移动一个像素的隔断时间,以毫秒为单元"}, {
74. "columnCount", "int", 分成几多列"}, {
75. "generateInterval", "int", 分成几多列"},
76. };
77. return pinfo;
78. }
79.
80. //static initializer for setting look & feel
81. static {
82. try {
83. //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
84. } catch (Exception e) {
85. }
86. }
87. }
#p#分页标题#e#
个中第11~14行界说了对应领导第2步所界说的参数变量,第70~78行获取参数的注释信息。在Applet通过init()初始化,在init()中挪用要领将网页中参数的值赋给Applet类的成员变量,以初始化变量的值。在第59~62行设定了Applet的巨细,其值应该和网页中<applet>的width和height属性值一致。
2、设计Applet界面
打开TypeTrainApplet.java,切换到Design视图页面中,设计如下的Applet界面
图 8 Applet界面设计
承继JApplet的Applet其默认的机关打点器是BorderLayout,首先在其东区(BorderLayout.EAST)安排一个infoPnl的JPanel组件,将infoPnl的机关打点器配置为GridLayout,9行1列,即在jbInit()要领中通过infoPnl.setLayout(new GridLayout(9, 1));配置。再在infoPnl上依次安排9个组件,这些组件的范例和用途别离说明如表所示:
表 2 组件说明
组件名 | 组件范例 | 用途 |
jButton1 | JButton | 开始/暂停按钮 |
jButton2 | JButton | 竣事按钮 |
jButton3 | JButton | 生存按钮 |
totalLbl_1 | JLabel | 总数标签 |
totalLbl_2 | JLabel | 总数值显示标签 |
rightLbl_1 | JLabel | 正确数标签 |
rightLbl_2 | JLabel | 正确数值显示标签 |
errorLbl_1 | JLabel | 错误数标签 |
errorLbl_2 | JLabel | 错误数值显示标签 |
你只要从设计器窗口左边的组件库顶用鼠标将组件拖到设计窗口的相应位置,并放开鼠标就可以了相应生成用户界面的代码了。
由于画布组件没有java.awt.Canvas并没有列在JBuilder的组件面板中,你可以直接通过编码的方法把画布组件放到Applet的中区(BorderLayout.CENTER),了可以点击JBuilder可视化设计器的Bean选择器图标 (位于组件库的上方),在弹出的Bean Chooser对话框中选择java.awt.Canvas,如下图所示:
图 9 通过Bean选择器选择Canvas组件
在Bean Chooser对话框中有一棵以包组织的类树,选择Canvas类,再点击OK按钮,在可视化设计器的Bean选择器的下拉菜单中将呈现java.awt.Canvas的类,如下图所示:
图 10 Bean选择器中的Canvas组件类
点击下拉菜单中的java.awt.Canvas,鼠标移到Applet设计界面的中心点击一下,一个画布组件就被添加到Applet的中区去了。在组件树中选中这个Applet中,将其定名为canvas,并确认其Constaints属性是CENTER(即位于中区)。
3、游戏的统计数据
游戏包罗3个统计数据,即已发生字母的总数,被正确击中的字母数及未被击中的字母数。需要有3个变量来生存这些统计数据,同时还需要一个要领,将数据写到Applet界面的统计标签组件中去。当用户点击开始按钮时挪用resetGame()要领将这些统计数据归0。
我们在TypeTrainApplet中添加以下粗体的代码。
代码清单 3 统计数据
1. …
2. public class TypeTrainApplet extends JApplet
3. {
4. …
5. volatile int totalCount = 0;//总数计数器
6. volatile int rightCount = 0;//正确数计数器
7. volatile int errorCount = 0;//错误数计数器
8. public TypeTrainApplet()
9. {}
10. …
11. //将统计功效画到界面上
12. private void drawResult()
13. {
14. totalLbl_2.setText("" + totalCount);
15. rightLbl_2.setText("" + rightCount);
16. errorLbl_2.setText("" + errorCount);
17. }
18. //重置现场
19. private void resetGame()
20. {
21. totalCount = 0;
22. rightCount = 0;
23. errorCount = 0;
24. drawResult();
25. }
26. …
27. }
drawResult()要领以下两种环境下都应被挪用:
·击中一个字母。
·一个字母下落到底端。
而resetGame()要领在点击开始按钮后挪用,将3个统计变量归零,以便从头开始统计。
主体措施
1、字母下落线程
#p#分页标题#e#
游戏界面中每一个下落的字母对应一个字母下落线程DropCharThread的实例,这个线程认真将一个随机的字母在指定的画布栏中从上至下落下。在TypeTrainApplet内部界说这个线程类,之所以要将其作为成员内部类来界说,是因为这样可以淘汰类和类之间的通信,低落挪用接口的巨大度。DropCharThread需要会见到TypeTrainApplet的浩瀚成员,作为内部类就可以直接会见TypeTrainApplet类的成员变量了。其代码如下所示:
代码清单 4 DropCharThread字母下落线程
1. …
2. public class TypeTrainApplet extends JApplet {
3. …
4. private class DropCharThread extends Thread {
5. char c; //对应的字符
6. int colIndex; //在哪列下落
7. int x, y; //队列的坐标
8. private static final int ACTION_DRAW_FONT = 1; //画字符
9. private static final int ACTION_CLEAR_FONT = 2; //清字符
10. public DropCharThread(char c, int colIndex) {
11. this.c = c;
12. this.colIndex = colIndex;
13. this.x = (colIndex - 1) * colWidth + colWidth / 2; //地址的横坐标
14. }
15. //线程要领
16. public void run() {
17. draw(ACTION_DRAW_FONT);
18. try {
19. while (c != pressKeyChar && y < canvas.getHeight() && statusCode != 0) {
20. synchronized (canvas) {
21. while (statusCode == 2) {
22. canvas.wait();
23. }
24. }
25. draw(ACTION_CLEAR_FONT);
26. y += stepLen;
27. draw(ACTION_DRAW_FONT);
28. Thread.sleep(stepInterval);
29. }
30. } catch (InterruptedException ex) {
31. }
32.
33. pressKeyChar = ' ';
34. draw(ACTION_CLEAR_FONT);
35. if (statusCode != 0) {//游戏没有遏制
36. totalCount++; //统计总数
37. if (y < canvas.getHeight()) {
38. rightCount++; //击中
39. } else {
40. errorCount++; //打不中
41. }
42. drawResult();
43. }
44. }
45.
46. /**
47. * 画字母
48. * @param actionType 1:画字母 2: 排除字母
49. */
50. private void draw(int actionType) {
51. synchronized (canvas) { //必需对资源canvas举办同步,不然会发生线程不安详
52. Graphics g = canvas.getGraphics();
53. if (actionType == ACTION_CLEAR_FONT) {
54. g.setXORMode(canvas.getBackground()); //排除
55. }
56. g.setFont(new Font("Times New Roman", Font.PLAIN, 12));
57. g.drawString("" + c, x, y);
58. }
59. }
60. }
61. …
62. }
由于这个类较量要害,逻辑也较量巨大,为了利便说明,我们将其流程通过一个流程图来描写,如下图所示:
图 11 字母下落线程流程图
1) 首先在栏序号为colIndex的栏的第一个位置画出生存在变量c中的字母(第17行)。
2) 当这个字母未被击中,未达到画布底部且用户未竣事游戏举办轮回,这步判定对应措施的19行。假如这个判定条件通过进入第3步,即进入轮回体,不然转到第5步。
3) 假如被暂停,这个线程进入期待态,直接被通知后才继承运行。需要指明一点的是,所有字母下落线程都用画布工具canvas举办同步,即用canvas举办通讯。线程间要举办通讯时,必然需要通讯线程都可以会见到的工具充当前言将这些线程"串"起来,通过这个工具的notify()/notifyAll()/wait()在线程间通讯。这个工具比如一个"月下老人",在线程的恋人间通报音讯。
#p#分页标题#e#
4) 当线程被叫醒后,或本来就没有期待,则进入下一个轮回的处理惩罚进程,在这个进程中,措施将本来位置的字母排除,下移纵坐标,并在新的位置画字母,以到达字母下落的动画结果,然后下落线程睡眠指定的毫秒数,毫秒数值为TypeTrainApplet成员变量stepInterval的值,而这个值可以在网页的<param name = "stepInterval" value = "50">标签中界说,到达节制下落速度的结果。
因为在画布上画字母后,这个字母并不会自动消失,假如直接移动纵坐标并在新位置画字母,原位置的字母依就存在。所以在新位置画字母之前,必需先将旧位置的字母排除。我们用了一个小能力,纵然用Graphics工具的setXORMode()要领,该要领两图像重叠部门的颜色。我们挪用这个要领将图像重叠部门的颜色配置为画布的配景致,这样在本来的位置上再次画字母时,因为前后两次画个字母恰好重叠,就到达了排除原位置字母的结果。
画字母和排除字母的措施相似,我们把它抽出到一个要领中draw(int actionType),如第50~59行代码所示,通过入参抉择是排除照旧画新字母。为加强措施的可读性,我们在第8~9行中界说了两个用于暗示清字母和画字母的行动常量。
5) 当措施出了轮回体后,进积德后的处理惩罚:将用于生存用户按键字母的pressKeyChar变量置为空字符,在画布上排除移到底部的字母。假如游戏没有竣事统计数据,并将数据写到界面的JLabel组件中。
2、添加击中音效
击中字母后播放一个短促的声音,将能大大提高游戏的听觉体验,这在节里,我们对字母下落线程稍作变动,以使其支持音效。
首先筹备一个声音文件hit.wav,放在TypeTrainApplet.java沟通的文件夹下。Applet类中界说了一个getAudioClip(URL url)要领,通过这个要领可以获取AudioClip的声音文件的工具。通过AudioClip的play()即可播放这个音效。
代码清单 5
1. …
2. import java.applet.AudioClip;
3. public class TypeTrainApplet extends JApplet {
4. …
5. AudioClip hitSound;//声明音效工具
6. …
7. public void init() {
8. …
9. hitSound = getAudioClip( (TypeTrainApplet.class).getResource(
10. "hit.wav"));//初始化音效工具
11. }
12. …
13. private class DropCharThread extends Thread {
14. …
15. public void run() {
16. …
17. draw(ACTION_CLEAR_FONT);
18. if (statusCode != 0) { //游戏没有遏制
19. totalCount++; //统计总数
20. if (y < canvas.getHeight()) {
21. hitSound.play();//击中时播放音效
22. rightCount++; //击中
23. } else {
24. errorCount++; //打不中
25. }
26. drawResult();
27. }
28. }
29. }
30. …
31. }
在第5行界说一个音效的工具,在Applet初始化时获取音效工具,如第9行所示。变动字母下落线程,当击中下落的字母时播放音效,如第21行所示。
3、字母下落线程的发生器线程
指法操练需要"子子孙孙,无穷匮也"地不绝发生字母下落线程,以使游戏一连举办,这个事情由发生器线程GenerateDropThread认真。GenerateDropThread线程出于和DropCharThread同样的原因,也作为TypeTrainApplet成员内部类来界说,其代码如下所示:
代码清单 6 GenerateDropThread 发生器线程
1. …
2. public class TypeTrainApplet extends JApplet {
3. …
4. private class GenerateDropThread extends Thread {
5. Random random = new Random(); //随机数
6. public void run() {
7. try {
8. while (statusCode != 0) { //发生下落线程
9. synchronized (canvas) {
10. while (statusCode == 2) {
11. canvas.wait();
12. }
13. }
14. DropCharThread dropCharThread = new DropCharThread(
15. getRandomChar(),
16. random.nextInt(columnCount) + 1);
17. dropCharThread.start();
18. Thread.sleep(generateInterval);
19. }
20. } catch (InterruptedException ex) {
21. }
22. }
23.
24. /**
25. * <b>成果说明:</b><br>
26. * 返回一个随机字符
27. * @return 随机字符
28. */
29. private char getRandomChar() {
30. int temp = 97 + random.nextInt(26);
31. return (char) temp;
32. }
33. } …
34. }
#p#分页标题#e#
这个线程很简朴:按期建设并启动一个DropCharThread字母下落线程。需要出格说明的是如作甚字母下落线程提供一个随机字母和一个随机栏序号。我们通过一个随机工具java.util.Random的nextInt(int range)要领发生一个0~range-1的整数作为随机栏序号,在第29~32行界说了一个随机发生字母的getRandomChar()要领,因为小写字母a~z的ASCII代码是97~112,第30行即获得一个小写字母所对应的ASCII代码,通过第31行强制范例转换就可获取一个随机的小写字母字符。
在每次轮回时,都判定游戏是否被暂停,假如暂停,则线程进入睡眠,暂停发生字母下落线程,如第8~13行所示。为了统一游戏总体的节制,所以这个线程也通过canvas工具举办同步,在其他处所挪用canvas.notifyAll()要领后,暂停的线程就复苏出来,继承事情。
在第18行,线程睡眠一小段时间,通过TypeTrainApplet的generateInterval成员变量就可以节制字母下落线程下落的速度,这个参数可以直接通过网页<param name = "generateInterval" value = "500">指定其值。
4、响应用户按键事件
所谓击中下落的字母,等于用户按下键盘中的一个键所对应的字母和某个字母下落线程的字母是一致的,对应的字母下落线程竣事并将击中数递增1。
要让游戏自动监测到用户所按的按键,就需要Applet响应键盘按键事件,下面我们来为Applet生成按键事件的处理惩罚要领。
打开TypeTrainApplet.java,切换到Design视图页中,在布局窗格的组件树中选择this(BorderLayout)节点,切换属性查察器到Event标签页中,双击keyPressed项,如下图所示:
图 12 为Applet生成响应按键的事件处理惩罚要领
此时,JBuilder为Applet生成了一个按键事件监听器,并切换到Source视图页并将光标定位到事件处理惩罚要领中,在要领中键入如下粗体的代码。
1. …
2. public class TypeTrainApplet extends JApplet {
3. …
4. /**获取用户点击按键所对应的字符*/
5. public void this_keyPressed(KeyEvent e) {
6. if (!e.isActionKey()) {
7. pressKeyChar = e.getKeyChar();
8. }
9. }
10. …
11. }
第6行判定按键是否字符的按键,假如是在第7行中获取按键所对应的字符。
节制游戏
至此,我们已经完成了Applet主要成果的开拓,剩下的事情是如何通过按钮节制游戏。在编写节制代码之前,先为开始/暂停按钮(jButton1)和遏制按钮(jButton2) 装饰一下,再编写节制代码。
1、为按钮添加图标
需要筹备3张按钮的图标,图标为gif名目,尺寸巨细为25×24象素。
·:jButton1在竣事和暂停状态的图标,定名为start.gif。
·:jButton1在游戏处于运行状态的图标,定名为pause.gif。
·:jButton2的图标,定名为stop.gif。当游戏处于暂停或运行状态时,jButton2才被激活。
将这些文件安排在TypeCharApplet.java源文件的目次下,即<工程根目次>/src/game目次下。
下面的代码利用java.awt.ImageIcon引用这3个图标,并在jbInit()中将图标显示到按钮上,如下所示:
代码清单 7 界说3个图标变量
1. …
2. public class TypeTrainApplet extends JApplet {
3. …
4. ImageIcon startIcon = new ImageIcon(TypeTrainApplet.class.getResource("start.gif"));
5. ImageIcon pauseIcon = new ImageIcon(TypeTrainApplet.class.getResource("pause.gif"));
6. ImageIcon stopIcon = new ImageIcon(TypeTrainApplet.class.getResource("stop.gif"));
7. …
8. private void jbInit() throws Exception {
9. …
10. jButton1.setIcon(startIcon);//配置开始按钮的图标
11. jButton2.setIcon(stopIcon);//配置遏制按钮的图标
12. jButton2.setEnabled(false);//将遏制按钮图标置为非激活态
13. …
14. }
15. }
第4~6用前面所述的图片初始化3个图标变量,个中TypeTrainApplet.class.getResource()要领以TypeTrainApplet.class地址目次为相对目次,查询资源文件。
第10~11行别离将开始和竣事图标显示到对应的按钮上,当用户点击开始按钮后,才将jButton1的图标切换为暂停的图标pauseIcon。
2、通过按钮事件节制游戏
由于字母下落线程通过监测statusCode的值抉择竣事或暂停,所以我们仅需要通过按钮事件变动这个节制变量就可以到达节制游戏的目标了。
#p#分页标题#e#
首先,我们打开TypeTrainApplet.java切换到Design的UI设计界面中,双击jButton1按钮,JBuilder自动为jButton1添加一个按钮点击事件监听器,并切换到Source视图中,将光标定位到事件处理惩罚要领处,我们在要领中添加以下粗体的代码:
代码清单 8 开始/暂停按钮事件处理惩罚要领
1. …
2. public class TypeTrainApplet extends JApplet {
3. …
4. public void jButton1_actionPerformed(ActionEvent e) {
5. if (statusCode == 0) { //从竣事->开始
6. resetGame();
7. statusCode = 1;
8. colWidth = canvas.getWidth() / columnCount;
9. //实例化字母下落线程发生器
10. GenerateDropThread gdThread = new GenerateDropThread();
11. gdThread.start();//发生器启动
12. jButton1.setIcon(pauseIcon);//切换为暂停的图标
13. jButton2.setEnabled(true);//遏制按钮激活
14. } else if (statusCode == 1) { //从运行->暂停
15. statusCode = 2;
16. jButton1.setIcon(startIcon);
17. } else { //从暂停->运行
18. statusCode = 1;
19. jButton1.setIcon(pauseIcon);
20. synchronized (canvas) {//通过canvas通知所有暂停的线程继承运行
21. canvas.notifyAll();
22. }
23. }
24. this.requestFocus();//Applet接管光标,以便其接管按键事件
25. }
26. …
27. }
在jButton1的按钮点击事件处理惩罚要领里按照statusCode所标识的游戏状态别离举办处理惩罚:
·当statusCode=0时,游戏原处于竣事或未开始的状态,暗示用户执行开始游戏的呼吁。开始一个新游戏的呼吁,将统计数据归0,按照画布当前的宽度和栏数计较出每栏的宽度,实例化一个发生器线程,并切换按钮的图标为暂停图标,将遏制按钮置为激活态。
·当statusCode=1时,游戏原处于运行态,暗示用户执行暂停的呼吁。变动状态并改换按钮的图标。
·当statusCode=2时,游戏原处于暂停态,暗示用户执行暂停后继承游戏的呼吁。变动状态并改换按钮图标,通过canvas工具通知所有暂停的线程。
其次,给遏制按钮jButton2生成以下的事件响应代码:
代码清单 9 遏制游戏的事件处理惩罚代码
1. …
2. public class TypeTrainApplet extends JApplet {
3. …
4. public void jButton2_actionPerformed(ActionEvent e) {
5. statusCode = 0;
6. synchronized (canvas) {
7. canvas.notifyAll();
8. }
9. jButton2.setEnabled(false);
10. jButton1.setIcon(startIcon);
11. }
12. …
13. }
首先变动游戏的状态,在第6~7行向所有处于期待状态的线程发出一个通知,防备线程"睡死"的环境。线程在轮回体的判定语句中判定出statusCode为0后将纷纷退出,所有线程竣事。尔后,将按钮置为非激活状并将开始/暂停按钮切换为开始的图标。
3、生存游戏统计数据
为了演示通过数字签名技能打破Applet安详限制的要领,我们特地设计了一个成果:将游戏的统计数字写入到客户端呆板的D:\result.txt文件中。在UI设计界面中双击jButton3的按钮,为"生存"按钮添加如下的事件处理惩罚要领:
代码清单 10 生存按钮事件处理惩罚要领
1. …
2. import java.io.*;
3. public class TypeTrainApplet extends JApplet {
4. …
5. public void jButton3_actionPerformed(ActionEvent e) {
6. FileWriter fw = null;
7. try {
8. File file = new File("d:\\result.txt");
9. fw = new FileWriter(file);
10. fw.write("总数:" + totalCount + "\n");
11. fw.write("正确数:" + rightCount + "\n");
12. fw.write("失败数:" + errorCount);
13. fw.flush();
14. JOptionPane.showMessageDialog(this, "后果乐成生存到d:\result.txt中",
15. "信息",JOptionPane.OK_OPTION);
16. } catch (IOException ex) {
17. ex.printStackTrace();
18. } finally {
19. try {
20. if (fw != null) {
21. fw.close();
22. }
23. } catch (IOException ex1) {
24. ex1.printStackTrace();
25. }
26. }
27. }
28. …
29. }
#p#分页标题#e#
至此,我们就完成了整个游戏的开拓进程,Rebuild事件工程,在<工程根目次>/classes文件夹下双击打开Applet领导为我们所生成的TypeTrainApplet.html网页,如果你呆板已经安装了JRE,我们的指法操练游戏将在网页中打开,点击开始按钮玩伙本身亲手建造的游戏,如下图所示:
图 13 在网页中运行指法操练Applet游戏
点击遏制按钮遏制游戏,试着点击"生存"按钮,将统计数据生存到D:\result.txt中,你将会在Java节制台中看到一个安详异常信息,如下图所示:
图 14 Applet的成果被安详打点器限制
因为一般的Applet运行在称为"沙盒"的安详模块下,Applet固然在客户端呆板上运行,但至多只是一个"外来客",客户机没有将其看成"自家人"来看待。所以Applet不能执行会见当地文件系统、执行当地措施,生存统计数据到文件也就产生异常了。在本章后头,我们将具体先容如何通过数字签名的技能来绕过Applet的安详限制,让客户机将这个"外来客"宾至如归。
4、存眷Applet生命周期
Applet在欣赏器中运行时,第一次加载Applet,将挪用init()要领,接着挪用start(),当窗口封锁或页面替换时先挪用stop()然后再挪用destroy()。
因为我们的游戏是多线程的措施,当封锁欣赏器时,假如Applet的字母下落线程还在运行大概会激发异常。在JBuilder中右击TypeTrainApplet.html,在弹出的菜单中选择Run using default,JBuilder利用AppletViewer运行TypeTrainApplet。启动游戏后直接封锁窗口,在信息窗格中将陈诉以下的异常信息:
java.lang.NullPointerException
at game.TypeTrainApplet$DropCharThread.draw(TypeTrainApplet.java:290)
at game.TypeTrainApplet$DropCharThread.run(TypeTrainApplet.java:258)
这是由于封锁AppletViewer后,TypeTrainApplet画布的Graphics工具先被销毁,而字母下落线程依然挪用会见这个工具,所以抛出空指针异常。
我们可以通过Applet的生命周期办理这个问题:Applet在被封锁前会挪用stop()和destroy()要领。我们只要操作stop()要领就可以了,在stop()要领中置一个标识,线程通过判定这个标识就可以知道当前窗口是否封锁,当发明封锁时就不再运行。
1. public class TypeTrainApplet extends JApplet {
2. …
3. boolean isClose = false;//用于标识Applet窗口有没有封锁
4. …
5. public void start() {
6. isClose = false;
7. }
8.
9. public void stop() {
10. statusCode = 0;//遏制游戏
11. isClose = true;//窗口封锁
12. }
13. …
14. private class DropCharThread extends Thread {
15. if(isClose) return ;//发明窗口封锁顿时返回
16. draw(ACTION_DRAW_FONT);
17. try {
18. while (c != pressKeyChar && y < canvas.getHeight() &&
19. statusCode != 0) {
20. synchronized (canvas) {
21. while (statusCode == 2) {
22. canvas.wait();
23. }
24. }
25. draw(ACTION_CLEAR_FONT);
26. y += stepLen;
27. draw(ACTION_DRAW_FONT);
28. Thread.sleep(stepInterval);
29. }
30. } catch (InterruptedException ex) {
31. }
32. if (!isClose) {//窗口没有封锁才后续处理惩罚
33. draw(ACTION_CLEAR_FONT);
34. if (statusCode != 0) { //游戏没有遏制
35. totalCount++; //统计总数
36. if (y < canvas.getHeight()) {
37. hitSound.play();
38. rightCount++; //击中
39. } else {
40. errorCount++; //打不中
41. }
42. drawResult();
43. }
44. }
45. }
46. }
Applet启动时挪用start()要领,这要领里将窗口封锁标识置为false,如第6行所示,而当窗口封锁时stop()要领被挪用,遏制游戏并置窗口封锁标识,如第10~11行所示。字母下落线程的措施也要作相应的调解,在进入线程和竣事线程都判定是否封锁了窗口。
打包并举办数字签名
#p#分页标题#e#
欣赏器对Applet的数字签名支持并没有一个统一的尺度,可是一些著名的欣赏器如IE和Navigator对举办数字签名的Applet都可以开放大部门的权限。要对Applet举办数据签名必需先将Applet类和资源打成一个JAR包。
JBuilder提供一个Applet的打包领导,在领导的最后一步可以指定一个数据证书对最终生成的JAR包举办签名。所以在这一节里,我们先先容数字签名的技能,尔后再讲授如何利用JBuilder的Applet打包领导。
1、数字签名技能
数字签名涉及到以下几个根基的观念:
·动静摘要
动静摘要是对原始数据凭据必然算法举办计较获得的功效,它主要检测原始数据是否被修悔改。动静摘要与加密差异,加密是对原始数据举办调动,可以从调动后的数据中得到原始数据,而动静摘要是从原始数据中得到一部门信息,它比原始数据少得多,因此动静摘要可以看作是原始数据的指纹。
·动静验证码
当甲和乙通信时,甲将数据传给乙时,同时也将数据的动静摘要传给乙,乙收到后可以用该动静摘要验证甲传的动静是否正确。这时会发生问题,即若通报进程中别人修改了数据时,同时也修改了动静摘要。乙就无法确认数据是否正确。动静验证码可以办理这一问题。 利用动静验证码的前提是 甲和乙两边有一个配合的密钥,这样甲可以将数据计较出来的动静摘要加密后发给乙,以防备动静摘要被改。由于利用了配合的密钥,所以称为"验证码"。
·数字签名
利用动静摘要和动静验证码两种技能可以担保数据没有颠末改变,但吸收者还无法确定命据是否确实是某小我私家发来的。尽量动静码可以确定命据是某个有同样密钥的人发来的,但这要求两边具有共享的密钥,若有一组用户共享,我们就无法确定命据的来历了。
数字签名等于被设计用来办理这个问题的技能。数字签名操作非对称加密技能,发送者利用私钥加密数据发生的动静摘要(签名),吸收者利用发送者的公钥解密动静摘要以验证签名是否是某小我私家的。由于私钥只有加密者才有,因此假如吸收者用某个公钥解密了某个动静摘要,就可以确定这段动静摘要一定是对应的私钥持有者发来的。
·数字证书
利用数字签名的前提是吸收数据者可以或许确信验证签名时(用发送者的私钥加密动静摘要)所用的公钥确实是发送者本人的,这需要通过数字证书来办理这个问题。
数字证书含有两部门数据:一部门是对应发送者(组织或小我私家)的信息,另一部门是这个发送者所对应的公钥。即数字证墨客存了发送者和其公钥一一对应的干系。同样,数字证书也有大概被捏造,有效的数字证书必需颠末权威 CA的签名,即权威CA验证数字证书的内容的真实性,然后再在数字证书上利用权威CA本身的私钥签名,相当于在发送者的证书上盖印。
其实数字签名技能是现实糊口在计较机规模的反应,我们不妨通过一个小故事将这此技能反向映射到糊口中。
《永不用失的电波》是60年月一部著名的影戏,报告了1938年我党地下组织在国统区上海的电台被仇人粉碎了,延安解放区我军电台政委李侠衔命前往的上海,增强奥秘电台的事情,为了担保上海地下党组织可以或许正确联系到真实的李侠而不被仇人蒙骗,我们不妨来设定这样的一个情节,李侠身上带一封先容其身份的先容信,这相当于动静摘要,还约定了讨论灯号:地下党讨论中说"山上杜鹃红艳艳",李侠则要接"山下溪水细潺潺",那么这个灯号就是"动静验证码"。而在李侠的先容信上有延安电台台长的签名,这个就是"数字签名",签名之上还加盖了一个延安电台的公章,这个就是数字证书。尚有一份证名电台公章的文件那就是CA证书了。虽然实际环境大概只需要一个灯号,太多对象反而会在动作中袒露身份,但在计较机规模这些对象都是须要的。
2、数字证书的生成
在JBuilder的Applet打包领导中仅需要一个数字证书,领导会为最终的JAR包生成动静摘要、动静验证码并签名。通过JDK自带的Keytool东西可觉得生成一个数据证书,这个东西位于JDK的bin目次下。
打开DOS定名窗口,定位到JBuilder 2005下自带的JDK的bin目次下,执行下面的Keytool定名生成一张本身的证书:
C:\Borland\JBuilder2005\jdk1.4\bin>keytool -genkey -alias chenxhCA -keyalg RSA -keystore superCALib -validity 3650
呼吁窗口将要求你输入一些小我私家书息如下图所示:
图 15 生成数字证书的呼吁窗口
#p#分页标题#e#
这里我们利用keytool东西生成了一个名为chenxhCA的证书,它存放到superCALib证书库中,有效期为10年,利用的加密算法上RSA。证书库superCALib的会见暗码是123456,而chenxhCA证书条目标会见暗码是123123。在输入作为发送者身份标识的信息后就会在当前方针,即C:\Borland\JBuilder2005\jdk1.4\bin下生成一个名为superCALib的证书库文件。
keytool参数较多,利用也较量巨大,具体利用说明,请拜见Sun网站的辅佐文档:
http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/keytool.html。
一般环境下你还需要将该证书发给权威的CA签名,这个证书才会被视为正当的证书,虽然你也可以模仿建设一个CA证书,用这个CA证书为我们将用于签发Applet的chenxhCA证书签名,为了简朴起见我们忽略这一步。
3、打包
此刻已经万事俱备了,我们可以开始操作JBuilder的打包领导将Applet所以文件打包并签名的进程。
1) File->New…->Archive,在Archive页中双击Applet JAR图标启动Applet打包领导。
2) 在领导第1步中指定Applet JAR的名字和生存到方针文件,如下图所示:
图 16 指定文件名
为了加快网络下载速度,我们勾选上Compress the contents of the archive选项,压缩JAR文件,减小文件的体积。Always create archive when building the project选项利用每次编辑工程时都从头建设Applet JAR包。点击Next到下一步。
3) 在这一步里,指定JAR文件中所需包括的资源文件。
由于TypeTrainApplet措施引用了3张图片,所以JAR文件除包括TypeTrainApplet.class措施文件外,还需要将用于按钮图标的文件选择进来,如下图所示:
图 17 指定JAR的内容
按Next到下一步。
留意:
当你指定game.TypeTrainApplet.class,start.gif,pause.gif,stop.gif,hit.wav时,打成的Applet JAR包将不能正确运行,那些和TypeTrainApplet类位于同一措施文件的事件监听器类将被解除在外,所以需要通过game/*.*来打包。
4) 由于领导第3~6步,我们不需要作出格的配置,所以一直按Next到第7步。
在这一步里,我们用上一小节中生成的数字证书签名Applet的方针JAR文件,如下图所示:
图 18 指定如何对JAR举办签名
·Digitally sign this archive选项在默认的环境下是未选中的,首先勾选该选项
·点击Keystore后的…按钮,选择我们适才在C:\Borland\JBuilder2005\jdk1.4\bin目次下所生成的superCALib证书库文件。
·在Keystore password中输入123456,即证书库的暗码。
·点击Alias后的…按钮,由于我们在superCALib证书库中仅有一个chenxhca证书,所以在弹出的Select Alias对话框的Available Alias列表中仅有一个chenxhca选项,选择chenxhca证书。
·在Alias password中输入123123,即chenxhca证书的私钥暗码。
·在Store type中输入JKS,由于Keytool东西的默认证书库范例是JKS,所以superCALib的范例为JKS。
在配置完今后的信息后,按Finish竣事领导,在工程窗格的资源树中将呈现一个TypeTrainJAR的节点。右击这个节点,在弹出的菜单中选择Rebuild,JBuilder将建设Applet的JAR包,并用chenxhca证书签名。
Rebuild完成后,工程窗格的TypeTrainJAR节点就可以展开了,展开这个节点,我们发明方针JAR文件中除了资源文件以外,在META-INF文件夹下尚有3个文件,如下图所示:
图 19 方针JAR中关于签名的文件
META-INF文件夹下的3个文件是和数字签名有关的文件,说明如下:
·MANIFEST.MF:这个 manifest 文件界说了与扩展和包相关的数据。
·CHENXHCA.SF:这是 JAR 文件的签名文件,文件名标识了签名者。
·CHENXHCA.RSA:与签名文件相关联的签名措施块文件,它存储了用于签名 JAR 文件的民众签名。
4、在文件中引用Applet包文件
我们此刻来变动TypeTrainApplet.html中<applet>的属性使其通过JAR来引用Applet措施。这个进程很扼要,打开TypeTrainApplet.html文件,切换到Source视图页中,将光标定位在<applet>标签中。窗口右边呈现<applet>标签的属性输入编辑器,在archive中输入game.JAR,按回车。
图 20 变动网页的<applet>标签属性
#p#分页标题#e#
JBuilder为<applet>标签添加archive的属性。由于game.JAR文件位于工程根目次下,而TypeTrainApplet.html文件位于工程目次的classes子文件夹下,所以需要将TypeTrainApplet.html拷贝到工程根目次下,这样archiver="game.JAR"的属性声明才是正确的,因为在寻找措施资源时,是以TypeTrainApplet.html地址目次为相对路径的。
生存后,到工程目次下双击TypeTrainApplet.html文件,IE检测到网页中包括了颠末签名的Applet措施,弹出一个安详告诫的对话框,如下图所示:
图 21 IE在运行签名的Applet前的安详告诫
由于我们的证书没有颠末权威机构的签名认证,所以对话框提示"此安详证书是由不行信的公司签发的"信息。需要指出的是游览器的JRE版本差异,弹出的告诫对话框并不沟通,上图是JRE版本为1.5.0时的告诫对话框。
可以通过点击"更多具体信息"按钮查察证书的信息,如下图所示:
图 22 签名证书的信息
点选"签发人"项,将可以看到证书执有者的小我私家书息。封锁这个对话框,回到"告诫-安详"对话框中,点击"是"接管这个签名的Applet。IE就对这个Applet开放了安详权限,不再受沙盒模子的限制了。
试着启动游戏,玩一伙儿后,点击"生存"按钮,Applet将正确地将统计数据生存到D:\result.txt文件中。
利用插件下载JRE
假如客户端游览器还未安装JRE或已安装的JRE版本低于你Applet的要求,或欣赏器自带的JRE不是Sun公司尺度的Applet,你Applet都大概无法正常运行。可以通过JDK自带的HtmlConverter.exe东西对带Applet的HTML文件举办转换,转换后的文件可以指定欣赏器在运行Applet时将特定版本的JRE以插件的方法下载并安装,就象带Flash插件或SVG插件一样。
我们先从game工程根目次的classes目次下,拷贝TypeTrainApplet.html到game工程根目次下,以使其和game.jar位于同一个目次。
HtmlConverter.exe东西位于JDK的bin目次下,我们利用JDK5.0下的,导航到JDK5.0所安装的bin目次中,双击HtmlConverter.exe,稍等半晌,将弹出如下的对话框:
图 23 HTML转换东西
1.点击"指定文件或目次路径"后的"欣赏…"按钮,选择工程目次下的TypeTrainApplet.html。
2."将文件备份到文件夹"指定了将未转换前的TypeTrainApplet.html文件备份到的目次。
3.在"模板文件"中配置转换模板,按照你客户端用户地址的平台和利用的欣赏器选择相应的选项。这里我们选择"只合用Windows和Solaris的尺度组件(IE和Navigator)"。
4.点选"利用任何Java1.5,或更高版本",这样Java plug-in插件将利用JER1.5版本,这样将利用JRE1.5系统最新的版本,假如选择"JRE1.5.0"将保持插件版本稳定,则不会去更新。
5.点击"转换(C)…"开始转换,原始的TypeTrainApplet.html被备份到备份文件夹下,在原位置的TypeTrainApplet.html已经被转换的功效包围。
提示:
假如你想利用JRE1.4或JRE1.3作为插件,则需要利用JDK1.4或JDK1.3所带的转换器举办转换。
打开转换后的TypeTrainApplet.html文件内容如下所示:
代码清单 11 转换后的TypeTrainApplet.html
1. <html>
2. <head>
3. <meta http-equiv="Content-Type" content="text/html; charset=GBK">
4. <title>HTML Test Page</title>
5. </head>
6. <body>game.TypeTrainApplet will appear below in a Java enabled browser.
7. <br>
8. <!--"CONVERTED_APPLET"-->
9. <!-- HTML CONVERTER -->
10. <object
11. classid = "clsid:CAFEEFAC-0015-0000-0000-ABCDEFFEDCBA"
12. codebase =
13. "http://java.sun.com/update/1.5.0/jinstall-1_5_0-windows-i586.cab#Version=1,5,0,0"
14. WIDTH = "400" HEIGHT = "400" NAME = "TestApplet" ALIGN = "middle" VSPACE =
15. "0" HSPACE = "0" >
16. <PARAM NAME = CODE VALUE = "game.TypeTrainApplet.class" >
17. <PARAM NAME = CODEBASE VALUE = "." >
18. <PARAM NAME = ARCHIVE VALUE = "game.JAR" >
19. <PARAM NAME = NAME VALUE = "TestApplet" >
20. <param name = "type" value = "application/x-java-applet;jpi-version=1.5">
21. <param name = "scriptable" value = "false">
22. <PARAM NAME = "stepLen" VALUE="2">
23. <PARAM NAME = "stepInterval" VALUE="50">
24. <PARAM NAME = "columnCount" VALUE="10">
25. <PARAM NAME = "generateInterval" VALUE="500">
26.
27. <comment>
28. <embed
29. type = "application/x-java-applet;jpi-version=1.5" \
30. CODE = "game.TypeTrainApplet.class" \
31. JAVA_CODEBASE = "." \
32. ARCHIVE = "game.JAR" \
33. NAME = "TestApplet" \
34. WIDTH = "400" \
35. HEIGHT = "400" \
36. ALIGN = "middle" \
37. VSPACE = "0" \
38. HSPACE = "0" \
39. stepLen ="2" \
40. stepInterval ="50" \
41. columnCount ="10" \
42. generateInterval ="500"
43. scriptable = false
44. pluginspage = "http://java.sun.com/products/plugin/index.html#download">
45. <noembed>
46.
47. </noembed>
48. </embed>
49. </comment>
50. </object>
51.
52. <!--
53. <APPLET CODE = "game.TypeTrainApplet.class" JAVA_CODEBASE = "." ARCHIVE
54. = "game.JAR" WIDTH = "400" HEIGHT = "400" NAME = "TestApplet" ALIGN =
55. "middle" VSPACE = "0" HSPACE = "0">
56. <PARAM NAME = "stepLen" VALUE="2">
57. <PARAM NAME = "stepInterval" VALUE="50">
58. <PARAM NAME = "columnCount" VALUE="10">
59. <PARAM NAME = "generateInterval" VALUE="500">
60. </APPLET>
61. -->
62. <!--"END_CONVERTED_APPLET"-->
63. </body>
64. </html>
#p#分页标题#e#
第13行指定了下载JRE插件的地点,假如没有安装这样的版本,将自动下载当前 JRE 1.5 系列的缺省下载版本,假如不能自动安装,则将用户引导到下载页面中,用户可以手工下载JRE,下载页面在第44行指定。
假如你的Applet最终陈设在一个Web处事器中,且Web处事器位于局域网中,则你事先可以将JRE1.5.0下载下来,安排到Web处事器的上下文中,并变动第13行和第44行的路径。
提示:
将jinstall-1_5_0-windows-i586.cab下载并安排到本身的Web处事器中,相应变动<object>的codebase属性值,并不会乐成自动安装JRE1.5.0,因为jinstall-1_5_0-windows-i586.cab并未包括JRE1.5.0的安装措施,而是通过cab文件中的jinstall-1_5_0.inf文件声明按照http://java.sun.com/update/1.5.0/1.5.0-b64.xml的设置信息,从Sun网站下载后安装。假如你Web处事器地址的局域网不能直接会见Sun网站,安装进程将无法安成。你需要变动cab文件中的jinstall-1_5_0.inf文件,下载并变动1.5.0-b64.xml设置文件才可以使局域网的客户端到你本身的Web处事器指定地点下载。
假如Applet是在jsp而非html文件中挪用,则可以利用<jsp:plugin>标签来引用applet,以使applet以插件方法引用JRE。关于<jsp:plugin>的利用要领,请查察jsp相关书籍。
总结
我们报告了如安在JBuilder开拓一个简朴的Applet指法操练游戏措施的进程,固然这个游戏在成果上属于不敢见公婆型,但它涵盖了Applet开拓的大部门内容和能力。我们特在Applet中配置了一个不安详的成果:在客户呆板中生存文件,欣赏器事先绝不包涵地阻截了它,而后我们通过数字签名技能晓之以情,动之以理"说服"了欣赏器打消安详限制。
大千世界,纷繁巨大,客户端欣赏器的JRE版本和厂家百家争鸣,百花齐放,为了使我们的Applet可以或许在Sun尺度的JRE1.5.0的版本上运行,我们动用了JDK自带的转换器对原html举办转换,这样尺度的JER1.5.0将作为插件的形式下载并安装以支持这个难伺候Applet。