2002 -0627 ver 1.00 発行 ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃.&&&& **** %%%%. JavaScript&Javaで目指そう!基本情報技術者試験 ┃ ┃&&&&&&******%%%%%% 執筆&編集 斎藤末広 suehiro@he.mirai.ne.jp ┃ ┃'&┃&''*┃*''%┃%' 発行 江口昌宏 jmaga@yscon.co.jp ┃ ┗━┻━━┻━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ★解除・登録 広告募集:http://www2.odn.ne.jp/~egu33/jmaga/java-maga.html ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ 第20号 2002/06/27 イベント駆動型プログラム(マウス) ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ プログラムを作成する上での注意事項: Windows98SE, SDK(JDK) 1.3.1,IE 5.5 を前提としています。 拡張子を表示するに設定してください。 ------------------------------------------------------------------------ ▼ イベント駆動型プログラム 運動会やサーカスなどをイベントといいます。日本語に訳すと催し物です。 ソフトウェアの世界では,イベントというと,マウスをドラッグしたとか, クリックした,また,窓の最大化ボタンを押したとかの操作を指します。 大型コンピュータが中心の頃のプログラムは,人間がスタートを指示して,数 時間後に終わるのを待つのが普通でした。このような処理の形態をバッチ処理と いいます。今では,人間が,コンピュータの画面に向い,マウスを押したり,文 字を入れたり,図を貼り付けたりして,コンピュータとやりとりしながら動作さ せるプログラムが増えています。こちらを対話型プログラムといいます。 対話型プログラムは,処理が始まったらそれをただ続けていくという流れでは なく,その都度の人間の指示に従って,やる内容を変化させていくという風につ くります。このような動きをするプログラムを,イベント駆動型プログラムとい います。 Java では,イベントがハードよりかソフトよりかによって,イベントを2つの レベルに分けます。ハードよりを低レベルイベント,ソフトよりを高レベルイベ ントといいます。低レベルイベントは,マウスクリック,キーボード入力などの イベントを指します。高レベルイベントとは,GUI において,ボタンを押したと か,テキスト枠の内容を変更したとかのイベントを指します。 今回は,イベント駆動プログラムのサンプルとして,マウスのドラッグの処理を 勉強します。 ------------------------------------------------------------------------ ▼ イベント駆動型の典型的なサンプル 次のようなサンプルを用意しました。画像が,マウスをクリックした場所に移 動するプログラムです。 例 j20-01 xSmpEvent01.java ソース http://www.yscon.co.jp/j/java/jmaga/j20/xSmpEvent01.java 動作 http://www.yscon.co.jp/j/java/jmaga/j20/xSmpEvent01.htm 説明がしやすいように,行番号を付けました。行番号の付いていないソースは, 最後に掲載しています。 1: import java.applet.Applet; 2: import java.awt.Graphics; 3: import java.awt.Image; 4: import java.awt.event.MouseAdapter; 5: import java.awt.event.MouseEvent; 6: 7: public class xSmpEvent01 extends Applet { 8: 9: Image ximg; 10: int x, y; 11: 12: MouseAdapter xia = new MouseAdapter(){ 13: public void mouseClicked(MouseEvent xmouse){ 14: x = xmouse.getX(); 15: y = xmouse.getY(); 16: repaint(); 17: } 18: }; 19: 20: public void init(){ 21: ximg = getImage(getDocumentBase(),"img01.gif"); 22: addMouseListener(xia); 23: } 24: 25: public void paint(Graphics xg){ 26: xg.drawImage(ximg, x, y, this); 27: } 28: } この xSmpEvent01.java の構造は, import 部 本体 宣言部 init()定義 paint()定義 です。 宣言部で,画像を扱うインスタンスと画像を表示する位置で使用する,x, y を 用意しています。さらに,この号で初めて登場した,MouseAdapter クラスのイン スタンスも生成しています。 init()定義では,画像の取り込みとこの号で話題にする Evet処理のプログラム があります。 paint()定義では,画像を x, y の位置に表示をしています。 ------------------------------------------------------------------------ ▼ マウスはどこ? xSmpEvent01 は,クリックしたところに画像を移動するプログラムです。肝心 のマウス関連の記述はどこにあるか見ましょう。 まず,import部にあります。 4: import java.awt.event.MouseAdapter; 5: import java.awt.event.MouseEvent; で,2つのクラスが import(輸入)されています。この記述から,MouseAdapter, MouseEvent ともに java.awt.evet フォルダにあることが分かります。 MouseEvent は,マウスが起こしたイベントを細かく知らせてくれるクラスです。 MouseEvnet と Event という名前が付いていますが,イメージは,マウスそのも のです。 MouseAdapter は,MouseEvent からのが頻繁に,マウス関係のイベントを受付 をする専用のクラスです。イメージは,マウス専用取次係(とりつぎ係)です。 こちら側(xSmpEvent01)とマウス(MouseEvent)の間に入ってくれるので,Adapter という名前が付いています。 ラジカセと100Vコンセントの間に入るアダプタのと同じアダプタです。100V電 源にあたるものがマウスで,ラジカセにあたるのが,本体のプログラム (xSmpEvent01)です。 この2つのクラス,MouseAdapter と MouseEventを利用して 12: MouseAdapter xia = new MouseAdapter(){ 13: public void mouseClicked(MouseEvent xmouse){ 14: x = xmouse.getX(); 15: y = xmouse.getY(); 16: repaint(); 17: } 18: }; と書かれています。new があることから分かるように,これは構築子(コンスト ラクタ)です。マウス取次係の分身(インスタンス) xia を生成しています。 生成するさいに,mouseClicked メソッド(関数)を定義しています。これが, 取次時に,MouseAdapterクラスの分身(インスタンス)である xia が,処理して くれる内容になります。mouseClicked だけが書いてあるので,他のマウスのイ ベントは無視されます。 ここで,mouseClicked のメソッド(関数)名に x がついていないところを注意 してください。Jマガでは,プログラムの作り手が変更できるところは,x 付き にしています。この mouseClicked メソッドは,すでに,マウス取次係MouseAdapter クラス内で,クリックしたときの仕事の名前は,mouseClicked に定義することと 記述されています。そのため,生成と同時に,mouseClicked というメソッド(関数) を同じ名前で再定義しています。この再定義のことを専門用語では,上書き(うわ がき,オーバライド)と言います。オーバライドは直訳すると,上乗りですが, 上書きが一般的な訳語として使用されています。 13: public void mouseClicked(MouseEvent xmouse){ 14: x = xmouse.getX(); 15: y = xmouse.getY(); 16: repaint(); 再定義(上書き)された mouseClicked メソッド(関数)を詳細にみましょう。 () の中の MouseEvent xmouse で,この関数の中では,マウスイベントの分身名 (インスタンス)が,xmouse として登場することになります。xmouse は,new さ れていません。すでに,MouseAdapter の中で存在していると予想できます。 x = xmouse.getX(); は,MouseEvent の分身 xmouse が,getX()を実行して, その結果を x に入れます。y 座標の位置も同様に y に入ります。 repaint()で,このマウス取次係が,このプログラム(xSmpEvent01)に対して, repaint()をしなさいと伝えます。 ------------------------------------------------------------------------ ▼ init() と paint() このプログラムの残りのところを見ましょう。 init() は,アプレットが表示されるときに先だって実行されます。 21: ximg = getImage(getDocumentBase(),"img01.gif"); 22: addMouseListener(xia); 21 行目では,img01.gif 画像を探してきて,その画像を ximg に設定します。 22 行目は,今回のテーマである,マウスイベントに関係する記述です。 addMouseListener(xia) は,xia というマウス取次係をこのプログラムに add (追加)しています。マウスとこのプログラム(xSmpEvent01)の間に,xia に立っ てもらい,マウスへ対応をしてもらいます。具体的にどう対応するかは,11 行目 から16行目にありました。 ------------------------------------------------------------------------ ▼ 再度,リストを確認 1: import java.applet.Applet; 2: import java.awt.Graphics; 3: import java.awt.Image; 4: import java.awt.event.MouseAdapter; 5: import java.awt.event.MouseEvent; 6: 7: public class xSmpEvent01 extends Applet { 8: 9: Image ximg; 10: int x, y; 11: 12: MouseAdapter xia = new MouseAdapter(){ 13: public void mouseClicked(MouseEvent xmouse){ 14: x = xmouse.getX(); 15: y = xmouse.getY(); 16: repaint(); 17: } 18: }; 19: 20: public void init(){ 21: ximg = getImage(getDocumentBase(),"img01.gif"); 22: addMouseListener(xia); 23: } 24: 25: public void paint(Graphics xg){ 26: xg.drawImage(ximg, x, y, this); 27: } 28: } マウスのイベントから見ると,このプログラムは,xia マウス取次係に,マウ スがクリックされたら,どうするかを覚えてもらい,(12行目から18行目),xiaに, このプログラムとマウスの間に入ってもらい,働いてもらうというプログラムで した。(22行目) その他の部分は,前号までに何回も登場した記述ですね。 ------------------------------------------------------------------------ ▼ 直接法で書き換え xSmpEvent.java では,xia が,12 行目で定義されて,22 行目で使われてい ます。使われているところに,直接書いて,xia は,無名インスタンスになって もらい,表舞台から退場してもらいましょう。 元プログラムで対象になるところ 12: MouseAdapter xia = new MouseAdapter(){ 13: public void mouseClicked(MouseEvent xmouse){ 14: x = xmouse.getX(); 15: y = xmouse.getY(); 16: repaint(); 17: } 18: }; 19: 20: public void init(){ 21: ximg = getImage(getDocumentBase(),"img01.gif"); 22: addMouseListener(xia); 23: } が次のように変ります。分かりやすいよう前の行番号をそのまま残しておきます。 20: public void init(){ 21: ximg = getImage(getDocumentBase(),"img01.gif"); 22: addMouseListener( new MouseAdapter(){ 13: public void mouseClicked(MouseEvent xmouse){ 14: x = xmouse.getX(); 15: y = xmouse.getY(); 16: repaint(); 17: } 18: } 22: ); 23: } どうですか,変更前の22行目を見て下さい。 22: addMouseListener(xia); この xia を 12: MouseAdapter xia = new MouseAdapter(){ 13: public void mouseClicked(MouseEvent xmouse){ 14: x = xmouse.getX(); 15: y = xmouse.getY(); 16: repaint(); 17: } 18: }; で置き換えましたね。 置き換えしたプログラムを新たに行番号をふり直して,プログラムリストの形 を整えたのが,次の xSmpEvent02.java です。下を見て下さい。 ------------------------------------------------------------------------ ▼ 無名インスタンスを使用した例 次の例が書き換えたものです。違うプログラムと分かるように,画像は,img02.gif に変更しました。(枠つきの木の絵から枠無しの木の絵に変更) 例 j20-02 xSmpEvent02.java ソース http://www.yscon.co.jp/j/java/jmaga/j20/xSmpEvent02.java 動作 http://www.yscon.co.jp/j/java/jmaga/j20/xSmpEvent02.htm 説明がしやすいように,行番号を付けました。行番号の付いていないソースは, 最後に掲載しています。 1: import java.applet.Applet; 2: import java.awt.Graphics; 3: import java.awt.Image; 4: import java.awt.event.MouseAdapter; 5: import java.awt.event.MouseEvent; 6: 7: public class xSmpEvent02 extends Applet { 8: 9: Image ximg; 10: int x, y; 11: 12: public void init(){ 13: ximg = getImage(getDocumentBase(),"img02.gif"); 14: 15: addMouseListener(new MouseAdapter(){ 16: public void mouseClicked(MouseEvent xmouse){ 17: x = xmouse.getX(); 18: y = xmouse.getY(); 19: repaint(); 20: } 21: }); 22: } 23: 24: public void paint(Graphics xg){ 25: xg.drawImage(ximg, x, y, this); 26: } 27: } このように直接法を利用してコンパクトにすることによって,マウス関連の処理 を書くところを絞ることできます。 import のところで, 4: import java.awt.event.MouseAdapter; 5: import java.awt.event.MouseEvent; init()のところで 15: addMouseListener(new MouseAdapter(){ 16: public void mouseClicked(MouseEvent xmouse){ 17: x = xmouse.getX(); 18: y = xmouse.getY(); 19: repaint(); 20: } 21: }); と書き,実際の仕事は, 17: x = xmouse.getX(); 18: y = xmouse.getY(); 19: repaint(); の3行でした。つまり,マウスをクリックしたときにどうするかは,この3行 のみを考えて,後は決まり切った書き方をすればいいことになります。 ------------------------------------------------------------------------ ▼ その他のマウスイベント マウスのクリックを含めて,他のマウスのイベント関連を整理すると, MouseAdapter が取次可能なイベント mouseClicked マウスをクリック(押してから離す) mouseEntered マウスが設定した境界内に入る mouseExited マウスが設定した境界内から出る mousePressed マウスを押す mouseReleased マウスを離す MouseMotionAdapter が取次可能なイベント mouseDragged ドラッグ mouseMoved 動く(ドラッグは含まない) があります。 MouseAdapter は,クリックなどマウスから合図が比較的ゆっくりなものを担当 します。これは私の予想ですが,合図の間隔は,1/10 秒程度でしょう。 MouseMotionAdapter は,マウスの動きを担当して,合図の間隔は,1/100 秒程度 と思います。 MouseAdapter も MouseMotionAdapter もイメージは,マウス専用の取次係です。 取次を受け付けるのは,ともに MouseEvent クラスのインスタンスです。 例として MousePressedメソッドとMoseMovedメソッドを追加するには 12: public void init(){ 13: ximg = getImage(getDocumentBase(),"img02.gif"); 14: 15: addMouseListener(new MouseAdapter(){ 16: public void mouseClicked(MouseEvent xmouse){ 17: x = xmouse.getX(); 18: y = xmouse.getY(); 19: repaint(); 20: } 21: }); 22: } に対して,以下のように挿入します。挿入したころがわかりやすいように,前の 行番号を残しています。また,コメント(メモ)を書いておきました。 12: public void init(){ 13: ximg = getImage(getDocumentBase(),"img02.gif"); 14: 15: addMouseListener(new MouseAdapter(){ 16: public void mouseClicked(MouseEvent xmouse){ 17: x = xmouse.getX(); 18: y = xmouse.getY(); 19: repaint(); 20: } public void mouseExited(MouseEvent xmouse){ x = 1000; // 表示できない場所を代入 y = 1000; // 表示できない場所を代入 repaint(); 21: }); // 閉じる addMouseListener addMouseMotionListener(new MouseAdapter(){ public void mouseMoved(MouseEvent xmouse){ x = xmouse.getX(); // 対応する処理を書く y = xmouse.getY(); // 対応する処理を書く repaint(); // 対応する処理を書く } }); 22: } // 閉じる init() このプログラムを,xSmpEvent03.java としました。この号の最後で完全な ソースを公開しています。 例 j20-03 xSmpEvent03.java マウスイベント処理メソッドの追加 ソース http://www.yscon.co.jp/j/java/jmaga/j20/xSmpEvent03.java 動作 http://www.yscon.co.jp/j/java/jmaga/j20/xSmpEvent03.htm ------------------------------------------------------------------------ ▼ 他のイベント処理 低レベルイベント処理のもう一つの代表例としては,キーボードの入力処理が あります。これは,次号で扱います。 ボタンクリックなどの高レベルのイベント処理も順番に扱っていきます。 なお,イベント処理は,Adapter(取次係)を利用せず,Listener interface の 仕組みを利用する方法もあります。こちらは,interface を学習したから勉強し ましょう。interface は,クラスもどきです。これはまたすごい仕組みです。楽し みにしておいてください。 ------------------------------------------------------------------------ ▼ 今回のサンプルのソース マウスイベント処理 Adapter を利用した単純な例 例 j20-01 xSmpEvent01.java ソース http://www.yscon.co.jp/j/java/jmaga/j20/xSmpEvent01.java 動作 http://www.yscon.co.jp/j/java/jmaga/j20/xSmpEvent01.htm xSmpEvent01.htm