updateメソッドの書き換え

広告

アプレットの描画処理は今までにも記述した通り下記のような流れになっています。

1. repaintをプログラム内で呼び出す。又はアプレットがブラウザが隠れるなど
   の理由で再描画必要と判断される。
2. updateメソッドが内部的に呼び出され、画面をクリアした後でpaintメソッド
   を呼び出す。
3. paintメソッドによってアプレットが描画される

実際にpaintメソッドが呼び出される前に、updateメソッドが呼ばれています。このメソッドの役割はアプレットの描画領域をデフォルトの背景色で全て塗りつぶしてからpaintメソッドを呼び出しています。その為、前のサンプルで円を繰り返し描いた時も、毎回画面はクリアされてから新しい円が描かれていました。

スレッドを使わない場合には問題無いのですが、アニメーションなどの処理を行う時に、いちいち画面をクリアして欲しくない場合もあります。updateメソッドは内部的に呼び出されるメソッドですので、呼ばないようにすることは出来ませんが、その中身を書き換えることは出来ます。

updateメソッドはAppletクラスの親クラスであるComponentクラスで用意されています。

このコンポーネントを更新します。

このコンポーネントが軽量コンポーネントでない場合、AWT は repaint の呼び
出しに応答して、update メソッドを呼び出します。バックグラウンドがクリア
されないと考えることができます。

Component の update メソッドがこのコンポーネントの paint メソッドを呼び
出し、このコンポーネントを再描画します。このメソッドは一般的に、repaint
の呼び出しに応答して追加処理が必要なサブクラスによってオーバーライドされ
ます。このメソッドをオーバーライドするコンポーネントのサブクラスは、
super.update(g) または update メソッドから paint(g) を直接呼び出す必要が
あります。

グラフィックスコンテキストの原点の (0, 0) 座標の点はこのコンポーネントの
左上隅になります。グラフィックスコンテキストのクリッピング領域はこのコン
ポーネントの境界の矩形になります。

パラメータ:
  g - 更新に使用する指定されたコンテキスト

このメソッドを自分のクラスの中で再定義することで書き換えを行います。具体的には背景クリアの処理を行わずに単にpaintメソッドだけを呼び出して欲しいので下記のような内容となります。

import java.applet.Applet;
import java.awt.Graphics;

public class ThreadTest extends Applet{
  public void init(){
    // 初期化処理
  }

  /* 背景クリアを行わないupdate */
  public void update(Graphics g){
    paint(g);
  }

  public void paint(Graphics g){
    // 描画処理
  }
}

サンプルプログラム

では前に作成した円をランダムに描くアプレットを背景クリアしないバージョンで作成してみましょう。

ThreadTest4.java

import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;

/*
<applet code="ThreadTest4.class" codebase="class" width="150" height="150">
</applet>
*/

public class ThreadTest4 extends Applet implements Runnable{
  Thread thread = null;
  int x, y;
  Color col;

  public void init(){
    x = 10;
    y = 10;
    col = new Color(255, 0 ,0);

    thread = new Thread(this);
    thread.start();
  }

  public void update(Graphics g){
    paint(g);
  }

  public void paint(Graphics g){
    g.setColor(col);
    g.drawOval(x, y, 50, 50);
  }

  public void run(){
    while(true){
      x = (int)(Math.random() * 100);
      y = (int)(Math.random() * 100);

      int red = (int)(Math.random() * 255);
      int green = (int)(Math.random() * 255);
      int blue = (int)(Math.random() * 255);
      col = new Color(red, green, blue);

      repaint();
    }
  }
}

上記を実際に実行してみると下記のようになります。

アプレットでのスレッドのテスト

アプレットでのスレッドのテスト

前回と異なり、今回は背景をクリアしていませんので、前に描いた円も消えないまま新しい円が次々と描かれて行きます。下記で実際に試して頂くことができます。

ThreadTest4.html

( Written by Tatsuo Ikura )