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位於不同的頁面,這種方法也同樣有效。