12/8 簡単なグラフィクス(3)


質問と回答

Q.
試験をやるかやらないか11月末に決まるはずだったのでは?
A.
まだ決めていません.人数がもう少し減ると,課題問題だけで採点がで きるのですが.
Q.
JDK 1.1ドキュメントのページが見えない
A.
ライセンスの関係で,ドキュメントは Unixサーバのローカルディスク 上に置かれています.NCやWindowsのNetscapeでは参照できません.
Q.
最大値,最小値を取るには?
A.
Mathクラスの max, min が使えます.
Q.
イベントを処理した後で,repaintというメソッドを呼んでいるが,これはどこで定義されているメソッドですか?
A.
GUI部品は, Componentクラスの子孫クラスですが,repaintは Componentの中で定義されています.

注意するのは,repaintの呼び出しが1対1でupdateに対応しているわけでない ことです.repaintはシステムに対して,暇になったらなるべく早くupdateを 呼んでくれと依頼するだけなので,暇でない時に repaintを何度も呼び出すと, 暇になってから1回だけ updateが呼ばれるということになります.


前回の課題について

課題1
上のプログラム MouseDrawに以下のような変更を加えたプログラムを作りなさい.

解答例

  // AWTを使うため,
import java.awt.*;
  // イベント駆動関係のクラスを用いるため
import java.awt.event.*;

  // 長方形のクラスを定義する.
class ColorRect{
  // 始点,終点のX座標,Y座標を int で保持する.
  public int start_x,start_y,end_x,end_y;
  public Color color;
  // ColorRectのコンストラクタ
  public ColorRect(int x1,int x2,int x3,int x4,Color col){
   start_x=x1;
   start_y=x2;
   end_x=x3;
   end_y=x4;
   color=col;
  }
}

 // インタフェースの実装では 「implements インタフェース名」と書く
 // 複数書く場合は,カンマで区切る
class MouseDraw extends Frame implements KeyListener, MouseListener, MouseMotionListener{
   // Rectの配列を保持する変数 rectsの宣言
  public ColorRect[] rects;
   // rectsのどこまで使われているかを示す変数 rectCountの宣言
  int rectCount;
   // マウスをドラッグ中かどうかを示す boolean型(真偽値)の変数draggingの宣言
  boolean dragging;
   // 表示する色を保持する変数
  Color rectColor;
   // コンストラクタの宣言
  public MouseDraw(String title){
     // 親クラス Frameのコンストラクタの宣言
    super(title);
     // 大きさ10のColorRectの配列を作成してrectsに代入
    rects=new ColorRect[10];
     // rectsは何も使われていない
    rectCount=0;
     // ドラッグ中ではない
    dragging=false;
     // 線の色は黒に
    rectColor=Color.black;
      // GUI部品と,Event Listenerを関連づける
    addKeyListener(this);
    addMouseListener(this);
    addMouseMotionListener(this);
  }
  public static void main(String args[]) {
     // MouseDrawのインスタンスを作成 frameに代入
    MouseDraw frame=new MouseDraw("MouseDraw");
     // サイズを 600x400に設定
    frame.setSize(600,400);
     // 表示する.
    frame.setVisible(true);
  }
  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);
      // 色を設定
      // rectCount個,rectsに登録されているrectsを描画する
    for(i=0;i< rectCount;i++){
      g.setColor(rects[i].color);
      int minx=Math.min(rects[i].start_x,rects[i].end_x);
      int maxx=Math.max(rects[i].start_x,rects[i].end_x);
      int miny=Math.min(rects[i].start_y,rects[i].end_y);
      int maxy=Math.max(rects[i].start_y,rects[i].end_y);
      g.fillRect(minx,miny,maxx-minx,maxy-miny);
    }
     // マウスをドラッグ中の時は
    if(dragging){
       // 赤い色で
      g.setColor(Color.red);
       // rects[rectCount] を描画する.
      int minx=Math.min(rects[i].start_x,rects[i].end_x);
      int maxx=Math.max(rects[i].start_x,rects[i].end_x);
      int miny=Math.min(rects[i].start_y,rects[i].end_y);
      int maxy=Math.max(rects[i].start_y,rects[i].end_y);
      g.drawRect(minx,miny,maxx-minx,maxy-miny);
    }
  }
   // KeyListenerを実装するためのメソッド
  public void keyPressed(KeyEvent e){
     // イベントからキーのコードを取り出す
    int key=e.getKeyChar();
     // デバッグ用の表示
    System.out.println("keyPressed("+e+","+key+")");
     // 入力が 'q'の時は終了する
    if(key=='r') rectColor=Color.red;
    else if(key=='g') rectColor=Color.green;
    else if(key=='b') rectColor=Color.blue;
    else 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+")");
     // 配列rectsのrectCount番目に線分を登録
    rects[rectCount]=new ColorRect(mx,my,mx,my,rectColor);
     // ドラッグ中であることを示す
    dragging=true;
     // 再表示をおこなう
    repaint();
  }
   // マウスのボタンが離された時のイベント
  public void mouseReleased(MouseEvent e){
     // マウスカーソルの位置を得る
    int mx=e.getX(),my=e.getY();
     // デバッグ用の表示
    System.out.println("mouseUp("+e+","+mx+","+my+")");
     // 配列rectsのrectCount番目の始点を変更
    rects[rectCount].end_x=mx;
    rects[rectCount].end_y=my;
     // rectCountを増やす
    rectCount++;
    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+")");
     // 配列rectsのrectCount番目の始点を変更
    rects[rectCount].end_x=mx;
    rects[rectCount].end_y=my;
     // 再表示をおこなう
    repaint();
  }
  public void mouseMoved(MouseEvent e){}
}

次に進む