<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Luben Park

    Java Ben 成長(zhǎng)之路

    Java 技巧 101:applet 間通信的替代方法

    作者 Tobias Hill



    摘要
    您可能認(rèn)為能讓 applet 彼此通信的唯一選擇就是使用 getApplet。不幸的是,getApplet 方法僅返回與發(fā)出調(diào)用的 applet 在同一個(gè) HTML 頁(yè)面上的 applet,這樣就限制了您通過(guò) applet 間的通信構(gòu)建有趣界面的方式。這篇技巧說(shuō)明的替代方法能使處于不同框架甚至不同瀏覽器窗口中的 applet 彼此調(diào)用對(duì)方的方法。

    java.applet 包中的 AppletContext 類(lèi)包含兩個(gè)成員方法,即 getApplet 和 getApplets。通過(guò)使用這兩個(gè)方法,一個(gè) applet 就可以找到其他 applet 并調(diào)用它們的方法。要這樣做必須滿(mǎn)足下面的安全要求:

  • 這些 applet 來(lái)自同一個(gè)服務(wù)器上的同一個(gè)目錄中。
  • 這些 applet 運(yùn)行于同一個(gè)瀏覽器窗口中的同一個(gè)頁(yè)面上。

    這樣設(shè)計(jì)安全限制可能有很好的原因;但是,后一個(gè)要求限制了利用 applet 間的通信制作有趣的多 applet 界面的方式。

    試考慮這樣一種情況:

    您剛編好一個(gè)很好的股票市場(chǎng)交易 applet,并決定為它編寫(xiě)一個(gè)良好的幫助系統(tǒng)。您希望幫助系統(tǒng)也是一個(gè) applet,并希望將它與股票市場(chǎng)交易 applet 在不同的瀏覽器框架中運(yùn)行。您作出這個(gè)決定可能是出于網(wǎng)站結(jié)構(gòu)方面的考慮,也可能是出于始終顯示幫助系統(tǒng)的需要。另外,您希望使幫助系統(tǒng)根據(jù)用戶(hù)當(dāng)前在股票交易 applet 中進(jìn)行的操作轉(zhuǎn)至正確的信息/指導(dǎo)(就像 Microsoft Office 套件中的“回形針”一樣)。您甚至計(jì)劃在幫助系統(tǒng)中編制向?qū)?,這些向?qū)Э蛇h(yuǎn)程指出問(wèn)題,并可遠(yuǎn)程執(zhí)行股票市場(chǎng)交易 applet 中的任務(wù)。

    這一方案中體現(xiàn)的思想很不錯(cuò)。但是,因?yàn)檫@兩個(gè) applet 處于不同的頁(yè)面上,所以 AppletContext 中的 Java API 無(wú)法幫助您實(shí)現(xiàn)這個(gè)想法 -- 但這篇技巧可以幫助您。


    使用 AppletContext API

    在說(shuō)明 applet 間通信的替代機(jī)制前,我將首先簡(jiǎn)要說(shuō)明一下 getApplet 和 getApplets 這兩個(gè)方法是如何工作的。一個(gè) applet 通過(guò)使用 getApplet 方法可以按名稱(chēng)找到同一個(gè) HMTL 頁(yè)面中的另一個(gè) applet,而通過(guò)使用 getApplets 方法可以找到同一個(gè)頁(yè)面上的所有 applet。這兩個(gè)方法如果成功執(zhí)行,則會(huì)向調(diào)用者返回一個(gè)或多個(gè) Applet 對(duì)象。調(diào)用者一旦找到一個(gè) Applet 對(duì)象,它就可能調(diào)用這個(gè) Applet 的公用方法。

    假定有下面這樣一段 HTML 代碼:
    PHP代碼:
    <applet code="Applet1" width="400" height="100" name="app1">
    </
    applet>

    <
    applet code="Applet2" width="400" height="100" name="app2">
    </
    applet>

    通過(guò)使用 applet 標(biāo)記中的 name 屬性,您就可以用下面的方式引用一個(gè)特定的 applet:
    PHP代碼:
    Applet theOtherApplet = getApplet("app1");
    theOtherApplet.anyMethod(); //調(diào)用任一個(gè)公用方法

    或者,您也可以用以下的代碼來(lái)檢索這個(gè)頁(yè)面上的所有 applet:
    PHP代碼:
    Enumeration allAppletsOnSamePage = getApplets();
    while(
    allAppletsOnSamePage.hasMoreElements()) {
    Applet appl = (Applet) allAppletsOnSamePage.nextElement();
    appl.anyMethod(); //調(diào)用任一個(gè)公用方法
    }

    當(dāng)發(fā)出調(diào)用的 applet 在它所在的同一個(gè) HTML 頁(yè)面上檢索到一個(gè)或幾個(gè) applet 之后,它就可以調(diào)用這些 applet 的公用方法。

    使用靜態(tài)數(shù)據(jù)結(jié)構(gòu)

    不幸的是,如果使用標(biāo)準(zhǔn)方法,則只能與同一個(gè) HTML 頁(yè)面中的 applet 通信。幸運(yùn)的是,您很容易就可以避開(kāi)這個(gè)限制。使 applet 間跨頁(yè)面通信的方法基于這樣一個(gè)事實(shí),即如果兩個(gè) applet 的 codebase 相同,則即使它們是在不同的瀏覽器窗口中被加載的,它們也共享同一個(gè)運(yùn)行時(shí)環(huán)境。粗略地說(shuō),codebase 就是從中加載 applet 的那個(gè)目錄。請(qǐng)參閱文后的參考資源,其中有一個(gè)鏈接指向有關(guān) codebase 的一篇教程。

    由于運(yùn)行時(shí)環(huán)境是共享的,因此所有 applet 實(shí)例都可以訪問(wèn)靜態(tài)域和靜態(tài)結(jié)構(gòu),這樣這些靜態(tài)域和結(jié)構(gòu)就可用來(lái)在不同 applet 之間傳遞信息。

    applet 不僅可以存儲(chǔ)諸如整數(shù)、字符和字符串這樣的簡(jiǎn)單數(shù)據(jù)類(lèi)型,而且每個(gè) applet 都可以將其自身(實(shí)例)的一個(gè)引用存儲(chǔ)在一個(gè)靜態(tài)域(可能在它自己的類(lèi)中)中。任何 applet 都可以訪問(wèn)這個(gè)域,從而獲得指向這個(gè)實(shí)例的引用。

    這聽(tīng)起來(lái)復(fù)雜嗎?不,一點(diǎn)也不復(fù)雜。我首先舉一個(gè)簡(jiǎn)單的例子。假定您的一個(gè) applet (AppletA.class) 在一個(gè)框架中,而另一個(gè) applet (AppletB.class) 在另一個(gè)框架中,而且這兩個(gè) applet 都是從同一個(gè) codebase 加載的。

    您現(xiàn)在希望授予 AppletA 訪問(wèn) AppletB 的公用方法的權(quán)限。您必須讓 AppletB 將其自身的一個(gè)引用存儲(chǔ)在一個(gè)靜態(tài)公用域中,就像下面這樣:
    PHP代碼:
    public class AppletB {
    public static
    AppletB selfRef = null; // 初始?xì)w零

    public void init() {
    // 生成對(duì)該實(shí)例的引用
    selfRef = this;
    }
    ...
    }

    現(xiàn)在您就可以從 AppletA 訪問(wèn) AppletB 的實(shí)例了:
    PHP代碼:
    public class AppletA {
    AppletB theOtherApplet = null;

    public
    void callAppletB() {
    // 獲取靜態(tài)域,其中存儲(chǔ)著指向 AppletB 的
    // 實(shí)例的指針。
    theOtherApplet = AppletB.selfRef;

    // 此后就可以調(diào)用實(shí)例方法了,
    // 如下所示...
    theOtherApplet.repaint();
    }
    ...
    }

    這就是我們所要做的全部工作。因?yàn)檫\(yùn)行時(shí)環(huán)境是由不同的 applet 共享的,所以即便 applet 不在同一個(gè)頁(yè)面上,這個(gè)方法同樣奏效。

    值得注意的一點(diǎn)是,上面的代碼并沒(méi)有處理在啟動(dòng) AppletB 之前就調(diào)用 AppletA 中的 callAppletB 方法的情況。如果發(fā)生這種情況,則 selfRef 將是 null,這樣不能進(jìn)行任何通信。

    一種更通用的方法

    當(dāng)然,還有一種更通用的方法。您可以創(chuàng)建這樣一個(gè)類(lèi),創(chuàng)建它的唯一目的就是在靜態(tài)數(shù)據(jù)結(jié)構(gòu)中存儲(chǔ) applet 的引用。稍后您將看到的 AppletList 類(lèi)就屬于這種情況。希望其他 applet 訪問(wèn)自己的公用方法的 applet 實(shí)例通過(guò) AppletList 將自己注冊(cè)。按照 AppletContext.getApplet(string name) 中的模式,每個(gè)注冊(cè)項(xiàng)都與一個(gè)字符串相關(guān)聯(lián)。當(dāng)一個(gè) applet 調(diào)用某個(gè) applet 的引用時(shí),這個(gè)字符串就起關(guān)鍵字的作用。

    通常,applet 是按下面的方式注冊(cè)的:
    PHP代碼:
    public class AppletA {
    public
    void start() {
    AppletList.register("Stock-trade-applet", this);
    ...
    }
    }

    另一個(gè) applet 獲取對(duì)它的訪問(wèn)權(quán):
    PHP代碼:
    public class AppletB {
    public
    void run() {
    AppletA tradeApplet =
    (
    AppletA) AppletList.getApplet("Stock-trade-applet");
    ...
    }
    }

    當(dāng)該 applet 停止運(yùn)行時(shí),您必須緊記在 AppletList 中撤銷(xiāo)注冊(cè):
    PHP代碼:
    public void stop() {
    AppletList.remove("Stock-trade-applet");
    ...
    }

    AppletList 類(lèi)的完整源代碼如下所示:
    PHP代碼:
    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: }

    要獲得說(shuō)明如何使用這個(gè)類(lèi)的示例,請(qǐng)?jiān)趨⒖假Y源中下載 exampleCode.zip。

    局限性

    正如我在前面提到的那樣,必須從同一個(gè) codebase 中加載這些 applet。此外,如果瀏覽器的兩個(gè)不同副本正在運(yùn)行,并且 applet 被加載到每個(gè)副本中,則 applet 可能無(wú)法彼此通信(取決于瀏覽器的版本和設(shè)置),因?yàn)樗鼈兛赡懿辉俟蚕硗粋€(gè)運(yùn)行時(shí)環(huán)境。但是,如果是瀏覽器本身衍生出新的瀏覽器窗口,則沒(méi)有任何問(wèn)題。

    該技巧已在幾個(gè)平臺(tái)和幾個(gè)瀏覽器版本中通過(guò)測(cè)試,但在某些配置中每個(gè) applet 的運(yùn)行時(shí)環(huán)境可能是獨(dú)立的。該技巧已在下面的操作系統(tǒng)和瀏覽器組合中通過(guò)測(cè)試:
  • Windows2000: 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

    小結(jié)

    這篇技巧說(shuō)明了能使 applet 彼此通信的一種替代方法。這種方法以 Java API 的 getApplet() 方法不支持的方式工作。這篇技巧中介紹的知識(shí)增大了將 applet 作為網(wǎng)站或內(nèi)部網(wǎng)的一部分的可能性 -- 可以用它替代或補(bǔ)充 getApplets 方法。

    作者簡(jiǎn)介

    Tobias Hill 是 Citerus 的創(chuàng)辦者之一,該公司以瑞典為基地,致力于在 Java 平臺(tái)上構(gòu)建因特網(wǎng)、內(nèi)部網(wǎng)和外部網(wǎng)系統(tǒng)。Hill 從 1996 年開(kāi)始用 Java 編程,參與了許多項(xiàng)目,從為自主控制的機(jī)器人編程到開(kāi)發(fā)在線焰火明信片制作程序等等。

    參考資源

    * 說(shuō)明如何使用 AppletList 類(lèi)的示例:
    exampleCode.zip
    * Sun 提供的關(guān)于 applet 間通信的 Java 教程:
    http://web2.java.sun.com/docs/books...tsonly/iac.html
    * Sun 提供的有關(guān) codebase(在其他問(wèn)題中)的 Java 教程:
    http://web2.java.sun.com/docs/books...sonly/html.html
    * 查看以前的所有 Java 技巧以及提交您自己的技巧:
    http://www.javaworld.com/javatips/j...tips.index.html
  • posted on 2005-12-23 17:06 Ben 閱讀(371) 評(píng)論(0)  編輯  收藏


    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲视频一区二区| 亚洲另类小说图片| 2015日韩永久免费视频播放| 亚洲人成在线精品| 又爽又高潮的BB视频免费看| v片免费在线观看| 亚洲欧洲日产国码久在线观看| 久久久高清免费视频| 特级av毛片免费观看| 亚洲精品高清视频| 在线观看亚洲免费| 国产精品免费大片| 精品韩国亚洲av无码不卡区| 亚洲av无码乱码国产精品fc2 | 无码国产精品一区二区免费虚拟VR| 亚洲hairy多毛pics大全| 亚洲国产另类久久久精品黑人| 亚洲人成免费电影| jyzzjyzz国产免费观看| 亚洲午夜国产精品无卡| 国产亚洲精品不卡在线| 成年女人毛片免费观看97| 中文在线免费看视频| 亚洲第一成年网站视频| 亚洲免费在线视频| 亚洲精品国产V片在线观看| 成年人视频免费在线观看| 国产精品午夜免费观看网站| 亚洲综合久久一本伊伊区| 亚洲精品国精品久久99热一| 日本特黄a级高清免费大片| 免费无码成人AV在线播放不卡| 色视频在线观看免费| 亚洲日韩国产二区无码| 亚洲国产精品久久久久网站| 亚洲人成无码网WWW| 永久免费bbbbbb视频| 波多野结衣免费在线观看| 亚洲欧美精品午睡沙发| 亚洲欧美综合精品成人导航| 国产在线观看免费观看不卡|