この章では、JSFのイベント処理について解説します。
まず、「イベント」とは、アプリケーションで行われる操作のことを指します。例えば「ボタンを押す」とか、「入力フィールドにデータを入力する」といった操作がイベントになります。
そして「イベント処理」とは、ある特定のイベントが起こったときに、何らかの処理を行うことです。
イベント処理は、大きく分けて2つの部分で処理が行われます。
まず、1つめは「イベント発生元」です。これは、ボタン・テキストフィールドなどイベントが起こる場所です。
2つめは「イベントリスナー」です。これは、発生したイベントを受け取り、イベントに対応する処理を行うところです。
JSFでは、2種類のイベント処理を行います。
1つめは、「Actionイベント」です。これは、ボタンやハイパーリンクが押されたときに発生するイベントです。
2つめは、「Value Changeイベント」です。これは、ボタンやハイパーリンクが押されたとき、対象となるUIコンポーネントが変化していたら発生するイベントです。
この章では、この2つのイベント処理について見てみましょう。
Actionイベントは、ボタンやハイパーリンクが押されたときに発生するイベントです。
例として、図9.1[Actionイベントの例]のような処理が可能になります。
「名前」を入力してボタンを押すと、2つの情報を出力します。1つめは入力された「名前」で、2つめは「どのボタンが押されたか」ということです。
では、イベント処理を行うJSPの例を見てみましょう。
<%@ page contentType="text/html; charset=Shift_JIS" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <html> <head> <link href="style.css" type="text/css" rel="stylesheet" /> <title>JSF: Action Eventのテスト</title> </head> <body> <h1>JSF: Action Eventのテスト</h1> <f:view> <h:form id="searchForm"> <p>名前を入力してください: <h:inputText id="word" value="#{ParameterBean.name}" /> </p> <p> <h:commandButton id="button1" value="Button1" actionListener="#{ParameterBean.assembleMessage}" /> <h:commandButton id="button2" value="Button2" actionListener="#{ParameterBean.assembleMessage}" /> </p> <p> <h:outputText id="message" value="#{ParameterBean.message}" /> </p> </h:form> </f:view> </body> </html>
このJSPはh:commandButtonが2つあります。このボタンが2つともイベント発生元になります。
h:commandButtonの部分を見てみましょう。
<h:commandButton id="button1" value="Button1" actionListener="#{ParameterBean.assembleMessage}" />
actionListener属性が、ここで新しく登場した属性です。
actionListener属性の値はMethod Binding式となっています。ParameterBeanのassembleMessageメソッドがイベントリスナーになるのです。
Managed Beanです。
import javax.faces.event.ActionEvent; public class ParameterBean { private String name = ""; private String message = "何も選択されていません"; public void setName(String name) { this.name = name; } public String getName() { return name; } public void setMessage(String message) { this.message = message; } public String getMessage() { return message; } public void assembleMessage(ActionEvent event) { String id = event.getComponent().getId(); StringBuffer sb = new StringBuffer(); sb.append(name); sb.append("さん、"); sb.append(id); sb.append("が押されました。"); message = new String(sb); } }
先に述べたように、assembleMessageメソッドがアクションリスナーになります。
アクションリスナーには、メソッドの型のルールがあります。1つめに、ActionEventオブジェクトを引数にとります。2つめに、返値はvoidです。
public void assembleMessage(ActionEvent event) { ...... }
assembleMessageメソッドの中に、次のような箇所があります。
String id = event.getComponent().getId();
この部分では、イベントが起こったUIコンポーネントのid属性の値を返します。
Action MethodとAction Eventはよく似ています。では、この2つはどのように使い分ければ良いのでしょうか?
単に画面遷移したいだけなら、Action Methodを利用した方がよいでしょう。outcomeを利用することで、簡潔に画面遷移を記述できます。
Actionイベントは、ActionEventオブジェクトを利用することで、イベント発生元のUIコンポーネントの情報を取得できます。こうした情報が必要なときには、Actionイベントを利用するのが良いでしょう。
Value Changeイベントは、ボタンやハイパーリンクが押されたとき、対象となるUIコンポーネントが変化していたら発生するイベントです。
例えば、図9.2[Value Change イベントの例]のような処理が可能になります。
"Go!"ボタンが押されたとき、ラジオボタンの選択内容が変化していたらメッセージを表示します。
図9.3[Value Change イベントの例]のように、"Go!"ボタンが押されても、ラジオボタンの選択内容が変化していなかったらメッセージは変化しません。
「野球」を選択してボタンを押すと、「野球」が選択された旨のメッセージが表示されます。その直後、「野球」が選択されたままでボタンを押しても、メッセージの内容は変化しません。Value Changeイベントの対象となるラジオボタンが変化しなければ、イベントは発生しないのです。
では、JSPの記述です。
<%@ page contentType="text/html; charset=Shift_JIS" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <html> <head> <link href="style.css" type="text/css" rel="stylesheet" /> <title>JSF: Value Change Eventのテスト</title> </head> <body> <h1>JSF: Value Change Eventのテスト</h1> <f:view> <h:form id="searchForm"> <p> 好きなスポーツをお選びください。 </p> <h:selectOneRadio value="#{ParameterBean.sports}" valueChangeListener="#{ParameterBean.assembleMessage}"> <f:selectItem itemValue="baseball" itemLabel="野球" /> <f:selectItem itemValue="soccer" itemLabel="サッカー" /> <f:selectItem itemValue="tennis" itemLabel="テニス" /> </h:selectOneRadio> <h:commandButton id="button" value="Go!" /> </p> <p> <h:outputText id="message" value="#{ParameterBean.message}" /> </p> </h:form> </f:view> </body> </html>
このJSPでは、ラジオボタンを表示しています。
h:selectOneRadioタグは、ラジオボタンを表すUIコンポーネントです。ラジオボタンは、1つだけ選択ができるボタンのグループです。
選択されたボタンの値はvalue属性で指定されたValue Bindingを使います。
<h:selectOneRadio value="#{ParameterBean.sports}" ...... </h:selectOneRadio>
ラジオボタンの個々の選択肢はf:selectItemタグで表します。f:selectItemタグは、1つの選択肢を表すUIコンポーネントです。
itemValue属性は、この選択肢が選ばれたときにh:selectOneRadio要素のvalue属性に入る値です。
itemLabel属性は、表示される文字列になります。
<f:selectItem itemValue="baseball" itemLabel="野球" /> <f:selectItem itemValue="soccer" itemLabel="サッカー" /> <f:selectItem itemValue="tennis" itemLabel="テニス" />
このJSPでは、ラジオボタンがイベント発生元になります。
valueChangeListener属性の値はMethod Binding式になっています。ParameterBeanのassembleMessageメソッドがイベントリスナーとなります。
<h:selectOneRadio value="#{ParameterBean.sports}" valueChangeListener="#{ParameterBean.assembleMessage}"> ...... </h:selectOneRadio>
Managed Beanです。
import java.util.Date; import java.text.DateFormat; import javax.faces.event.ValueChangeEvent; import javax.faces.context.FacesContext; import javax.faces.application.Application; import javax.faces.el.ValueBinding; public class ParameterBean { private String sports = ""; private String message = "何も選択されていません"; public void setSports(String sports) { this.sports = sports; } public String getSports() { return sports; } public void setMessage(String message) { this.message = message; } public String getMessage() { return message; } public void assembleMessage(ValueChangeEvent event) { String str = event.getNewValue().toString(); Date d = new Date(); DateFormat df = DateFormat.getDateTimeInstance(); StringBuffer sb = new StringBuffer(); sb.append(df.format(d)); sb.append("に"); if (str.equals("baseball")) { sb.append("野球"); } else if (str.equals("soccer")) { sb.append("サッカー"); } else if (str.equals("tennis")) { sb.append("テニス"); } sb.append("が選択されました。"); message = new String(sb); } }
assembleMessageメソッドがアクションリスナーになります。ActionEventと同様に、Value Changeイベントのアクションリスナーには、メソッドの型のルールがあります。1つめに、ValueChangeEventオブジェクトを引数にとります。2つめに、返値はvoidです。
public void assembleMessage(ValueChangeEvent event) { ...... }
assembleMessageメソッドの中に、次のような箇所があります。イベントが起こったUIコンポーネントの現在の値を返します。このプログラムでは、f:selectItemタグのitemValue属性で指定されているbaseball, soccer, tennisのいずれかの値になります。
String str = event.getNewValue().toString();