45fan.com - 路饭网

搜索: 您的位置主页 > 电脑频道 > 电脑教程 > 阅读资讯:Applet间的通讯的详细分析

Applet间的通讯的详细分析

2016-08-28 17:55:28 来源:www.45fan.com 【

Applet间的通讯的详细分析

 

 

Tricks
of the
Java Programming Gurus

by Glenn L. Vanderburg. et al.

1.Applet间的通讯

 


目录

  • getApplet: 官方机制
  • 静态变量和方法
  • 网络通讯
  • 基于线程的通讯
  • 总结

考虑到你要完成的任务,一个applet,甚至几个独立的applet,有时可能都不够。还好,applet之间可以通讯,通过协作它们可以完成一些更复杂的任务。一组协作的applet所能产生的效能使单个applet所不能媲美的。

Applet之间的通讯可以通过传统方法实现:applet可以互相调用对方的成员方法或者通过socket或数据流通讯。事实上,applet间互相查找的途径有很多,每一种方法都有自身的优缺点。本文将讨论四种通讯机制,并给出一个较为复杂的例子,在这个例子中我们将使用其中一种通讯机制。

getApplet: “官方”机制

Java API 本身就有用来支持applet程序间协作的特性:AppletContext 类的 getAppletgetApplets 方法。设有这两个函数,applet程序可以通过名称查找并访问对方。你可以这样调用 getApplet

Applet friend = getAppletContext().getApplet("Friend");

一旦调用结束,变量 friend 就成了名为"Friend"的applet的一个实例(instance) (如果这样的一个"Friend"applet存在的话)。例如:如果 "Friend" 是 Sun的 Animator applet 的一个实例,friend 将包含对这个实例的一个参考(reference)。

Applet的名字是在HTML中指定的,而不是在Java代码中。为了创建一个能被前面的实例代码所发现的animator applet,你可以在HTML插入如下几行:

<applet code="Animator.class" width=25 height=25 name="Friend">
<!-- applet parameters go here -->
</applet>

getApplets 方法和 getApplet 差不多,只不过getApplets返回一个Enumeration,其中列举了所有可以进行访问的applet。然后我们就可以根据applet的不同属性来查询一个applet,包括applet的名字。下面示范了如何用getApplets查找一个名为"Friend" 的applet:

Applet friend;
for( Enumeration e = getAppletContext().getApplets();e.hasMoreElements();){
try {
Applet t = (Applet) e.nextElement();
if ("Friend".equals(t.getParameter("name"))) {
friend = t;
break;
}
}
catch (ClassCastException e) {
}
}

显然,上述方法的工作很多,你不会用这种途径去查找一个applet。然而,如果你要查询多个applet,或是你不知道你所要查找的applet的确切的名字,这将是一种行之有效的方法。举个例子来说,用getApplets查找所有以"Helper­"开头命名的applet将会很容易,你的applet就可以和同一页面中的所有的helper applet通讯了。

不幸的是,这种官方推荐的applet通讯机制至少有两大问题。首先,这种机制目前并没有被具体化,因此不同的应用程序对该机制有不同的实现。例如,getApplets 返回的是可以访问的applet,但是什么是可以访问?没有明确的定义。你可能得到的是同一页面上的applet,从同一个站点加载的applet,或者是两者的交集,这些都取决于运行applet的浏览器。这些问题因该促使Sun和Java's licensees制定出一个更加严密的,明确定义的applet协作机制。不过目前为止,这种applet通讯及值的不一致实现仍然是个令人头痛的问题。

另外一个问题就没有这么简单了。它看起来很容易理解,但它会使事情复杂到令很多applet程序员吃惊的地步。问题出在 getAppletgetApplets 不会让你得到一个还没有完全加载并初始化了的applet。由于网络的不确定和其他因素,例如applet的大小,我们不能决定页面上哪一个applet首先被加载,哪一个最后被加载。这就意味着我们原来的计划:首先启动并控制一个applet,查找其他applet,然后同它们协作,如果不增加额外的处理的话,是不能够达到预期目的的。

当然了,解决上述问题有很多方法。控制applet可以检查它的协作伙伴,如果它们还没有就绪,就进入等待睡眠(一秒钟左右),然后再次协作applet的状态,直到所有协作成员都已被初始化过。虽然这种方法效率很低,会导致较长的启动时间,怎么说它还是有效的。一个更好的解决方法是“双向查找、提醒机制”(two-way search-and-notification mechanism),当一个applet初始化完成后,控制这个applet查找其他applet并通知它们“我准备好了”。使用这种机制,所有辅助applet(helpers initialize)初始化完成后,主控applet将能够立即找到它们并开始协作,如果哪个辅助appplet迟一步完成初始化,主控applet也会被及时通知。

静态变量和方法

很多情况下,我们可以通过使用一个通用类的静态成员变量和方法构造一个内部applet通讯机制。如果多个applet都依赖于这个通用类,它们就可以把这个类作为一个消息的汇集点(rendezvous point),在那里注册它们的存在并察看其他applet的存在。

这里有个例子。如果在一个页面上ColorRelay applet被使用多次,不同的实例通过协作显示不同的图片(一些不同颜色的打字机色带)。你可以想象这些applet依靠一个标志位。如果一个applet显示了彩色的图片,其他的只能现实黑白的图片。图 1.1 是运行时的截图,清单 1.1 是 HTML 代码。

图 1.1 : ColorRelay applet 运行中

Applet间的通讯的详细分析


清单 1.1. ColorRelay.html.
<html>
<body>
<h1>Used Applets Sale!</h1>

<p>
<applet align=baseline code="COM.MCP.Samsnet.tjg.ColorRelay.class"
width=50 height=50 name="first">
<param name="flashColor" value="0x0000ff">
<param name="sleepTime" value="1">
<param name="image" value="spiral.gif">
</applet>
Low, low prices!

<p>
<applet align=baseline code="COM.MCP.Samsnet.tjg.ColorRelay.class"
width=50 height=50>
<param name="flashColor" value="0x00ff00">
</applet>
This week only!

<p>
<applet align=baseline code="COM.MCP.Samsnet.tjg.ColorRelay.class"
width=50 height=50>
<param name="flashColor" value="0xff0000">
<param name="sleepTime" value="3">
</applet>
We won't be undersold!

</html>

清单 1.2 展示了 ColorRelay applet的程序框架,具体方法用注释代替了。我们将在后面的清单中提供完整的代码。


清单 1.2. ColorRelay.java (part 1).
/*
* ColorRelay.java 1.0 96/04/14 Glenn Vanderburg
*/

package COM.MCP.Samsnet.tjg;

import java.applet.*;
import java.awt.*;
import java.awt.image.*;

/**
* An applet which coordinates with other instances of itself on a Web
* page to alternately flash copies of an image in different colors.
*
* @version 1.0, 14 Mar 1996
* @authorGlenn Vanderburg
*/

public class ColorRelay extends Applet implements Runnable
{
// These are used to maintain the list of active instances
static ColorRelay list, listTail;
ColorRelay next, prev;

// This thread switches between instances
static Thread relayer;

// This is the original, unmodified base image which all
// of the instances use.
static Image originalImage;

// The color that this instance uses to flash.White is the default.
Color flashColor = Color.white;

// The modified, colorized image.
Image modifiedImage;

// The image currently being displayed.This reference
// alternates between originalImage and modifiedImage.
Image image;

// We use a media tracker to help manage the images.
MediaTracker tracker;

// The time we wait while flashing.Two seconds is the default.
int sleepSecs = 2;

// Method: static synchronized
//addToList(ColorRelay elem)Listing 1.3
// Method: static synchronized
//removeFromList(ColorRelay elem)Listing 1.3
// Method: public init()Listing 1.4
// Method: public start()Listing 1.5
// Method: public stop()Listing 1.5
// Method: public run() Listing 1.5
// Method: public getAppletInfo() on CD
// Method: public getParameterInfo ()on CD
// Method: public paint(Graphics g) on CD
// Method: public update(Graphics g)on CD
// Method:flash()on CD
// Method:parseRGB(String str)on CD
}

正如你看到的那样,程序中有一些普通的变量:两个Iamge,一个Color,一个MediaTracker,一个时间值,还有两个静态方法用来将 ColorRelay 对象插入链表。此外还有四个静态变量:originalImage, 当applet没有轮到发亮时显示;一个线程对象,用来协调applet之间的活动,还有applet链表的首位节点。

 


未完,待续。

翻译:chenyuan_tongji (chenyuan_tongji@sian.com)

 

本文地址:http://www.45fan.com/dnjc/68941.html
Tags: 间的 通讯 Applet
编辑:路饭网
关于我们 | 联系我们 | 友情链接 | 网站地图 | Sitemap | App | 返回顶部