69.html

来自「写给JSP初级程序员的书」· HTML 代码 · 共 264 行

HTML
264 行
字号
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

<meta name="description" content="Java,JDBC,EJB,Open Source,jdk,rmi">
<meta name="Keywords"
content="Java, servlets, Java servlet, Javascript, ActiveX, VRML,
        applet, applets, directory, news, jdbc, applications, 
        Java applications, Java developer, Java development, developer, 
        classes, Jars.com, Jars, intranet, Java applet, Javabeans, 
        Java products, JDK, Java development kit, java development environment, JIT,
        JavaPlan, enterprise tools, JVM, Java Virtual Machine, Java resources, 
        SUN, CGI, Perl, database, network, html,
        xml, dhtml, rating, ratings, review, jars, cgi, programming,
        software review, software rating">
<title>csdn_如何实现Applet之间跨浏览器窗口的通信</title>
<style>
.news {   BACKGROUND: #007cd3;  font-family: "宋体"; font-size: 9pt }
.t {  font-family: "宋体"; font-size: 9pt }
.t1 { color:#007cd3;  font-family: "宋体"; font-size: 9pt }
.white { font-family: "宋体"; font-size: 9pt;color:#FFFFFF }
.red { font-family: "宋体"; font-size: 9pt;color:#FF0000 }
A:visited {color:#0000FF}
A:hover {color: #ff6666; text-decoration: none}
.text {font-size: 12px; line-height: 160%; font-family: "宋体"}
.text1 {color:#000000; font-size: 12px; line-height: 130%; font-family: "宋体"; text-decoration: none}
.text1:visited {color:#000000}
.text1:hover {color: #000000}
.text2 {color:#000000; font-size: 12px; line-height: 130%; font-family: "宋体"; text-decoration: none}
.text2:visited {color:#000000}
.text2:hover {color: #000000}
.text3 {font-size: 12px; line-height: 100%; font-family: "宋体"; text-decoration: none}
.large {font-size: 14.8px; line-height: 130%}
</style>
</head>

<body


<center>




  <tr>
    <td WIDTH="100%" VALIGN="TOP">
      <tr>
        <td WIDTH="100%" CLASS="white"></td>
      </tr>
    
      <tr>
        <td WIDTH="50%" bordercolor="#FFFFFF" CLASS="t1" bgcolor="#F0F0F0" align="center" nowrap>如何实现Applet之间跨浏览器窗口的通信  </td>
   <p>     <td WIDTH="50%" bordercolor="#FFFFFF" CLASS="t1" bgcolor="#F0F0F0" align="center" nowrap>作者: 仙人掌工作室 </td></p>
      </tr>
      <tr>        <td WIDTH="100%" bordercolor="#FFFFFF" CLASS="t" bgcolor="#F0F0F0" colspan="2">
        <P>   <B>问题说明</B> 
<P>   java.applet包的AppletContext类包含如下两个成员方法:getApplet和getApplets。使用这两个方法,Applet能够寻找到其他的Applet并调用它们的方法。不过这是以满足如下安全条件为前提的: 
<UL>
  <LI>所有Applet位于同一服务器的同一目录。 
  <LI>所有Applet运行在同一页面且位于同一浏览器窗口内。 
</UL>
<P>   或许为Applet加上这些安全限制都有着很充分的理由,但第二个条件给我们实现带有Applet到Applet通信功能的多Applet界面带来了限制。 
<P>   请设想如下情形: 
<P>   你刚好编写完了一个用于股票交易的Applet,接下来想要为它做一个完善的帮助系统。这个帮助系统也是一个Applet,而且应该放到和股票交易Applet不同的另外一个帧里。你作出这个决定的原因可能是出于网站整体结构的考虑,也可能是你想让帮助系统总是处于显示状态。你还想让帮助Applet能够自动根据用户的当前操作切换到相应的帮助条目(就象Microsoft 
  Office帮助系统提供的那样)。此外,你甚至还计划着在帮助系统里做一个向导,使它能够在另外一个窗口中指导用户如何完成股票交易Applet里的各种任务。 
<P>   应当承认这种设想是非常美妙的。然而,由于这些Applet位于不同的页面,AppletContext中的Java API无法帮助你完全实现这种设想——不过本文介绍的技术能够。 
<P>   在介绍新的Applet到Applet通信方法之前,我们先要简要地介绍一下getApplet和getApplets这两个方法的用法。Applet能够寻找到同一页面的其他Applet,这既可以调用getApplet方法通过名字查找,也可以调用getApplets方法找出同一页面内的所有Applet。这两个方法都在调用成功时返回一个或多个Applet对象给调用者。调用者找到目标Applet对象之后,接着就可以调用它的公用方法。 
<P>   假设HTML页面的代码片断如下: 

  <TR> 
    <TD> 
      <PRE>&nbsp;</PRE>
    </TD>
  </TR>
<P>   通过APPLET标记的name属性,我们可以用如下代码引用指定的Applet: 

  <TR> 
    <TD> 
      <PRE><P>
    Applet theOtherApplet = getApplet("app1");
   //调用该Applet的公用方法
    theOtherApplet.anyMethod(); 
</PRE>
    </TD>
  </TR>
<P>   或者,我们也可以用下面的代码提取页面内的所有Applet: 

  <TR> 
    <TD> 
      <PRE><P>
    Enumeration allAppletsOnSamePage = getApplets();
    while(allAppletsOnSamePage.hasMoreElements()) {
        Applet appl = (Applet) allAppletsOnSamePage.nextElement();
    // 调用Applet的公用方法
        appl.anyMethod();
    }
</PRE>
    </TD>
  </TR>
<P>   当发出调用的Applet提取到同一HTML页面内的一个或多个Applet对象时,它就可以调用这些Applet对象的公用方法。
<P>   遗憾的是,使用这种标准方法我们只能实现同一页面内的Applet通信。但如果幸运的话,我们可以很方便地突破这一局限。实现跨页面Applet到Applet通信基于这样一个事实,即如果两个Applet具有相同的codebase,那么即使它们运行在不同的浏览器窗口中,它们也将共享同一个运行时环境。所谓的codebase,我们可以粗略地把它看成Applet所在的服务器目录,请参见本文后面参考资源中有关codebase示范的链接。 
<P>   共享运行时环境使得类的静态域和结构能够被所有的Applet实例访问,因此,我们可以用这些静态域和结构在不同的Applet之间传递信息。 
<P>   我们不仅可以把简单数据类型——比如整数、字符、字符串存储到这些静态域,而且还可以存储Applet实例本身的引用,这样,其他的Applet就可以通过访问这些静态域得到该Applet实例的引用。 
<P>   这种方法非常复杂吗?事实上,它并不复杂。下面我们来看一个简单的例子。假设有两个Applet(AppletA.class和AppletB.class)位于不同的帧,但它们具有相同的codebase。 
<P>   现在我们要从AppletA里面访问AppletB的公用方法。首先我们要在AppletB里面把它自己的引用保存到一个静态公用域,如: 

  <TR> 
    <TD> 
      <PRE><P>
    public class AppletB {
        public static AppletB selfRef = null; // Initially zero

        public void init() {
            // 保存当前实例的引用
            selfRef = this;
        }
        ...
    }
</PRE>
    </TD>
  </TR>
<P>   现在AppletA可以访问AppletB的实例: 

  <TR> 
    <TD> 
      <PRE><P>
    public class AppletA {
        AppletB theOtherApplet = null;
        public void callAppletB() {
      // 获得静态域的值,这个静态域保存了
      // AppletB实例的引用
            theOtherApplet = AppletB.selfRef;

      // 接下来就可以调用AppletB实例
      // 的方法,例如:
            theOtherApplet.repaint();
        }
        ...
    }
</PRE>
    </TD>
  </TR>
<P>   这样就实现了两个Applet的通信。由于不同的Applet共享运行时环境,因此即使这些Applet位于不同的页面,这种方法也同样有效。 
<P>   不过应当注意的是,上面的代码不能处理这种情况:在AppletB没有启动之前就在AppletA里面调用callAppletB方法。如果发生这种情况,则selfRef的值将是null,Applet之间的通信不能正常进行。
<br>
<P>   当然,我们还可以设计出更加通用的方法。我们可以创建一个类,这个类的唯一用途就是在自己的静态数据结构中保存其他Applet的引用。下面是一个参考实现AppletList。想要让其他Applet访问自己的公用方法的Applet实例首先要在AppletList中注册。按照AppletContext.getApplet(string 
  name)方法的处理模式,每个注册的Applet都和一个字符串相关联。以后当其他Applet需要引用某个Applet实例时,这个字符串就可以作为键(即Applet的标识)使用。 
<P>   下面是Applet在AppletList中注册的典型过程: 

  <TR> 
    <TD> 
      <PRE><P>
    public class AppletA {
        public void start() {
            AppletList.register("Stock-trade-applet", this);
            ...
        }
    }
</PRE>
    </TD>
  </TR>
<P>   其他Applet访问已注册Applet的过程如下: 

  <TR> 
    <TD> 
      <PRE><P>
    public class AppletB {
        public void run() {
            AppletA tradeApplet =
                (AppletA) AppletList.getApplet("Stock-trade-applet");
            ...
        }
    }
</PRE>
    </TD>
  </TR>
<P>   当Applet结束运行时它必须从ApplietList取消注册: 

  <TR> 
    <TD> 
      <PRE><P>
    public void stop() {
        AppletList.remove("Stock-trade-applet");
        ...
    }
</PRE>
    </TD>
  </TR>
<P>   AppletList类的完整代码如下: 

  <TR> 
    <TD> 
      <PRE><P>
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: }
</PRE>
    </TD>
  </TR>
<P>   请从本文后面下载exampleCode.zip了解更多有关如何应用AppletList类的信息。 
<P>   <B>本方法的局限</B> 
<P>   如前所述,参与通信的Applet必须具有相同的codebase。此外,如果你运行的是两个不同的浏览器副本且Applet分别运行于这两个浏览器中,由于这些Applet可能没有共享运行时环境(这和浏览器版本、设置有关),因此它们可能不能进行通信。然而,如果你是从同一个浏览器创建出新的浏览器窗口,那么这个问题是不存在的。 
<P>   本文所介绍的技术已经顺利通过好几个平台和浏览器版本的测试,但导致多个Applet拥有各自的运行时环境的配置还是存在的。顺利通过测试的操作系统和浏览器组合如下所示: 

  <TR> 
    <TD>Windows 2000: </TD>
    <TD>Internet Explorer 5.0, Internet Explorer 5.5, Netscape Navigator 4.72, 
      Opera 4.01 </TD>
  </TR>
  <TR> 
    <TD>Windows 98: </TD>
    <TD>Internet Explorer 4.72, Internet Explorer 5.0, Netscape Navigator 4.02 
    </TD>
  </TR>
  <TR> 
    <TD>Mac OS 9: </TD>
    <TD>Internet Explorer 4.5, Netscape Navigator 4.5 </TD>
  </TR>
  <TR> 
    <TD>Red Hat 6.2: </TD>
    <TD>Netscape Navigator 4.73 </TD>
  </TR>
<P>   <B>小结</B> 
<P>   本文介绍了一种新的实现Applet到Applet通信的方法,这种方法在无法使用Java API的getApplet()方法时仍旧有效。掌握了这种方法,你就有更多的机会在Web网站或Intranet上使用Applet——用它来替换getApplets方法,或者补充getApplets方法的不足。 
<P>   参考: 
<UL>
  <LI>如何使用AppletList的例子:<br>
    <A href="exampleCode.zip"  >http://www.javaworld.com/javatips/javatip101/exampleCode.zip</A> 
  <LI>The Sun Java tutorial on applet-to-applet communication: <br>
    <A href="http://web2.java.sun.com/docs/books/tutorial/applet/appletsonly/iac.html" target="_blank" >http://web2.java.sun.com/docs/books/tutorial/applet/appletsonly/iac.html</A> 
  <LI>The Sun Java tutorial on codebases (among other issues): <br>
    <A href="http://web2.java.sun.com/docs/books/tutorial/applet/appletsonly/html.html" target="_blank" >http://web2.java.sun.com/docs/books/tutorial/applet/appletsonly/html.html</A> 
        </td>
      </tr>
    </td>
  </tr>
</div>
</body>
</html>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?