Javaアプレットでは画面描画処理をAppletクラスからオーバーライドするpaint()メソッド上で実行します。
そのpaint()メソッドはrepaint()メソッドによって呼び出され、再描画を行いますが、画面に描画する情報が多いと描きかけの画面が表示され、画面がちらついたように見えることがあります。
これはJavaアプレット画面の描画処理とディスプレイの再描画間隔(
リフレッシュレート)とのタイミングによって起こりえる現象です。
つまり、描きかけの状態のときに、ディスプレイ全体の描画が行われたら、Javaアプレット画面には描きかけの画面が表示されてしまうのです。
特にゲームを作る場合、画面上にたくさんのイメージを描画し、動きも激しくなるのでJavaアプレット画面の再描画間隔も短くなり、画面のちらつきが顕著になります。
その画面のちらつきを防ぐために、
ダブルバッファリングと呼ばれる手法が使われています。
public class Timer extends Applet implements Runnable{
………
private Image offImage;
public void init(){
………
offImage = createImage(width, height); //イメージバッファ生成
}
public void start(){
running = true;
}
………
public void run(){
try{
while(running){
count++ ;
repaint();
Thread.sleep(100);
}
}catch(Exception e){}
}
public void update(Graphics g){
paint(g);
}
public void paint(Graphics g){
Graphics gv = offImage.getGraphics();
gv.clearRect(0, 0, 520, 400); //バッファ領域クリア
gv.drawString("" + count, 50,50); //バッファ領域上に描画
//バッファ領域に書き込んでおいたイメージを描画
g.drawImage(offImage, 0, 0, width, height, this);
}
}
上記サンプルのpaint()メソッド内では、画面描画領域には直接イメージを描き込むのではなく、まずバッファ領域に描画すべきイメージを描きこんでいます。
そして、最後にまとめて、バッファ領域のイメージを画面描画領域に描き込んでいます。
こうすることで、描きかけの画面が表示されることがなくなり、画面のちらつきを防ぐことができます。
また上記サンプルではAppletクラスのupdate()メソッドもオーバーライドしています。
本記事冒頭で、paint()メソッドはrepaint()メソッドによって呼び出されると書きましたが、実はrepaint()メソッドは、paint()メソッドを直接呼ぶのではなく、update()メソッドを呼び、update()メソッドがpaint()メソッドを呼ぶというしくみになっています。
repaint()メソッド → update()メソッド → paint()メソッド
update()メソッドでは画面全体を塗りつぶし、真っ白な状態に(クリア)してpaint()メソッドを呼び出します。
しかし、今回のようにバッファ領域を使う場合、その画面全体を塗りつぶす作業はバッファ領域に対して行えばいいため、画面描画領域で行う必要のない処理です。
むしろ、一度画面全体を真っ白にしてしまうので、これも画面のちらつきの原因になります。
そこで、update()メソッドをオーバーライドしてやり、update()メソッド内の処理はpaint()メソッドを呼び出すだけにしてやります。
このような処理を加えてやることで、画面がちらつくという問題を解決させます。