当前位置: 首页 > 图灵资讯 > 技术篇> 让不同页面的applet之间能够通信

让不同页面的applet之间能够通信

来源:图灵教育
时间:2024-03-07 09:38:48
Java 技巧 101:applet 了解如何使间通信的替代方法 applet 跨框架和浏览器窗口相互通信作者 Tobias Hill 你可能认为可以让步 applet 使用彼此通信的唯一选择是使用 getApplet。不幸的是,getApplet 该方法仅返回并发出调用。 applet 在同一个 HTML 页面上的 applet,这限制了你的通过 applet 构建有趣界面的通信方式。该技能的替代方法可以在不同的框架甚至不同的浏览器窗口中使用 applet 互相调用对方的方法。java.applet 包中的 AppletContext 该类包含两种成员方法,即 getApplet 和 getApplets。通过使用这两种方法,一种 applet 你可以找到别的 applet 并调用它们的方法。必须满足以下安全要求:

这些 applet 来自同一服务器上的同一目录。

 

这些 applet 在同一浏览器窗口的同一页面上运行。

这种设计安全限制可能有很好的原因;然而,后一个要求限制了使用 applet 通信制作有趣多了 applet 界面的方式。

考虑这样的情况:

你刚刚编了一个很好的股票市场交易 applet,并决定为它编写一个良好的帮助系统。您希望帮助系统也是一个 applet,并希望与股票市场交易 applet 在不同的浏览器框架中运行。你的决定可能是出于网站结构的考虑,也可能是出于总是显示帮助系统的需要。此外,您希望根据用户当前的股票交易,帮助系统 applet 将操作转移到正确的信息/指导(就像 Microsoft Office 套件中的“回形针”相同)。您甚至计划在帮助系统中编制导游,可以远程指出问题,远程执行股票市场交易 applet 中的任务。

这个计划反映了很好的想法。但是,因为这两个 applet 在不同的页面上,所以 AppletContext 中的 Java API 你不能帮助你实现这个想法 -- 但是这个技巧可以帮助你。

使用 AppletContext 说明了API applet 在间通信的替代机制之前,我将首先简要解释一下 getApplet 和 getApplets 这两种方法是如何工作的。一个 applet 通过使用 getApplet 根据名字可以找到相同的方法 HMTL 页面中的另一个 applet,而通过使用 getApplets 在同一页面上找到所有的方法 applet。如果这两种方法成功实施,它们将返回一个或多个调用器 Applet 对象。一旦调用者找到了一个 Applet 对象,它可以调用这个对象 Applet 公用方法。

假设有以下段落 HTML 代码:

<applet code=“Applet1” width="400" height="100" name="app1"></applet><br><applet code=“Applet2” width="400" height="100" name="app2"></applet><br>

通过使用 applet 标记中的 name 属性,您可以使用以下方法引用一个特定的特定方法 applet:

Applet theOtherApplet = getApplet(app1);theOtherApplet.anyMethod(); ///调用任何公共方法

或者,您也可以使用以下代码检索页面上的所有代码 applet:

Enumeration allAppletsOnSamePage = getApplets();while(allAppletsOnSamePage.hasMoreElements()) {Applet appl = (Applet) allAppletsOnSamePage.nextElement();appl.anyMethod(); ///调用任何公共方法}

发出调用的 applet 它所在的同一个 HTML 在页面上检索一个或多个页面 applet 之后,它可以调用这些 applet 公用方法。

不幸的是,如果使用标准方法,静态数据结构的使用只能与标准方法相同 HTML 页面中的 applet 通信。幸运的是,你可以很容易地避免这种限制。使 applet 间跨页面通信的方法是基于这样一个事实,即如果有两个 applet 的 codebase 同样,即使它们在不同的浏览器窗口中加载,它们也分享相同的运行环境。粗略地说,codebase 就是从中加载 applet 目录。目录。请参考文本后的参考资源,其中一个链接指向相关资源 codebase 一个教程。

所有的环境都是共享的,因为环境是共享的,所以 applet 所有的例子都可以访问静态域和静态结构,这些静态域和结构可以用于不同的结构 applet 两者之间传递信息。

applet 它不仅可以存储简单的数据类型,如整数、字符和字符串,还可以存储每个数据类型 applet 它本身(实例)的引用可以存储在静态域(可能在自己的类中)中。任何 applet 所有这些域都可以访问,以获得指向这个例子的参考。

这听起来复杂吗?不,一点也不复杂。我先举个简单的例子。假设你的一个 applet (AppletA.class) 在一个框架中,另一个框架 applet (AppletB.class) 在另一个框架中,这两个 applet 都是从同一个 codebase 加载的。

你现在想给予 AppletA 访问 AppletB 公共方法的权限。你必须让 AppletB 将自己的引用存储在静态公用域中,如下:

public class AppletB {public static AppletB selfRef = null; // 初始归零publicic void init() {// 引用selfreffef生成本实例 = this;}...}

现在你可以做到了 AppletA 访问 AppletB 的实例了:

public class AppletA {AppletB theOtherApplet = null;public void callAppletB() {// 获取静态域,其中存储方向 AppletB 的// 实例指针。theOtherApplet = AppletB.selfRef;// 之后可以调用实例方法,/// 如下所示...theOtherApplet.repaint();}...}

这就是我们要做的所有工作。因为环境在运行过程中是不同的 applet 所以即使是共享 applet 这种方法不在同一页面上也起作用。

值得注意的是,上述代码尚未启动 AppletB 之前就调用 AppletA 中的 callAppletB 方法的情况。如果发生这种情况, selfRef 将是 null,不能进行任何通信。

当然,还有一种更通用的方法。创建这样一个类别的唯一目的是存储在静态数据结构中 applet 的引用。以后你会看到的 AppletList 这种情况属于类。希望其他 applet 访问自己的公共方法 applet 实例通过 AppletList 注册自己。按照 AppletContext.getApplet(string name) 在中间模式下,每个注册项都与字符串相关。当一个 applet 调用某个 applet 引用时,字符串起着关键字的作用。

通常,applet 以下方式注册:

public class AppletA {public void start() {AppletList.register("Stock-trade-applet", this);...}}

另一个 applet 获得其访问权:

public class AppletB {public void run() {AppletA tradeApplet =(AppletA) AppletList.getApplet("Stock-trade-applet");...}}

当该 applet 当停止运行时,你必须记住 AppletList 注册中撤销:

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。

正如我前面提到的,局限性必须从同一个开始 codebase 中加载这些 applet。另外,如果浏览器的两个不同副本正在运行,并且 applet 加载到每个副本中, applet 它们可能无法相互通信(取决于浏览器的版本和设置),因为它们可能不再共享相同的运行环境。但是,如果浏览器本身衍生出新的浏览器窗口,那就没有问题了。

该技能已经通过了几个平台和几个浏览器版本的测试,但在某些配置中,每个都是 applet 环境可能是独立的。该技能已在以下操作系统和浏览器组合中进行测试:

Windows20000: Internet Explorer 5.0,Internet Explorer 5.5,Netscape Navigator 4.72,Opera 4.01 Windows 98: Internet Explorer 4.72,Internet Explorer 5.0,Netscape Navigator 4.02 Mac OS 9: Internet Explorer 4.5,Netscape Navigator 4.5 Red Hat 6.2: Netscape Navigator 4.73

小结的技巧说明了它可以使用 applet 一种替代相互通信的方法。这种方法用于 Java API 的 getApplet() 这种方法不支持工作。这项技能中介绍的知识的增加将增加 applet 可能性作为网站或内部网络的一部分 -- 可以用它代替或补充 getApplets 方法。

Tobias作者简介 Hill 是 Citerus 作为创始人之一,该公司以瑞典为基地,致力于 Java 因特网、内部网和外部网系统建立在平台上。Hill 从 1996 年开始用 Java 从独立控制的机器人编程到在线焰火明信片制作程序的开发,编程参与了许多项目。