分享
 
 
 

如何实现Applet之间跨浏览器窗口的通信

王朝other·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

java.applet包的AppletContext类包含如下两个成员方法:getApplet和getApplets。使用这两个方法,Applet能够寻找到其他的Applet并调用它们的方法。不过这是以满足如下安全条件为前提的:

所有Applet位于同一服务器的同一目录。

所有Applet运行在同一页面且位于同一浏览器窗口内。

或许为Applet加上这些安全限制都有着很充分的理由,但第二个条件给我们实现带有Applet到Applet通信功能的多Applet界面带来了限制。

请设想如下情形:

你刚好编写完了一个用于股票交易的Applet,接下来想要为它做一个完善的帮助系统。这个帮助系统也是一个Applet,而且应该放到和股票交易Applet不同的另外一个帧里。你作出这个决定的原因可能是出于网站整体结构的考虑,也可能是你想让帮助系统总是处于显示状态。你还想让帮助Applet能够自动根据用户的当前操作切换到相应的帮助条目(就象Microsoft Office帮助系统提供的那样)。此外,你甚至还计划着在帮助系统里做一个向导,使它能够在另外一个窗口中指导用户如何完成股票交易Applet里的各种任务。

应当承认这种设想是非常美妙的。然而,由于这些Applet位于不同的页面,AppletContext中的Java API无法帮助你完全实现这种设想——不过本文介绍的技术能够。

在介绍新的Applet到Applet通信方法之前,我们先要简要地介绍一下getApplet和getApplets这两个方法的用法。Applet能够寻找到同一页面的其他Applet,这既可以调用getApplet方法通过名字查找,也可以调用getApplets方法找出同一页面内的所有Applet。这两个方法都在调用成功时返回一个或多个Applet对象给调用者。调用者找到目标Applet对象之后,接着就可以调用它的公用方法。

假设Html页面的代码片断如下:

通过APPLET标记的name属性,我们可以用如下代码引用指定的Applet:

Applet theOtherApplet = getApplet("app1");

//调用该Applet的公用方法

theOtherApplet.anyMethod();

或者,我们也可以用下面的代码提取页面内的所有Applet:

Enumeration allAppletsOnSamePage = getApplets();

while(allAppletsOnSamePage.hasMoreElements()) {

Applet appl = (Applet) allAppletsOnSamePage.nextElement();

// 调用Applet的公用方法

appl.anyMethod();

}

当发出调用的Applet提取到同一HTML页面内的一个或多个Applet对象时,它就可以调用这些Applet对象的公用方法。

遗憾的是,使用这种标准方法我们只能实现同一页面内的Applet通信。但假如幸运的话,我们可以很方便地突破这一局限。实现跨页面Applet到Applet通信基于这样一个事实,即假如两个Applet具有相同的codebase,那么即使它们运行在不同的浏览器窗口中,它们也将共享同一个运行时环境。所谓的codebase,我们可以粗略地把它看成Applet所在的服务器目录,请参见本文后面参考资源中有关codebase示范的链接。

共享运行时环境使得类的静态域和结构能够被所有的Applet实例访问,因此,我们可以用这些静态域和结构在不同的Applet之间传递信息。

我们不仅可以把简单数据类型——比如整数、字符、字符串存储到这些静态域,而且还可以存储Applet实例本身的引用,这样,其他的Applet就可以通过访问这些静态域得到该Applet实例的引用。

这种方法非常复杂吗?事实上,它并不复杂。下面我们来看一个简单的例子。假设有两个Applet(AppletA.class和AppletB.class)位于不同的帧,但它们具有相同的codebase。

现在我们要从AppletA里面访问AppletB的公用方法。首先我们要在AppletB里面把它自己的引用保存到一个静态公用域,如:

public class AppletB {

public static AppletB selfRef = null; // Initially zero

public void init() {

// 保存当前实例的引用

selfRef = this;

}

...

}

现在AppletA可以访问AppletB的实例:

public class AppletA {

AppletB theOtherApplet = null;

public void callAppletB() {

// 获得静态域的值,这个静态域保存了

// AppletB实例的引用

theOtherApplet = AppletB.selfRef;

// 接下来就可以调用AppletB实例

// 的方法,例如:

theOtherApplet.repaint();

}

...

}

这样就实现了两个Applet的通信。由于不同的Applet共享运行时环境,因此即使这些Applet位于不同的页面,这种方法也同样有效。

不过应当注重的是,上面的代码不能处理这种情况:在AppletB没有启动之前就在AppletA里面调用callAppletB方法。假如发生这种情况,则selfRef的值将是null,Applet之间的通信不能正常进行。

当然,我们还可以设计出更加通用的方法。我们可以创建一个类,这个类的唯一用途就是在自己的静态数据结构中保存其他Applet的引用。下面是一个参考实现AppletList。想要让其他Applet访问自己的公用方法的Applet实例首先要在AppletList中注册。按照AppletContext.getApplet(string name)方法的处理模式,每个注册的Applet都和一个字符串相关联。以后当其他Applet需要引用某个Applet实例时,这个字符串就可以作为键(即Applet的标识)使用。

下面是Applet在AppletList中注册的典型过程:

public class AppletA {

public void start() {

AppletList.register("Stock-trade-applet", this);

...

}

}

其他Applet访问已注册Applet的过程如下:

public class AppletB {

public void run() {

AppletA tradeApplet =

(AppletA) AppletList.getApplet("Stock-trade-applet");

...

}

}

当Applet结束运行时它必须从ApplietList取消注册:

public void stop() {

AppletList.remove("Stock-trade-applet");

...

}

AppletList类的完整代码如下:

0: import java.util.*;

1: import java.applet.Applet;

2:

3: public class AppletList {

4: PRivate static Hashtable applets = new Hashtable();

5:

6: public static void register(String name, Applet applet) {

7: applets.put(name,applet);

8: }

9:

10: public static void remove(String name) {

11: applets.remove(name);

12: }

13:

14: public static Applet getApplet(String name) {

15: return (Applet) applets.get(name);

16: }

17:

18: public static Enumeration getApplets() {

19: return applets.elements();

20: }

21:

22: public static int size() {

23: return applets.size();

24: }

25: }

请从本文后面下载exampleCode.zip了解更多有关如何应用AppletList类的信息。

本方法的局限

如前所述,参与通信的Applet必须具有相同的codebase。此外,假如你运行的是两个不同的浏览器副本且Applet分别运行于这两个浏览器中,由于这些Applet可能没有共享运行时环境(这和浏览器版本、设置有关),因此它们可能不能进行通信。然而,假如你是从同一个浏览器创建出新的浏览器窗口,那么这个问题是不存在的。

本文所介绍的技术已经顺利通过好几个平台和浏览器版本的测试,但导致多个Applet拥有各自的运行时环境的配置还是存在的。顺利通过测试的操作系统和浏览器组合如下所示:

小结

本文介绍了一种新的实现Applet到Applet通信的方法,这种方法在无法使用Java API的getApplet()方法时仍然有效。把握了这种方法,你就有更多的机会在Web网站或Intranet上使用Applet——用它来替换getApplets方法,或者补充getApplets方法的不足。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有