アプレットプログラミング


Javaの特徴である,WWWブラウザの中で動くアプレット(Applet)と呼ばれる プログラムも,通常のGUIプログラムとそれほど差はなく書ける.注意するの は以下の点である. 先ほどのプログラムを書き直してみる.
// <applet code=AppTest width=600 height=450></applet>
  // アプレットを使うため
import java.applet.*;
  // AWTを使うため,
import java.awt.*;
  // イベント駆動関係のクラスを用いるため
import java.awt.event.*;
  // Vectorクラスを用いるため
import java.util.*;

  // 線分のクラスを定義する.
class Line{
  // 始点,終点のX座標,Y座標を int で保持する.
  public int start_x,start_y,end_x,end_y;
  // Lineのコンストラクタ
  public Line(int x1,int x2,int x3,int x4){
   start_x=x1;
   start_y=x2;
   end_x=x3;
   end_y=x4;
  }
}
// 外側のFrameに直接 paintするのではなく, お絵書き領域を作る.
class MyCanvas extends Canvas implements KeyListener, MouseListener, MouseMotionListener{
   // Lineの配列を保持するVectorクラスの変数 lineArrayの宣言
  Vector lineArray;
   // マウスをドラッグ中かどうかを示す boolean型(真偽値)の変数draggingの宣言
  boolean dragging;
   // 表示する色を保持する変数
  Color lineColor;
   // コンストラクタの宣言
  public MyCanvas(){
    super();
    lineArray=new Vector();
     // ドラッグ中ではない
    dragging=false;
     // 線の色は黒に
    lineColor=Color.black;
      // GUI部品と,Event Listenerを関連づける
    setSize(600,400);
    addKeyListener(this);
    addMouseListener(this);
    addMouseMotionListener(this);
  }
  Image offScreenImage;
  Graphics offScreenGraphics;
  public void update(Graphics g){
    if(offScreenImage==null){
      offScreenImage=createImage(600,400); // オフスクリーンイメージを600x400のサイズで作成
      offScreenGraphics=offScreenImage.getGraphics(); // オフスクリーンイメージに描画するための Graphics オブジェクト
    }
    paint(offScreenGraphics); // 次の画面のイメージを作る.
    g.drawImage(offScreenImage,0,0,this); // イメージを本物のスクリーンに書き込む
  }
   // offScreenImageの書き直しをする際に呼ばれる
  public void paint(Graphics g){
    int i;
      // 白で(0,0)-(600,400)を塗り潰す
    g.setColor(Color.white);
    g.fillRect(0,0,600,400);
      // 色を設定
    g.setColor(lineColor);
    int size=lineArray.size();
    if(dragging) size--;
    for(i=0;i< size;i++){
      Line l=(Line)lineArray.elementAt(i);
      g.drawLine(l.start_x,l.start_y,l.end_x,l.end_y);
    }
     // マウスをドラッグ中の時は
    if(dragging){
       // 赤い色で
      g.setColor(Color.red);
       // lines[lineCount] を描画する.
      Line l=(Line)lineArray.elementAt(i);
      g.drawLine(l.start_x,l.start_y,l.end_x,l.end_y);
    }
  }
   // KeyListenerを実装するためのメソッド
  public void keyPressed(KeyEvent e){
     // イベントからキーのコードを取り出す
    int key=e.getKeyChar();
     // デバッグ用の表示
    System.out.println("keyPressed("+e+","+key+")");
     // 入力が 'q'の時は終了する
    if(key=='q') System.exit(0);
  }
   // 要らないイベントに対応するメソッドも中身は空で書いておく必要がある.
  public void keyReleased(KeyEvent e){}
  public void keyTyped(KeyEvent e){}
   // MouseListenerを実装するためのメソッド
  public void mousePressed(MouseEvent e){
     // 押された時のマウスカーソルの位置を得る
    int mx=e.getX(),my=e.getY();
     // デバッグ用の表示
    System.out.println("mousePressed("+e+","+mx+","+my+")");
     // 配列linesのlineCount番目に線分を登録
    lineArray.addElement(new Line(mx,my,mx,my));
     // ドラッグ中であることを示す
    dragging=true;
     // 再表示をおこなう
    repaint();
  }
   // マウスのボタンが離された時のイベント
  public void mouseReleased(MouseEvent e){
     // マウスカーソルの位置を得る
    int mx=e.getX(),my=e.getY();
     // デバッグ用の表示
    System.out.println("mouseUp("+e+","+mx+","+my+")");
     // 配列linesのlineCount番目の始点を変更
    Line l=(Line)lineArray.elementAt(lineArray.size()-1);
    l.end_x=mx;
    l.end_y=my;
    dragging=false;
     // 再表示をおこなう
    repaint();
  }
  public void mouseClicked(MouseEvent e){}
  public void mouseEntered(MouseEvent e){}
  public void mouseExited(MouseEvent e){}
   // MouseMotionListenerを実装するためのメソッド
  public void mouseDragged(MouseEvent e){
     // マウスカーソルの位置を得る
    int mx=e.getX(),my=e.getY();
     // デバッグ用の表示
    System.out.println("mouseDrag("+e+","+mx+","+my+")");
     // 配列linesのlineCount番目の始点を変更
    Line l=(Line)lineArray.elementAt(lineArray.size()-1);
    l.end_x=mx;
    l.end_y=my;
     // 再表示をおこなう
    repaint();
  }
  public void mouseMoved(MouseEvent e){}
  // Delete ボタンが押された時の処理
  public void deleteLine(){
    int size;
    if((size=lineArray.size())>0){
      lineArray.removeElementAt(size-1);
      repaint();
    }
  }
  // Clear ボタンが押された時の処理
  public void clearLine(){
    lineArray.removeAllElements();
    repaint();
  }
}
// アプレットはpublicである必要
public class AppTest extends Applet implements ActionListener{
  MyCanvas myCanvas;
  Button deleteButton,clearButton;
  // コンストラクタは書かない.アプレット作成時に initが呼ばれる.
  // メニューバーは使えない
  public void init(){
    // パネル(ボタンなどを配置するための入れ物)部分を作成する.
    Panel panel=new Panel();
    panel.setLayout(new FlowLayout());
    panel.add(deleteButton=new Button("Delete"));
    deleteButton.addActionListener(this);
    panel.add(clearButton=new Button("Clear"));
    clearButton.addActionListener(this);
    // BorderLayoutを用いる.
    setLayout(new BorderLayout());
    // 上部に Panel
    add(panel,"North");
    // 下部に MyCanbasを配置する.
    add(myCanvas=new MyCanvas(),"South");
    // 部品をおさめるのに適当と思われるサイズにする.
    setSize(getPreferredSize());
    setVisible(true);
  }
  public void actionPerformed(ActionEvent e){
    System.out.println(e);
    Object source=e.getSource();
    // Deleteボタンが押された時
    if(source.equals(deleteButton)){
      myCanvas.deleteLine();
    }
    // Clearボタンが押された時
    else if(source.equals(clearButton)){
      myCanvas.clearLine();
    }
  }
}
ほとんど変更がなく書けるのが分かるだろう.これを実行するには, apptest.htmlという
<applet code="AppTest" width=600 height=450>
</applet>
といったファイルを同じディレクトリに作って,
appletviewer apptest.html
を実行する.あるいは,WWWブラウザでこのファイルをアクセスすると良い( apptest.html ).
先ほどのファイルのように,先頭にコメントで
// <applet code=AppTest width=600 height=450> </applet>
のように書いて置くと,
appletviewer AppTest.java
でアプレットを実行できる.ただし,WWWブラウザでアクセスするときは拡張 子をチェックするため,別に apptest.html が必要になる.
なお,このセンターのNC, Unix, WindowsのNetscapeは内部のJava処理系のバー ジョンが古いため,この授業に従って作成したJava2 ベースのアプレットは実 行できないことがある.

注意

イメージの読み込みの際には,ファ イルからのイメージのロードと描画で使った 「Toolkit.getDefaultToolkit().getImage(ファイル名)」というテクニックが 使えない.代わりに,AppletクラスgetImageメソッドを使う.

initの中で,

    frame=new DrawImage();
    frame.image=getImage(getCodeBase(),"test.gif");
のように使う.

注意

WWWブラウザで一度読み込んだアプレットプログラムはキャッシュされるソー スプログラムを変更して,コンパイル後に同じページを読み直しても古いプロ グラムを実行してしまうことがある.

「Shift+再読み込み」で新しいプログラムがロードされることもあるようだが, 確実な方法は,同じプログラムを別のURLでアクセスさせることによりWWWブラ ウザのキャッシュを無効にする方法である.

たとえば,「file:/home/ktanaka/java/canvastest.html」というhtmlファイ ルの中で同じディレクトリの,CanvasTestというAppletを使っていたとする. これを編集してコンパイルして, 「file:/home/ktanaka/java/canvastest.html」を再読み込みしても新しいプ ログラムが実行されない時は,

cd /home/ktanaka
ln -s java java1
のようにシンボリックリンクを作成すると,同じファイルが 「file:/home/ktanaka/java1/canvastest.html」というURLで参照できるよう になる.こちらのURLで参照すると新たにプログラムが読み込まれる.次に編 集したら,今度は
cd /home/ktanaka
ln -s java java2
のようにする.これを繰り返すことによって,何度も繰り返すことができる.
次に進む