プログラムによるイベントリスナの追加・削除

プログラムによってイベントリスナを追加する方法は二つあります。

メンバーを宣言する

ユーザーによって作られたクラスを使ってコンポーネントをオーバーライドするとき、以下のようにメンバーファンクションをイベントリスナとして宣言できます。

ZUMLページの中で、use属性を宣言することでデフォルト以外のクラスを指定できます。以下に書いたようにZKにorg.zkoss.zul.Window [28]の代わりにMyClassを使用させます。

<window use="MyClass">
...
</window>

そうして、以下のようにデフォルトクラスから拡張することでMyWindow.javaを実装します。

public class MyWindow extends org.zkoss.zul.Window {
    public void onOK() { //add an event listener    
        ...//handles the onOK event (sent when ENTER is pressed)        
    }    
}

以下のように宣言すると、イベントについてより多くの情報を取得できます。

public void onOK(org.zkoss.zk.ui.event.KeyEvent event) {...}

異なったイベントは異なったイベントオブジェクトに関連している可能性があります。詳しくはAppendx Cを参照ください。

動的にイベントリスナを追加と削除

開発者はorg.zkoss.zk.ui.ComponentインターフェイスのaddEventListenerremoveEventListenerメソッドを使って、イベントリスナを動的に追加したり削除したりします。以下に書いたように、動的に追加されるイベントリスナはorg.zkoss.zk.ui.Componentインタフェイスを実装しなければなりません。

void init(Component comp) {
    ...    
    comp.addEventListener("onClick", new MyListener());    
    ...    
}
class MyListener implements org.zkoss.zk.ui.event.EventListener {
    public void onEvent(Event event) throws UiException {    
        ...//processing the event        
    }    
}

可延イベントリスナ(通信のタイミングを遅らせるイベントリスナ)

デフォルトではクライアントで起こったイベントはサーバーに送られます。しかし、多くのイベントリスナはユーザー側で何かを表示させるよりは、ただサーバーの状態をコントロールします。つまりこの状態制御リスナに対して起こったイベントは即座に情報を送る必要がありません。サーバーのパフォーマンスをあげるため、クライアントとサーバー間の通信量を最小にし、これらのリスナをまとめて送信します。便宜上これらを、可延イベントリスナと呼びます。

イベントリスナの通信を一時保留するのにorg.zkoss.zk.ui.event.Deferrableインタフェイスを実装し、以下のようにisDeferrableメソッドにtrueを返します。

public class DeferrableListener implements EventListener, Deferrable {
    private boolean _modified;    
    public void onEvent(Event event) {    
        _modified = true;        
    }    
    public boolean isDeferrable() {    
        return true;        
    }    
}

クライアントでイベントが発生したとき(例えば、ユーザーがリスト項目を選択したとき)、可延リスナだけが登録しているか、又は、イベントリスナが全く登録していない場合、ZKはイベントを送信しません。代わりに、イベントはクライアント側の待ち行列に保存されます。

少なくともひとつ可延でないリスナが登録しているのであれば、イベントはすぐにすべて待ち行列にあるイベントとともにサーバーへ送られます。すべてのイベントは順番通り送信されます。

【ヒント】:可延リスナを使って、サーバーの状態を維持します。一方、ユーザー側での視覚的な変更は。不可延リスナを使用します。

動的にページにてイベントリスナを追加と削除

開発者は動的にページへ(org.zkoss.zk.ui.Page)イベントリスナを追加できます。一度付加されると、指定したページのコンポーネントに名前が指定されたすべてのイベントはリスナへ送られます。

すべてのページイベントリスナは即時に作動するものではありません。つまりisArapメソッドは無視されます。

代表的な例はページ単位のイベントリスナを使用して、以下のように”変更フラグ”をコントロールします。

public class ModificationListener implements EventListener, Deferrable {
    private final Window _owner;    
    private final Page _page;    
    private boolean _modified;    

    public ModificationListener(Window owner) {    
        //Note: we have to remember the page because unregister might        
        //be called after the owner is detached        
        _owner = owner;        
        _page = owner.getPage();        
        _page.addEventListener("onChange", this);        
        _page.addEventListener("onSelect", this);        
        _page.addEventListener("onCheck", this);        
    }    
    /** Called to unregister the event listener.    
     */    
    public void unregister() {    
        _page.removeEventListener("onChange", this);        
        _page.removeEventListener("onSelect", this);        
        _page.removeEventListener("onCheck", this);        
    }    
    /** Returns whether the modified flag is set.    
     */    
    public boolean isModified() {    
        return _modified;        
    }    
    //-- EventListener --//    
    public void onEvent(Event event) throws UiException {    
        _modified = true;        
    }    
    //-- Deferrable --//    
    public boolean isDeferrable() {    
        return true;        
    }    
}

【メモ】:Deferrable インターフェイスを実装するかどうかはこの例の中ではオプションです。それはページイベントリスナはDeferrable を実装しなくてもデフォルトでも可延であるからです。

呼び出し順序

イベントリスナの呼び出す順序は以下の通りです。onClickイベントが届いたと想定しましょう。

  1. 目的コンポーネントへ追加されたonClickイベントのリスナをひとつずつ呼び出します。ただしこれは、リスナがorg.zkoss.zk.ui.event.Expressインターフェイスを実装する場合のみです。また、追加される順番と呼び出される順番は同じです。

  2. 目的コンポーネントの中のonClick属性に明記したスクリプトを呼び出します。

  3. org.zkoss.zk.ui.event.Expressインタフェイスを実装していない目的コンポーネントへ追加されたonClickイベントのリスナをひとつずつ呼び出します。追加される順番と呼び出される順番は同じです。

  4. 目的コンポーネントのonClickメンバーメソッドを呼び出します。

  5. 目的コンポーネントが属しているページへ追加されたonClickイベントに対してイベントリスナを呼び出します。追加される順番と呼び出される順番は同じです。

org.zkoss.zk.ui.event.Expressインタフェイスは装飾用のインタフェイスです。イベントリスナの呼び出される優先順位を変更する際に使用します。イベントリスナがコンポーネントではなく、ページへ追加された場合は、このインターフェースは使用できません。

呼び出し順序を中止

org.zkoss.zk.ui.event.Eventクラスの中のstopPropagationメソッドを呼ぶことで呼び出し順序を中止できます。一度あるイベントリスナがこのメソッドを呼び出すと、それ以降のすべてのイベントリスナは無視されます。



[28] デフォルトクラスはzul.jarにあるlang.xmlに定義されています。