2009年6月6日土曜日

Java AWT 描画処理 まとめ

paintメソッド以外からの描画


ボタンクリックやマウスクリックなどpaintメソッド以外からの描画処理を行います。

下記のコードはマウスクリックした座標に円を描画します。
GraphicsインスタンスはコンポーネントのgetGraphicsメソッドで取得します。
getGraphicsメソッドで取得したGraphicsインスタンスは、使用後disposeします。

package graphicsSample;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class GraphicSample03 extends Frame{

private static final long serialVersionUID = 1L;

public static void main(String args[]){
new GraphicSample03();
}

public GraphicSample03(){
this.setTitle("GraphicSample03");
this.setSize(300,300);
this.addMouseListener(new MyMouseAdapter());
this.setVisible(true);
}

private class MyMouseAdapter extends MouseAdapter{

public void mouseClicked(MouseEvent arg0) {
Graphics g = getGraphics();
try{
g.setColor(Color.darkGray);
g.drawOval(arg0.getX(), arg0.getY(), 50, 50);
}finally{
g.dispose();
}

}
} 

}






しかし、画面をリサイズすると描画が消えてしまいます。

ダブルバッファリングを利用して画面をリサイズしても描画が消えないようにする


対応策としてよく用いられているのが「ダブルバッファリング」です。
これは描画処理用のイメージ領域を別に作成し、まず必要な描画を全てそのイメージ領域に行っておいてから、最後にイメージ領域をフレームにまとめて描画します。

まずイメージ領域をインスタンスフィールドに用意します。
マウスクリックではこのイメージ領域に描画を行います。
paintメソッドでそのイメージ領域を描画します。

リサイズされるとpaintメソッドが実行されイメージ領域から再描画されます。
package graphicsSample;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class GraphicSample04 extends Frame{

private static final long serialVersionUID = 1L;

public static void main(String args[]){
new GraphicSample04();
}

//バッファ用イメージ
Image Img = null;

public GraphicSample04(){
this.setTitle("GraphicSample04");
this.setSize(300,300);
this.addMouseListener(new MyMouseAdapter());  
this.setVisible(true);
}

public void paint(Graphics g) {
//バッファ用イメージとグラフィックを作成します。
//コンストラクタではcreateImageインスタンスを作成できないのでココで初期化する。
if (Img == null){
Img = this.createImage(this.getWidth(),this.getHeight());
}
//イメージを描画します。
g.drawImage(Img,0,0,this);
}

private class MyMouseAdapter extends MouseAdapter{
public void mouseClicked(MouseEvent arg0) {
//バッファ用イメージに描画
Img.getGraphics().setColor(Color.darkGray);
Img.getGraphics().drawOval(arg0.getX(), arg0.getY(), 50, 50);
//paintを呼び出します。
repaint();
}
}
}



これで画面をリサイズしても描画は消えません。

しかし、画面を大きくしても描画領域は大きくならないため、大きくなった部分をマウスクリックしても円が描画されません。

画面のサイズに合わせて描画領域を変更する


componentResizedイベントで画面サイズに合わせて描画領域を変更します。
package graphicsSample;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;


public class GraphicSample05 extends Frame{

private static final long serialVersionUID = 1L;

public static void main(String args[]){
new GraphicSample05();
}

//バッファ用イメージ
Image backImg = null;
//バッファ用グラフィック
//Graphics backGraphic =null;

public GraphicSample05(){
this.setTitle("GraphicSample05");
this.setSize(300,300);
this.addMouseListener(new MyMouseAdapter());
this.addComponentListener(new MyComponentListener());
this.setVisible(true);
}

public void paint(Graphics g) {
//バッファ用イメージとグラフィックを作成します。
//コンストラクタではcreateImage、getGraphicsインスタンスを作成できないのでココで初期化する。
if (backImg == null){
backImg = this.createImage(this.getWidth(),this.getHeight());
//backGraphic = backImg.getGraphics();
}
//ブッファイメージを描画します。
g.drawImage(backImg,0,0,this);
}

private class MyMouseAdapter extends MouseAdapter{
public void mouseClicked(MouseEvent arg0) {
//ブッファ用イメージに描画
//backGraphic.setColor(Color.darkGray);
//backGraphic.drawOval(arg0.getX(), arg0.getY(), 50, 50);
backImg.getGraphics().setColor(Color.darkGray);
backImg.getGraphics().drawOval(arg0.getX(), arg0.getY(), 50, 50);
//paintを呼び出します。
repaint();
}
}

private class MyComponentListener extends ComponentAdapter{
public void componentResized(ComponentEvent arg0) {
//リサイズ後の現在サイズを取得します
Rectangle rec = getBounds(); 
//イメージのサイズより現在のサイズが大きい場合
if ((backImg.getWidth(null) <= rec.width ) | (backImg.getHeight(null) <= rec.height)){
//新たなイメージを作ります。
Image newImg = createImage(rec.width, rec.height);
//新たなイメージに古いイメージを描画します。
newImg.getGraphics().drawImage(backImg, 0, 0, null);
//新たなイメージをインスタンス変数に保存します。
backImg = newImg;
}
}
}
}

0 件のコメント: