アニメーション


アニメーション(動画)を実現するには,適当な時間間隔で画面の書き換えを 行えば良い.先ほどの MouseDraw を改造して,一秒に一回,Line の終点のy 座標を10増やすというアニメーションを実現したのが以下のプログラムである.
import java.io.*;
import java.awt.*;
import java.awt.event.*;

class Line{
  public int start_x,start_y,end_x,end_y;
  public Line(int x1,int x2,int x3,int x4){
   start_x=x1;
   start_y=x2;
   end_x=x3;
   end_y=x4;
  }
}

class MouseDraw extends Frame implements KeyListener, MouseListener, MouseMotionListener{
  public Line[] lines;
  int lineCount;
  boolean dragging;
  Color lineColor;
  public MouseDraw(String title){
    super(title);
    lines=new Line[10];
    lineCount=0;
    dragging=false;
    lineColor=Color.black;
    addKeyListener(this);
    addMouseListener(this);
    addMouseMotionListener(this);
  }
  public static void main(String args[]) throws IOException{
    MouseDraw frame=new MouseDraw("MouseDraw");
    frame.setSize(600,400);
    frame.show();
      // 現在,実行中のスレッドを得る.
    Thread t=Thread.currentThread();
      // 無限ループに入る.
    for(;;){
      try{
          // 1000ミリ秒(1秒)待つ(スリープする)
        t.sleep(1000,0);
      }
      catch (InterruptedException e){
        System.err.println("Interrupted");
      }
        // 変数frameに入っている MouseDrawクラスのインスタンスの動的メソッド
        // dropを呼び出す.
      frame.drop();
    }
  }
  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); // イメージを本物のスクリーンに書き込む
  }
    // 1秒に1回呼ばれる.
  public void drop(){
    int i;
      // 0からlinesCountの間
    for(i=0;i< lineCount;i++){
        // lines配列のi番目の要素の end_y というインスタンス変数の値を10増やす
      lines[i].end_y+=10;
    }
      // 再表示して,画面を更新する.
    repaint();
  }
  public void paint(Graphics g){
    int i;
    g.setColor(Color.white);
    g.fillRect(0,0,600,400);
    g.setColor(lineColor);
    for(i=0;i< lineCount;i++){
      g.drawLine(lines[i].start_x,lines[i].start_y,
                 lines[i].end_x,lines[i].end_y);
    }
    if(dragging){
      g.setColor(Color.red);
      g.drawLine(lines[i].start_x,lines[i].start_y,
                 lines[i].end_x,lines[i].end_y);
    }
  }
  public void keyPressed(KeyEvent e){
    int key=e.getKeyChar();
    System.out.println("keyPressed("+e+","+key+")");
    if(key=='q') System.exit(0);
  }
  public void keyReleased(KeyEvent e){}
  public void keyTyped(KeyEvent e){}
  public void mousePressed(MouseEvent e){
    int mx=e.getX(),my=e.getY();
    System.out.println("mousePressed("+e+","+mx+","+my+")");
    lines[lineCount]=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].end_x=mx;
    lines[lineCount].end_y=my;
    lineCount++;
    dragging=false;
    repaint();
  }
  public void mouseClicked(MouseEvent e){}
  public void mouseEntered(MouseEvent e){}
  public void mouseExited(MouseEvent e){}
  public void mouseDragged(MouseEvent e){
    int mx=e.getX(),my=e.getY();
    System.out.println("mouseDrag("+e+","+mx+","+my+")");
    lines[lineCount].end_x=mx;
    lines[lineCount].end_y=my;
    repaint();
  }
  public void mouseMoved(MouseEvent e){}
}
mainのメソッドの後ろに付け加えられた,
    Thread t=Thread.currentThread();
    for(;;){
      frame.drop();
      try{
        t.sleep(1000,0);
      }
      catch (InterruptedException e){
        System.err.println("Interrupted");
      }
    }
が,画面の書き換えを行うメソッド drop を1秒ごとに呼び出す部分である. まず,
  for(;;){
    ブロック
  }
というのは,ブロックの部分を永遠に(このプログラムではC-c で抜けるか,q というキー入力をして,System.exit(0)で抜けるかするまで)繰り返し実行す るための構文である.

dropを呼んだ後に1秒待つ必要があるが,Java 言語ではプログラムの並行実行 をするために,スレッドという概念があり Thread クラス が対応している.実行の中断,再開はスレッドを単位に行 うが,このプログラムでは動作しているスレッドは main から動き始めた1つ だけであり,Thread.currentThread() で得ることができる.ここで得た t に, 「t.sleep(ミリ秒,ナノ秒)」と呼び出すことにより,実行を指定した時間だけ スリープさせる(止める)ことができる.


GUI部品の組み合わせ
ktanaka@XXX.ecc.u-tokyo.ac.jp