Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Nexaweb

...

  • NXML macro commands
  • Server side resources such as JSP pages, Servlets and static pages
  • Client-side java code including calls to MCOs and system services

 This section covers the following topics:

  • Event overview
  • Using macros to handle events
  • Server-side event handling
  • Client-side event handling
  • Event ordering

Event Overview

In event-driven programming, you define an event handler for each event to which the application needs to react.  Such events include:

  • Physical events such as a keystroke, button click, or mouse hovering over a component
  • Higher-level UI events such as a selection being made from a dropdown list or a checkbox changing state.

Event handlers for these events might include a:

  • Macro - a client-side script included in the XML defining the UI
  • Server-side document
  • Method of a user-defined client class or MCO

In any case, the event handler executes some application functionality, in sufficient details, to appropriately react to a particular user action. The Nexaweb client relies on events to respond to user commands.The Nexaweb client defines approximately 30 events.  See the UI documentation for details on what events the Nexaweb client can fire for each component.

All events cause the client to create an event object with information describing the event.  After the client creates the event object, the client either:

  • Executes the macro
  • Encodes the event information and sends it by HTTP to a server-side handler
  • Passes the event object to the client-side MCO hand

For example, given the following code:

...

は、onMouseOver などのハードウェアの直接応答から、onStateChange などの論理イベントに至るまで、さまざまなレベルのイベントを処理する機能を備えています。Nexaweb に対応したアプリケーションは、次の方法によってこのようなイベントを処理します。
  • NXML マクロ コマンド
  • JSP ページ、サーブレット、静的ページなど、サーバーサイドのリソース
  • MCO やシステム サービスへの呼び出しを含むクライアントサイドの Java コード
ここでは次のトピックについて説明します。
  • イベントの概要
  • マクロを使用したイベントの処理
  • サーバーサイドのイベント処理
  • クライアントサイドのイベント処理
  • イベントの順序付け
イベントの概要
イベント方式のプログラミングでは、アプリケーションが反応する必要のある各イベントに対してイベントハンドラを定義します。このようなイベントには次のものがあります。
  • キーストローク、ボタンのクリック、コンポーネント上でのマウスのホバーリングなどの物理的イベント
  • ドロップダウン リストや状態を変更するチェックボックスで行われる選択など、より高度な UI イベント
このようなイベントのイベントハンドラには、次のものがあります。
  • マクロ (UI を定義する XML に含まれるクライアントサイドのスクリプト)
  • サーバーサイドのドキュメント
  • ユーザー定義のクライアント クラスまたは MCO のメソッド
いずれの場合も、 イベントハンドラは、必要とされるアプリケーションの機能を十分に実行して、特定のユーザーアクションに対して適切に反応します。Nexaweb クライアントは、イベントに依存してユーザーコマンドに応答します。Nexaweb クライアントは約 30 のイベントを定義します。Nexaweb クライアントが各コンポーネントに対して発生させることが可能なイベントの詳細については、UI ドキュメントを参照してください。
どのようなイベントの場合でも、クライアントはイベントを説明する情報を含むイベントオブジェクトを作成します。クライアントはイベントオブジェクトを作成した後で、次のいずれかを実行します。
  • マクロを実行する
  • イベント情報をエンコードして、HTTP を使用してサーバーサイドのハンドラに送信する
  • イベント オブジェクトをクライアントサイドの MCO ハンドラに渡す
次のコード例を使用して説明します。

<button text="my button" onCommand="buttonclick.jsp"

...

/>

...

onCommand

...

  • id attribute - a user defined id or a Nexaweb assigned id
  • event attribute - the 'onCommand' in this case

 Using Macro Event Handlers

You can define a client-side macro script in the UI document to handle a client event. The following example defines:

...

イベントがサーバー上の

buttonclick.jspに発生して、自動的に次の属性を URL パラメータとして渡します。
  • id 属性 - ユーザー定義の ID または Nexaweb で指定された ID
  • event 属性 - この例では 'onCommand'

マクロのイベントハンドラの使用

クライアントサイドのマクロスクリプトを UI ドキュメントで定義して、クライアントイベントを処理できます。以下に示す例では、次の内容が定義されます。
  • changeLabelTextMacro マクロ
  • ボタンの onCommand ハンドラを macro://changeLabelTextMacro.execute()

...

  • として定義
このマクロでは、ユーザーがボタンをクリックすると、クライアントがラベルのテキストを "Some new text

...

" に更新します。

 

Code Block

...

languagehtml/xml
linenumberstrue
<macro:macro xmlns:macro="http://nexaweb.com/macro"

...

 

...

name="changeLabelTextMacro">

...

<xu:modifications document="nxml" version="1.0"

...

 xmlns:xu="http://nexaweb.com/xupdate">

...


<xu:set-attribute select="id(''mylabel'')">

...


<xu:attribute name="text" value="Some new text"/>

...


</xu:set-attribute>

...


</xu:modifications>
</macro:macro>

...


<button onCommand="macro://changeLabelTextMacro.execute()"

...

 

...

text="Change mylabel text" />
<label id="mylabel" text="This is some text" />

Server-Side Event Handling

Firing a client event to the server is a more powerful tool when the server is interested in the user's action on the client side. The handler can be a JSP page, a servlet, or a static page with XUpdate statements.  

The following example shows a JSP page receiving event parameters and generating an XUpdate document to return to the client.

...

 

サーバーサイドのイベント処理

クライ アントイベントをサーバーに発生させる機能は、サーバーがクライアントサイドでのユーザーアクションに関与する場合に非常に強力なツールとなります。この ハンドラは、JSP ページ、サーブレット、または XUpdate 文を使用する静的ページの場合があります。

次の例では、JSP ページがイベントパラメータを受け取って XUpdate ドキュメントを生成し、クライアントに返すプロセスを示します。

UI ドキュメントはハンドラを次のように指定します。

 

Code Block
<button onCommand="changeLabelText.jsp" text="Change mylabel text" />
<label id="mylabel" text="This is some text" />

 

changeLabelText.

...

jspは、サーバーサイドでイベントを処理します。

 

Code Block

...

...

<xu:modifications document="nxml" version="1.0" 

...

xmlns:xu=

...

http://nexaweb.com/xupdate">

...

<xu:set-attribute select="id('mylabel')">

...


<xu:attribute name="text" value="Button <%=

...

 

...

(request.getParameter("id") + " fired event " +

...

 

...

request.getParameter("event")) %>"/>

...


</xu:set-attribute>
</xu:modifications>

...

 

ここでは、サーバーサイドの JSP ページでrequest.getParameter("id")

...

とrequest.getParameter("event")

...

を使用して、ボタン要素の id と発生するevent の名前を取得します。onCommand属性を設定する際に、この idevent の値を指定する必要はありません。これらの値は、実行時に URL に添付されます。さまざまな UI 要素から発生させることができるイベントについては、UI リファレンスドキュメントを参照してください。

 

サーバーサイドでクライアントイベントを処理する際にサーバーセッションまたはサーバーサイドのドキュメントにアクセスする必要がある場合は、次を呼び出すことができます。
Code Block
SessionManager smgr = ServiceManager.getSessionManager();
ServerSession nxsession = smgr.findByRequest(request);

...

 

サーバーの UI DOM

...

が有効になっている場合は、次のコードを使用して、サーバーサイドで UI ドキュメントを取得できます。

Document uiDom = nxsession.getDocumentRegistry().getUiDocument();

...

また、返されたDocumentを調べるか、com.nexaweb.

...

Client-Side Event Handling

If the server does not need to be notified of an event, the event can be handled immediately by a call to a system service or to a customer-created client-side class called a Managed Client Object (MCO).  This client-side method can update the client UI, create or update different documents, or even connect to the server again.  The following examples show uses of client-side code invocation for handling events. 

1. Simple Element Access and Attribute Change

...

xmlで API を使用して、名前によって要素を検索することができます。
 

クライアントサイドのイベント処理
サーバーにイベントを通知する必要がない場合は、システムサービスまたは MCO (Managed Client Object) と呼ばれる、顧客に よって作成されたクライアントサイドのクラスへの呼び出しによって直ちにイベントを処理することができます。このクライアントサイドのメソッドにより、ク ライアント UI の更新、各種ドキュメントの作成または更新、さらにサーバーへの再接続を行うことができます。次の例では、イベントを処理するためにクライアントサイドの コード呼び出し機能を使用する方法を示します。

1. 簡単な要素へのアクセスと属性の変更
この例は、clientSessionlabel 要素を順に取得するコードを示します。これらの要素を取得した後、ClientSession のgetEventHandler().getClientEvent()

...

In this example, the UI document declares the MCO and specifies the handler:

...

languagehtml/xml
linenumberstrue

...

を呼び出して ClientEvent オブジェクトを取得します。このオブジェクトはイベントのパラメータを提供します。使用可能なパラメータはイベントの種類によって異なります。

この例では、UI ドキュメントは MCO を宣言してハンドラを指定します。

 

Code Block
<mco:declarations xmlns:mco="http://nexaweb.com/mco">

...


...

<mco:mco id="eventMco" src="pkg.EventHandlers"/>

...

</mco:declarations>
<nxml>

...

<rootPane>

...


<flowLayout/>

...


...

<button onCommand="mco://eventMco.changeLabelText()"

...

 

...

text="Change mylabel text" />

...


...

<label id="mylabel" text="This is some text" />

...

</rootPane>
</nxml>

The handler is method changeLabelText in user-created EventHandlers.java:

...

languagejava
linenumberstrue

...

 


このハンドラは、ユーザーによって作成されたEventHandlers.java内にあるchangeLabelTextメソッドです。

 

Code Block
private static final XPath LABEL_XPATH =

...


XPathFactory.createXPath("id('mylabel')");

...



public void changeLabelText(){

...

ClientSession s = getSession();

...


...

Element label = LABEL_XPATH.evaluateAsElement(

...

s.getDocumentRegistry().getUiDocument());

...



...

Object domLock =

...

label.getOwnerDocument().getDomSynchronizationObject();

...



ClientEvent event = s.getEventHandler().getClientEvent();

...


synchronized(domLock){

...


label.setAttribute("text", "some new text from "

...


...

+ event.getParameter("id") + ":"

...

+ event.getParameter("event"));

...

}

...


}

 

2.

...

時間のかかるクライアンサイドタスクの実行


イベント ハンドラで時間のかかるタスクを行う場合、待機中のカーソルを使用してユーザーに待機するよう通知した後、別のスレッドでタスクを実行できます。次の例で は、これを実行する方法を示します。この例は、ラベルの更新を完了するまでに 5 秒かかるタスクを示しています。このタスクがクライアントで実行中であることをユーザーに知らせるために、displayService.pushGlassPane()

...

を実行して待機中のカーソルを表示し、この間ユーザーが入力を行わないようにします。タスクが終了すると、displayService.popGlassPane()

...

は待機中のカーソルを解除して再び入力を受け付けます。

次に、この UI ドキュメントを示します。

 

Code Block
<button onCommand="mco://eventMco.waitOnLongTask()" text="Change mylabel text" />
<label id="mylabel" text="This is some text" />

The following shows the MCO handler method:

...

languagejava
linenumberstrue

...

 


次に、MCO ハンドラのメソッドを示します。

 

Code Block
public void waitOnLongTask(){

...


final ClientSession s = getSession();

...


s.getDisplayService().pushGlassPane();

...

new Thread(new Runnable(){

...


...

public void run(){

...


...

try{

...


Thread.sleep(5000);

...


...

onChangeLabelText();

...

}catch(Exception e){

...


...

e.printStackTrace();

...


}finally{

...


...

s.getDisplayService().popGlassPane();

...


...

}

...


...

}

...


...

}).start();

...

}
}

 

3.

...

This is a special event that you can use when you want to add validation code to an element or check other conditions before the focus is lost from the current element. The client fires the onBeforeActiveLost event handler before it fires an element's onActiveLost. When the event handler returns false, the event is consumed; in other words, the focus stays in the currently focused element.  Only a a client-side MCO can handle an onBeforeActiveLost event handler since neither macros nor server-side handlers can return boolean.  Remember that an onBeforeActiveLost handler must execute very quickly.

The following example ensures that a textField's input length is exactly 10 characters. It prevents the user from being able to click or tab away from the textField if it has fewer or more than 10 characters. 

The following shows the UI document:

...

onBeforeActiveLostイベントハンドラ

これは、現要素からフォーカスがロストする前に、要素に検証コードを追加する際、または他の状態を確認する際使用することができる特別なイベントです。クライアントは要素の onActiveLost を発生させる前に onBeforeActiveLost イベントハンドラを発生させます。イベントハンドラが false を返す時、イベントは消費されます。つまり、現在のフォーカス要素にフォーカスは残ります。クライアントサイドのMCO だけが、onBeforeActiveLost イベントハンドラをハンドルすることができます。なぜならマクロやサーバーサイドのハンドラはブール値を戻すことができないからです。onBeforeActiveLost ハンドラは非常に早く実行しなくてはならないことに注意して下さい。

次の例は textField の入力長さが厳密に10 文字を維持していることを示しています。こうすることにより、10文字以下もしくは以上の場合、ユーザーが textfField をクリックしたりタブから離れることができないようにします。

次の例は UI 文書を示しています :

Code Block
 <textField text="input 10 characters only" onBeforeActiveLost="mco://eventMco.onBeforeActiveLost()"/>

...

次の例は MCO ハンドラメソッドを示しています:

Code Block

...

languagejava
linenumberstrue
public boolean onBeforeActiveLost(){
   ClientSession s = McoContainer.getSession();
   ClientEvent event = s.getEventHandler().getClientEvent();
   String id = event.getParameter("id");
   Element element = 
      s.getDocumentRegistry().getUiDocument().getElementById(id);
   String text = (String)element.getAttribute("text");
   if ( text.length() == 10)
     return true;
   else
     return false;
   }
 } 

 

Event Ordering

The Nexaweb Platform provides many different events, some fired in sequence such as onCommand and onMouseUp for a button.  The following provides general information about event sequences:

Note: Take care when handling multiple events that can fire in sequence. For example, have the first handler set a flag or redirect the second handler.

...

イベントの順序

Nexaweb Platform は多くの異なるイベントを提供します。中にはボタンの onCommand や onMouseUp のように順番に実行されるものもあります。次ではイベント発生順序に関する一般的な情報を提供しています :

メモ: 順番に発火する可能性がある、複数のイベントをハンドリングする際、気を付けて下さい。例えば最初のハンドラにフラグを設定する、または2番目のハンドラをリダイレクトするなど。

  • onBeforeActiveLost イベントはフォーカスを失う際に発生します。クライアントが onBeforeActiveLost イベントに false を戻す場合、コンポーネントはフォーカスを失わず、他のイベントは発生しません。
  • ユーザが <Enter> キーを押下する際、onCommand イベントが常に最初に実行されます。
  • 物理的イベントから直接発生するイベントに関しては、次の順番でイベントが発生します:
    1. onKeyDown (<Enter>以外のキーボードアクションの場合) または onMouseDown (マウスクリックの場合) イベントが最初に発火します。
    2. その後、フォーカスに変更がある際、テキストに変更のあるテキストコンポーネントがフォーカスを失った場合 onEdit イベントが先行します。
    3. 次に onActiveLost が発生し、onActiveGained が続きます。
    4. フォーカス変更後、onStateChange のような上位レベルの合成イベントが続きます。
    5. 次に、キーボードイベントに対し、onKeyCharが発生します。
    6. リリースでは、onKeyUp が キーボードに対し発生するか、マウスによる onMouseUp が発生します (ボタンのonCommandの後) 。