熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

如何實現Applet之間跨浏覽器窗口的通信

2013-11-23 19:24:03  來源: Java核心技術 

   javaapplet包的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(app);
  //調用該Applet的公用方法
  theOtherAppletanyMethod();
  
  
  
  
   或者我們也可以用下面的代碼提取頁面內的所有Applet
  Enumeration allAppletsOnSamePage = getApplets();
  while(allAppletsOnSamePagehasMoreElements()) {
    Applet appl = (Applet) allAppletsOnSamePagenextElement();
  // 調用Applet的公用方法
    applanyMethod();
  }
  
  
  
  
   當發出調用的Applet提取到同一HTML頁面內的一個或多個Applet對象時它就可以調用這些Applet對象的公用方法
  
   遺憾的是使用這種標准方法我們只能實現同一頁面內的Applet通信但如果幸運的話我們可以很方便地突破這一局限實現跨頁面Applet到Applet通信基於這樣一個事實即如果兩個Applet具有相同的codebase那麼即使它們運行在不同的浏覽器窗口中它們也將共享同一個運行時環境所謂的codebase我們可以粗略地把它看成Applet所在的服務器目錄請參見本文後面參考資源中有關codebase示范的鏈接
  
   共享運行時環境使得類的靜態域和結構能夠被所有的Applet實例訪問因此我們可以用這些靜態域和結構在不同的Applet之間傳遞信息
  
   我們不僅可以把簡單數據類型——比如整數字符字符串存儲到這些靜態域而且還可以存儲Applet實例本身的引用這樣其他的Applet就可以通過訪問這些靜態域得到該Applet實例的引用
  
   這種方法非常復雜嗎?事實上它並不復雜下面我們來看一個簡單的例子假設有兩個Applet(AppletAclass和AppletBclass)位於不同的幀但它們具有相同的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 = AppletBselfRef;
  
   // 接下來就可以調用AppletB實例
   // 的方法例如
      theOtherAppletrepaint();
    }
    
  }
  
  
  
  
   這樣就實現了兩個Applet的通信由於不同的Applet共享運行時環境因此即使這些Applet位於不同的頁面這種方法也同樣有效
  
   不過應當注意的是上面的代碼不能處理這種情況在AppletB沒有啟動之前就在AppletA裡面調用callAppletB方法如果發生這種情況則selfRef的值將是nullApplet之間的通信不能正常進行
  
  
   當然我們還可以設計出更加通用的方法我們可以創建一個類這個類的唯一用途就是在自己的靜態數據結構中保存其他Applet的引用下面是一個參考實現AppletList想要讓其他Applet訪問自己的公用方法的Applet實例首先要在AppletList中注冊按照AppletContextgetApplet(string name)方法的處理模式每個注冊的Applet都和一個字符串相關聯以後當其他Applet需要引用某個Applet實例時這個字符串就可以作為鍵(即Applet的標識)使用
  
   下面是Applet在AppletList中注冊的典型過程
  public class AppletA {
    public void start() {
      AppletListregister(Stocktradeapplet this);
      
    }
  }
  
  
  
  
   其他Applet訪問已注冊Applet的過程如下
  public class AppletB {
    public void run() {
      AppletA tradeApplet =
        (AppletA) AppletListgetApplet(Stocktradeapplet);
      
    }
  }
  
  
  
  
   當Applet結束運行時它必須從ApplietList取消注冊
  public void stop() {
    AppletListremove(Stocktradeapplet);
    
  }
  
  
  
  
   AppletList類的完整代碼如下
  : import javautil*;
  : import javaappletApplet;
  :
  : public class AppletList {
  : private static Hashtable applets = new Hashtable();
  :
  : public static void register(String name Applet applet) {
  : appletsput(nameapplet);
  : }
  :
  : public static void remove(String name) {
  : appletsremove(name);
  : }
  :
  : public static Applet getApplet(String name) {
  : return (Applet) appletsget(name);
  : }
  :
  : public static Enumeration getApplets() {
  : return appletselements();
  : }
  :
  : public static int size() {
  : return appletssize();
  : }
  : }
  
  
  
  
   請從本文後面下載exampleCodezip了解更多有關如何應用AppletList類的信息
  
   本方法的局限
  
   如前所述參與通信的Applet必須具有相同的codebase此外如果你運行的是兩個不同的浏覽器副本且Applet分別運行於這兩個浏覽器中由於這些Applet可能沒有共享運行時環境(這和浏覽器版本設置有關)因此它們可能不能進行通信然而如果你是從同一個浏覽器創建出新的浏覽器窗口那麼這個問題是不存在的
  
   本文所介紹的技術已經順利通過好幾個平台和浏覽器版本的測試但導致多個Applet擁有各自的運行時環境的配置還是存在的順利通過測試的操作系統和浏覽器組合如下所示
  
   小結
  
   本文介紹了一種新的實現Applet到Applet通信的方法這種方法在無法使用Java API的getApplet()方法時仍舊有效掌握了這種方法你就有更多的機會在Web網站或Intranet上使用Applet——用它來替換getApplets方法或者補充getApplets方法的不足
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26802.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.