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