Section 3.8 action メソッド

今回もイベント関係の話ね。
前回はレイヤがクリックされた時に呼び出される onClick メソッドと、 マウスのボタンが離された時に呼び出される onMouseDown メソッドを使ったよね。
でも…
ん?
あれって、時計の表示の更新に関係あるの?
あー、前回のイベントハンドラはそれとは直接関係ないよ。
えっ、関係ないの!?
でもイベントには色々種類があるから、時計の表示を更新するために使うイベントハンドラも後でちゃんと作るよ。
あ、そうなの?
うん。
けどそれは次回にして、今回は action メソッドについて見ていこうと思うんだ。
action メソッド?
action メソッドっていうのは、Layer クラスとかで使える、 ちょっと特殊なイベントハンドラだよ。
特殊って?
onClick メソッドとか onMouseDown メソッドは、 マウスがクリックされたとか、ボタンが離されたとか、特定のイベントが起こった時にだけ呼び出されるよね。
うん、そうだね。
action メソッドは、特定のイベントが起こった時だけじゃなくて、どのイベントが起こった時でも呼び出されるんだ。
ってことは、マウスがクリックされても呼び出されるし、ボタンが押されたり離されたりしても呼び出されるってこと?
うん、そういうこと。
あと、普通のイベントハンドラとのもう一つの大きい違いは、イベントが起きた時に「コンストラクタに指定したオーナーの action メソッドが呼び出される」ってこと。
オーナー?
例えば Layer クラスの場合は、コンストラクタの第1引数に指定する、レイヤが所属するウィンドウがオーナーになるんだ。
それじゃ action メソッドは Layer クラスのメソッドじゃないってこと?
そ。レイヤに関するイベントが起こった時に呼び出される action メソッドは Window クラスの action メソッドなんだ。
でも、1つのウィンドウの中にいっぱいレイヤを作れるんでしょ?
それだと、イベントが起こったのがどのレイヤか判らなくなっちゃわない?
もちろんその辺はちゃんと考えてあるよ。
じゃ、ここからは例を見ながら action メソッドについて説明していくね。
はーい。

action メソッドの使用例(レイヤ上のマウスカーソルの位置表示)>

class MyWindow extends Window
{
    // コンストラクタ
    function MyWindow()
    {
        super.Window();

        add(new Layer(thisnull));  // プライマリレイヤを作ります

        // ウィンドウのクライアント領域のサイズを 400×300 にします
        setInnerSize(400, 300);
        // プライマリレイヤのサイズをクライアント領域に合わせます
        primaryLayer.setSize(innerWidth, innerHeight);

        visible = true;
    }

    // デストラクタ
    function finalize()
    {
        super.finalize();
    }

    // action メソッド
    function action(ev)
    {
        // ↓プライマリレイヤでイベントが起こった場合に、この条件式は真になります
        if(ev.target == primaryLayer)
        {
            if(ev.type == "onMouseMove")
            {
                // onMouseMove イベントが起こった場合は、マウスカーソルの位置をタイトルに表示します
                caption = "マウスカーソルの位置:(" + ev.x + ", " + ev.y + ")";
            }
            else if(ev.type == "onMouseLeave")
            {
                // onMouseLeave イベントが起こった場合は、以下のメッセージをタイトルに表示します
                caption = "マウスカーソルはプライマリレイヤの外にあります";
            }
        }
    }
}

var win = new MyWindow();  // ウィンドウを作ります

まずは実行してみて。
うん。

<実行結果>

実行直後に表示されたウィンドウ

ふつうのウィンドウが表示されたね。
じゃあ、マウスカーソルをプライマリレイヤの上で動かしてみて。
うん、わかった。

プライマリレイヤの上でマウスカーソルを動かした時のウィンドウ

あっ、タイトルバーにマウスカーソルの座標が表示された!
しかも座標の表示はリアルタイムに更新されてるでしょ。
うん、マウスカーソルを動かすと表示が変わるね。
それじゃ、今度はマウスカーソルをプライマリレイヤの外に出してみて。

マウスカーソルをプライマリレイヤの外に出した時のウィンドウ

あ、タイトルバーの表示が「マウスカーソルはプライマリレイヤの外にあります」になったね。
今回のスクリプトは2種類のイベントを処理してるんだけど、 action メソッドを使うと両方のイベントを処理できるんだ。
へぇ、そうなんだ〜。
action メソッドって便利なメソッドだね。
場合によってはね。
それじゃ、スクリプトの方を見ていくね。
は〜い!
コンストラクタデストラクタは解ると思うから、説明は省略するね。
うん、おっけーだよ。
じゃ、action メソッドの説明をするね。
まずは action メソッドの引数から。
ev っていう引数があるね。
うん。action メソッドの引数はこの1つだけ。
この引数は辞書配列になってて、その要素はイベントの種類によって違うんだ。
辞書配列って、§1.15で出てきたよね。
要素が文字列になってる配列なんだよね。
そうそう。
で、まずチェックするのが target っていう要素と type っていう要素。
それってどんな要素なの?
target っていう要素は、イベントが起こったオブジェクトになってるんだ。
じゃあ、『ev.target == primaryLayer』っていうのは、 イベントが起こったのがプライマリレイヤだったら真になるってこと?
ん、そだよ。
もう一つの type っていう要素は起こったイベントの種類を表してて、そのイベントが起きた時に呼び出されるメソッドの名前と同じになってるんだ。
だから、例えばレイヤがクリックされた場合は、type"onClick" っていう文字列になるワケ。
target を見ればイベントが起こったオブジェクトが判って、 type を見ればどんなイベントが起こったか判るようになってるんだね。
うん、そういうこと。
なるほどね〜、だから action メソッドだけで色んなイベントの処理ができるんだね。
それじゃ次は action メソッドで処理してるイベントの説明をするね。
最初は onMouseMove っていうイベントだね。
これってマウスカーソルが動いた時に起きるイベントなんじゃない?
ん、そのとーり。
Layer クラスには onMouseMove っていうメソッドがあって、 このメソッドはレイヤの上でマウスカーソルが移動した時に呼び出されるんだ。

onMouseMove メソッドの引数>
引数名引数の意味値の種類
第1引数xマウスが移動した位置の x 座標数値
第2引数yマウスが移動した位置の y 座標数値
第3引数shiftマウスが移動した時に押されていたシフト系のキー/マウスボタンの種類mbLeft(左ボタン), mbRight(右ボタン), mbMiddle(中ボタン), ssAlt(ALTキー), ssShift(SHIFTキー), ssCtrl(CTRLキー)のビット OR による組み合わせ

引数は onMouseUp メソッドのとちょっと似てるね。
だね。今回はマウスカーソルがある位置の座標を表示するから xy を使ってるんだ。
あ、そういえば action メソッドだと引数はどうやったら判るの?
引数も辞書配列に入ってるんだ。
例えば xev.xyev.y で参照できるよ。
引数の名前と要素の名前が同じになってるんだね。
ん、そうだよ。
それじゃ次は onMouseLeave メソッドね。
これはどんなイベントが起きた時に呼び出されるメソッドなの?
onMouseLeave メソッドは、 マウスカーソルがレイヤの範囲外に出て行った時に呼び出されるメソッドなんだ。ちなみに引数は無いよ。
そっか、だから onMouseLeave メソッドが呼び出されたら、マウスカーソルがプライマリレイヤの外に出たって判るんだね。
うん。
あと、これと逆の onMouseEnter っていうメソッドもあるよ。
逆ってことは、マウスカーソルがレイヤの範囲内に入った時に呼び出されるメソッド?
そうそう。
でも、マウスカーソルがレイヤの範囲内に入ると onMouseMove メソッドも呼び出されるから、今回は使ってないけどね。
あ、そうなんだ。
こんなふうに action メソッドを使うと、 前回みたいにわざわざ Layer クラスを継承して新しいクラスを作らなくてもイベント処理ができるっていうメリットもあるよね。
そういえば今回のプライマリレイヤは Layer クラスのオブジェクトになってるもんね。
とは言っても、オブジェクトやイベントの数が多い時には、action メソッドだけで全部のオブジェクトの全部のイベントを処理しようとすると、 action メソッドが複雑になっちゃうけどね。
そっか、どのイベントを action メソッドで処理すればいいかをちゃんと考えなくちゃいけないんだね。
ん、そういうことだね。
じゃ、今回はここまで。
また次回ね!


前へ | TOP | 次へ