...
- 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:
...
- NXML マクロ コマンド
- JSP ページ、サーブレット、静的ページなど、サーバーサイドのリソース
- MCO やシステム サービスへの呼び出しを含むクライアントサイドの Java コード
- イベントの概要
- マクロを使用したイベントの処理
- サーバーサイドのイベント処理
- クライアントサイドのイベント処理
- イベントの順序付け
- キーストローク、ボタンのクリック、コンポーネント上でのマウスのホバーリングなどの物理的イベント
- ドロップダウン リストや状態を変更するチェックボックスで行われる選択など、より高度な UI イベント
- マクロ (UI を定義する XML に含まれるクライアントサイドのスクリプト)
- サーバーサイドのドキュメント
- ユーザー定義のクライアント クラスまたは MCO のメソッド
- マクロを実行する
- イベント情報をエンコードして、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()
...
- として定義
...
Code Block |
---|
...
language | html/xml |
---|---|
linenumbers | true |
<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 ドキュメントを生成し、クライアントに返すプロセスを示します。
UI ドキュメントはハンドラを次のように指定します。
Code Block |
---|
<button onCommand="changeLabelText.jsp" text="Change mylabel text" />
<label id="mylabel" text="This is some text" /> |
...
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> |
...
...
...
サーバーサイドでクライアントイベントを処理する際にサーバーセッションまたはサーバーサイドのドキュメントにアクセスする必要がある場合は、次を呼び出すことができます。
Code Block |
---|
SessionManager smgr = ServiceManager.getSessionManager();
ServerSession nxsession = smgr.findByRequest(request); |
...
...
Document uiDom = nxsession.getDocumentRegistry().getUiDocument();
...
...
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
...
クライアントサイドのイベント処理
1. 簡単な要素へのアクセスと属性の変更
...
In this example, the UI document declares the MCO and specifies the handler:
...
language | html/xml |
---|---|
linenumbers | true |
...
この例では、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:
...
language | java |
---|---|
linenumbers | true |
...
このハンドラは、ユーザーによって作成された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()
...
...
次に、この 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:
...
language | java |
---|---|
linenumbers | true |
...
次に、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 |
---|
...
language | java |
---|---|
linenumbers | true |
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 イベントが常に最初に実行されます。
- 物理的イベントから直接発生するイベントに関しては、次の順番でイベントが発生します:
- onKeyDown (<Enter>以外のキーボードアクションの場合) または onMouseDown (マウスクリックの場合) イベントが最初に発火します。
- その後、フォーカスに変更がある際、テキストに変更のあるテキストコンポーネントがフォーカスを失った場合 onEdit イベントが先行します。
- 次に onActiveLost が発生し、onActiveGained が続きます。
- フォーカス変更後、onStateChange のような上位レベルの合成イベントが続きます。
- 次に、キーボードイベントに対し、onKeyCharが発生します。
- リリースでは、onKeyUp が キーボードに対し発生するか、マウスによる onMouseUp が発生します (ボタンのonCommandの後) 。