文字:  背景:  字号:

 

第十章 制作Applet

  在这一章,我们将讨论有关AppletHTML的内容,并介绍java.applet包所提供的支持。运用本章的知识,将能够开发自己的Applet和动态页面。

10.1 进一步认识Applet

  前文我们曾给出了一个Applet的简单示例,它提供了不少信息。
  Applet是Java语言的又一应用形式。它没有main方法,因而不能由解释器直接解释执行。为了运行它,我们需要把它放进Web页面。当这个页面在浏览器上显示时,Applet就在页面中指定的一部分区域内显示其运行结果。
   Web页面是用HTML语言编写的。HTML是Hypertext Markup Languarg的简称,一般译作超文本标记语言或超文本置标语言。HTML语言使用许多标记(tab)来描述一个页面。在这些标记中,有一个<APPLET>标记(有关HTML语言将在下文再作介绍,读者暂不必关心其细节)。Applet的有关信息就由这一标记引导的内容给出。这些内容和显示的许多属性,有的可以缺省,但至少应包括Applet的源路径(即,从哪儿找到Applet的.class文件),以及Applet显示区域的高度和宽度。当一个浏览器装入一个含有<Applet>标记的HTML语言编写的Web页面时,它会调用装入器,按照文档中Applet代码路径去寻找.class文件并执行它。
  Applet利用了浏览器的资源,当它被装入时,它的外部环境是浏览器预先定义的执行环境。然后浏览器才会根据HTML文本中的信息提供Applet所要求的环境。浏览器中的应用程序能显示图像,演奏声音等。Applet就是通过使用这些浏览器所提供的能力来工作的。
  Applet由运行时系统来构造。当它所在的页面被浏览器装入后,Applet就出生了。这时系统自动调用init()方法,进行一些必要的初始化工作。接着,系统将调用start()方法启动Applet的执行。当浏览器切换到别的页面时,stop()被调用,以终止Applet的执行。假如浏览器又切换回Applet所在页面,那么运行时系统将从调用start()方法开始Applet的又一次运行。当浏览器关掉时,Applet走到了它一生的终点。系统将先调用stop()停止它的执行,然后用destroy()方法来完成资源回收等收尾工作。如果浏览器重载页面,就会先令Applet死亡(依次调用stop()和destroy()),然后装入页面(调用init()),开始Applet的又一次生命。Applet的生命周期图示见图10.1。
    ┌────────┐     ┌─────────┐
    │  出生    ├────→│   启动    │
    │(Init())│   ┌→│(start())├┐关
    └────────┘   │ └─────────┘│掉
         切换回页面   │            │浏 
    ┌───────────┐│ ┌────────┐ │览 
    │  消亡       │└─┤   停止   │ │器
    │(destroy())│←─┤(stop())│←┘
    └───────────┘  └────────┘
     图10.1 Applet的生命周期图
  Applet本身是Panel的子类,它也有事件控制机制。上面四个方法是用来响应Java运行时系统产生的事件的。如果还有其它事件要处理(比如,按了一个按钮),那么可以在Applet中重写由 Component类继承来的handleEvent()方法(旧的API适用)或用监听者来监听和处理事件(1.1版的API适用)。
  Applet的应用很广,可以为页面带来动态交互内容,带来声音、动画效果,可以通过CGI(通用网关接口)与远程数据库相联系。Applet也可以打开窗口,做一些窗口程序中常做的事。如果把协议处理器(ProtocolHandler,将在§11.7介绍)等网络方面的元素与Applet结合起来,Applet的功能会更强。

10.2 java.applet包

 

10.2.1 Applet类

  Applet类是所有Applet类的父类。它有一个缺省的无参构造函数,但一般不用。

  Applet类所提供的方法有22个。

  (1)有关运行环境和Applet状态的方法 

原型 注释
public AppletContext getAppletContext() 用以得到与Applet有关的上下文(AppletContext)对象。此方法与访问Applet的执行环境有关。
public void resize(int width,int height) 重新设置Applet所在区域的大小。该方法重写了Component类的resize()方法。它还有一个重载方法。
public void resize(Demesion d)
public void showStatus(String msg) 用Applet的上下文(如执行它的浏览器)来显示Applet的状态信息
public final void setStub(Applet Stub) 用来设置与Applet相关的“存根”AppletStub。除非你要构造自己的Applet浏览器,否则不要使用它。由final修饰符可知这个方法是不可重写的。
public Locale getLocale() Local是 java.util包中的一个类,封装与国家、语言等相等的地域信息。这个方法用于获取与Appet相关的Locale对象。
public boolean isActive() 判断Applet是否处于被激活的状态

  (2)用于操作声音、图像资源的方法

原型 注释
public Image getImage(URL url) 从给定的URL获取Image对象,用以处理图像。
public Image getImage(URL url,String name) 获取指定URL和名字的Image对象。
public AudioClip getAudioClip(URL url)
public AudioClip getAudioClip(URL url,String name) 用以获取AudioClip对象。这两个方法用以处理声音
public void play(URL url)  
public void play(URL url,String name) 用于演奏指定的AudioClip对象。

  (3)与生命周期有关的方法

原型 注释
public void init() 做初始化工作,在Applet被装入时调用。
public void start() 启动Applet的运行。
public void stop() 停止Applet运行时被自动调用
public void destroy() 当Applet消亡时被自动调用,一般用来做回收资源等收尾工作

  (4)与Applet所在页面有关的方法

原型 注释
public URL getCodeBase() 返回Applet所在的文档的URL。
public URL getDocumentBase() 返回Applet所在的HTML文档的URL。
public String getAppletInfo() 返回一个String对象,其中包含Applet的版本,拷贝权、作者等信息
public String[][]getParameterInfo() 描述Applet参数的名字、类型和描述
public String getParameter(String) 得到在HTML文档中传给Applet的参数

  Applet类的继承关系:

  java.lang.Object

    └java.awt.Component

      └java.awt.Container

        └java.awt.Panel

          └java.applet.Applet

10.2.2 java.applet包中的接口

  Applet包中的三个接口分别是AppletContext、AppletStub和AutioClip,它们均由java.lang.Object类继承而来。

  Appletcontext接口顾名思义是指Applet所在的“上下文”。所谓Applet的上下文是指装入、执行Applet的浏览器或appletviewer。Applet类中的getAppletContext()方法可以访问这一接口的对象。本接口提供七个与Applet上下文有关的方法:

原型 注释
public abstract Applet getApplet(String name) 按名字得到相应的Appet对象。
public abstract Enumeration getApplets() 得到与当前AppletContext对象相关的所有Applet。返值为一个Enumeration对象。Enumeration是java.util中的一个接口类,其中封装了枚举数据集合的方法
public abstract AudioClip getAudioClip(URL) 根据URL得到相应的AudioClip对象
public abstract Image getImage(URL) 根据URL得到相应的Image对象
public ablstract void showDocument(URL) 让浏览器显示特定URL的页面
public ablstract void showDocument(URL,String) 根据URL和文档名显示指定页面
public abstract void showStatus(String) 用浏览器显示状态信息
public abstract boolean isActive()  
public abstract URL getDocumentBase()  
public abstract URL getCodeBase()  
public abstract String getParamenter(String)  
public abstract Appletcontext getAppletContext()  
public abstract void appletResize(int,int)  
 

  AppletClip接口是用来处理声音的。它定义了三个无参的方法play(),stop(),loop(),分别用来开始演奏、停止演奏AppletClip对象。

10.3 HTML语言与Applet

10.3.1 概述
10.3.2 HTML标记简介
10.3.3 用javadoc生成HTML文档

10.4 开发实例

//点击此处请看效果

//calculator.java
import java.lang.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
public class calculator extends Applet

{
  TextField text = new TextField();
  Label label=new Label("Calculator");
  public Button buttons[]=new Button[15];
  //初始化
  public void init()
  {
    setBackground(Color.gray);
    GridBagLayout gridbag = new GridBagLayout();
    setLayout(gridbag);
    for(int i=0;i<10;i++)
    {
      buttons[i]=new Button(""+i+"");
    }
    buttons[10] = new Button("-");
    buttons[11] = new Button("*");
    buttons[12] = new Button("CLR");
    buttons[13] = new Button("+");
    buttons[14] = new Button("=");
    int px[] = {0,0,4,7,0,4,7,0,4,7,0,4,7,0,4,7,0};
    int py[] = {0,3,3,3,5,5,5,7,7,7,9,9,9,11,11,11,2};
    int pwidth[]={10,4,3,3,4,3,3,4,3,3,4,3,3,4,3,3,10};
    int pheight[] = {2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
    GridBagConstraints cons[] = new GridBagConstraints[17];
    for(int i=0;i<17;i++)
    {
      cons[i] = new GridBagConstraints();
      cons[i].fill = new GridBagConstraints().BOTH;
      cons[i].gridx = px[i];
      cons[i].gridwidth=pwidth[i];
      cons[i].gridheight = pheight[i];
      if(i==0)
      {
        gridbag.setConstraints(text,cons[0]);
        add(text);
      }
      else if(i==16)
      {
        gridbag.setConstraints(label,cons[16]);
        add(label);
      }
      else
      {
        gridbag.setConstraints(buttons[i-1],cons[i]);
        add(buttons[i-1]);
      }
    }
    //以上摆放各个零件
    text.setText("");
    text.setEditable(false);
    text.setFont(new Font("TimesRoman",Font.BOLD,14));
    text.setBackground(Color.cyan);
    label.setBackground(Color.lightGray);
    //以上作一些初始化工作
    for(int i=0;i<15;i++)
    {
      buttons[i].addActionListener(new MyActionListener(this));
      //登记每个按钮的事件监听者
    }
  }
  //绘制屏幕
  public void paint(Graphics g)
  {
    g.draw3DRect(35,1,130,189,true);
    g.fill3DRect(35,1,130,189,true);
  }
}
//自定义的监听者类监听各个按钮的动作并处理相应事件
class MyActionListener implements ActionListener
{
  calculator clr;
  static long number,num1;
  static char opr;
  public MyActionListener(calculator cl)
  {
    super();
    clr=cl;
  }
  public void actionPerformed(ActionEvent e)
  {
    String screen;
    Button eSrc = (Button)e.getSource();
    String cmd = eSrc.getActionCommand().trim();
    int i;
    if(cmd.equals("CLR"))//按钮"CLR"被按动
    {
      clr.text.setText("0");
    }
    else if("+".equals(cmd)||"-".equals(cmd)||"*".equals(cmd))//运算键被按动
    {
      clr.text.setText("0");
      num1=number;
      opr=cmd.charAt(0);
    }
    else if("=".equals(cmd))//被按动
    {
      int sign;
      if(number>0) sign=1;
      else sign=-1;
      if(sign*num1>0) sign=1;
      else sign=-1;
      switch(opr)
      {
        case '+':number=number+num1;break;
        case '*':number=number*num1; break;
        case '-':number=num1-number; break;
      }
      if(number>999999999||number<-999999999)
      {
        clr.text.setText("Overflow");
      }
      else
        clr.text.setText(""+number+"");
      opr = ' ';
    }
    else if((i=Integer.parseInt(cmd))>=0&&i<=9)//按了数字键
    {
      screen = clr.text.getText();
      if(screen.length()<9) //Limit the width of input
      {
        if(screen.trim().equals("0"))

          clr.text.setText(cmd);
        else
          clr.text.setText(screen+cmd);
        number=Integer.parseInt(clr.text.getText());
      }
    }
  }
}

10.5 通用网关接口