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(ミリ秒,ナノ秒)」と呼び出すことにより,実行を指定した時間だけ スリープさせる(止める)ことができる.