同一个applet类在不同浏览器的同步

 
如果想要两个窗口内同步显示两支证券,那就得让两个浏览器之间能够通信,或者应该说两个applet之间能够通信,java.applet包的AppletContext类提供了 getApplet getApplets 方法以获得其它 applet 的引用,使用这两个方法, Applet 能够寻找到其他的 Applet 并调用它们的方法。不过这是以满足如下安全条件为前提的:
  
  所有 Applet 位于同一服务器的同一目录。
  所有 Applet 运行在同一页面且位于同一浏览器窗口内。
  或许为 Applet 加上这些安全限制都有着很充分的理由,但第二个条件给我们实现带有 Applet Applet 通信功能的多 Applet 界面带来了限制。所有由于这些 Applet 位于不同的页面, AppletContext 中的 Java API 无法帮助你完全实现我们的目标。
       要实现跨页面Applet到Applet通信首先要满足第一个条件,即如果两个Applet具有相同的codebase,那么即使它们运行在不同的浏览器窗口中,它们也将共享同一个运行时环境。所谓的codebase,我们可以粗略地把它看成Applet所在的服务器目录。
共享运行时环境使得类的静态域和结构能够被所有的Applet实例访问,因此,我们可以用这些静态域和结构在不同的Applet之间传递信息。   
   我们不仅可以把简单数据类型――比如整数、字符、字符串存储到这些静态域,而且还可以存储Applet实例本身的引用,这样,其他的Applet就可以通过访问这些静态域得到该Applet实例的引用。
假设有两个Applet(AppletA.class和AppletB.class)位于不同的帧,但它们具有相同的codebase。
  现在我们要从AppletA里面访问AppletB的公用方法。首先我们要在AppletB里面把它自己的引用保存到一个静态公用域,如:
public class AppletB
{
    public static AppletB selfRef = null;
    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位于不同的页面,这种方法也同样有效。
不过应当注意的是,上面的代码不能处理这种情况:在AppletB 没有启动之前就在AppletA 里面调用callAppletB 方法。如果发生这种情况,则selfRef 的值将是null ,Applet 之间的通信不能正常进行。
  当然,我们还可以设计出更加通用的方法。我们可以创建一个类,这个类的用途就是在自己的静态数据结构中保存其他Applet的引用。下面是一个参考实现AppletList。想要让其他Applet访问自己的公用方法的Applet实例首先要在AppletList中注册。按照AppletContext.getApplet(string name)方法的处理模式,每个注册的Applet都和一个字符串相关联。以后当其他Applet需要引用某个Applet实例时,这个字符串就可以作为键(即Applet的标识)使用。
下面是Applet在AppletList中注册的典型过程:
public class AppletA
{
    public void start()
{
      AppletList.register("Stock-trade-applet", this);
      ...
    }
  }
其他Applet访问已注册Applet的过程如下:
public class AppletB
{
    public void run()
{
      AppletA tradeApplet =
(AppletA) AppletList.getApplet("Stock-trade-applet");
      ...
    }
  }
当Applet结束运行时它必须从ApplietList取消注册:   
public void stop()
{
  AppletList.remove("Stock-trade-applet");
  ...
  }
AppletList类的完整代码如下:
import java.util.*;
import java.applet.Applet;
 
public class AppletList
{
  private static Hashtable applets = new Hashtable();
  
  public static void register(String name, Applet applet)
{
      applets.put(name,applet);
  }
  
  public static void remove(String name)
 {
      applets.remove(name);
  }
  
  public static Applet getApplet(String name)
 {
      return (Applet) applets.get(name);
  }
  
  public static Enumeration getApplets()
 {
      return applets.elements();
  }
  
  public static int size()
{
      return applets.size();
  }
  }
上述的办法是对两个不同的applet类来通信,而我们的目标是让同一个applet类在不同浏览器的同步,即在一支证券在一个浏览器中单步或自动回放,另一支证券要在另一个浏览器窗口中同步单步或自动回放,也就是无论点击任何一个浏览器中的单步或自动按钮,其余的浏览器也要同步回放。
因此,我们也不需要取其它applet的引用了,只要在单步或自动控制逻辑中加入调用从AppletList中取applet全集的函数getApplets,并遍历这些applet,并循环调用单步或自动的控制逻辑就可以了,因为我们并不知道AppletList的HashTable中哪个是第一个打开的窗口,哪个是第二个打开的窗口,那就干脆不管它是第几个,只要HashTable中有几个,那我们就调用这几个applet的控制逻辑。
下面是取applet的全集及循环执行的代码:
Enumeration appletList = AppletList.getApplets();
while(appletList.hasMoreElements())
{
    OrderApplet tradeApplet = (OrderApplet)appletList.nextElement();
    …… // 控制逻辑
}
但一定不能忘了,要在applet的stop方法中加入取消注册的语句,否则如果已经打开三个窗口,中途又关掉一个窗口,AppletList的HashTable中仍有三个applet的引用,与实际数量不符。
 
如前所述,参与通信的Applet 必须具有相同的codebase 。此外,如果你运行的是两个不同的浏览器副本且Applet 分别运行于这两个浏览器中,由于这些Applet 可能没有共享运行时环境(这和浏览器版本、设置有关),因此它们可能不能进行通信。然而,如果你是从同一个浏览器创建出新的浏览器窗口,那么这个问题是不存在的。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值