FormコンポーネントはFormタグの生成を担当します。また、Submitコンポーネントは
サブミットボタンの生成を担当します。TextFieldコンポーネントは文字通りテキストフィールド
の生成を担当します。
今回は、フォームを使用してよくある足し算フォームを作成します。
Tapestryでのリクエスト処理は、どちらかというとGUIでのイベント処理に
似ています。コンポーネント志向のフレームワークといわれる所以ですね。
各サブミットボタンやフォームは自身が定義されているページ仕様ファイルにて
リスナーを登録されます。この登録されたリスナーがフォームのサブミット時や
ボタンのアクション時に呼ばれます。つまり、ページコンポーネントクラスの方で
好きにコールバックメソッドを作成して、後はページ仕様ファイルにてコールバック
されるよう登録すればよいのです。
今回のサンプルでは、
- doForm001Submit
- doCalc
- doClear
という3つのコールバックメソッドがページコンポーネントクラス側に
定義されています。
Tapestryのイベント処理は、Swingのイベント処理に似ていて、
わかりやすいです。
[ページ仕様ファイル]
<page-specification class="gsf.samples.tapestry.Home"> <!-- Formコンポーネント HTMLのformタグの生成を担当する。 リクエストの値を使用してページを表示したりする場合は、必須. Tapestryでは、フォームコンポーネントに対してSubmit時に 起動するコールバックメソッドを指定することができる("listener"属性) この属性にページコンポーネントで用意したメソッドを指定すると フォームSubmit時にコールされるようになる。 また、Submit時だけでなく、他のイベントの際にも(リフレッシュ時など) コールバックを指定できるようになっている。(Tapestryのドキュメントを参照の事) --> <component id="myForm001" type="Form"> <!-- フォームで使用するリクエスト送信方法 (METHOD) デフォルトは、postとなっている。 --> <binding name="method">literal:post</binding> <!-- フォームをサブミットした際に、アクティブなセッション情報を 取得するかどうか? デフォルトは、true(取得する) --> <binding name="stateful">ognl:true</binding> <!-- フォームがサブミットされた際にコールされる コールバックメソッドを指定. ognlの指定の方法は、 ognl:listeners.コールバックメソッド名 なお、コールバックメソッドは通常、戻り値が いらない場合は public void xxxxCallBackMethod(org.apache.tapestry.IRequestCycle cycle){ } という形式で作成する。 --> <binding name="listener">ognl:listeners.doForm001Submit</binding> </component> <!-- TextFieldコンポーネント テキストフィールドの生成を担当する. --> <component id="text001WithinForm001" type="TextField"> <!-- 画面に表示する値を指定. --> <binding name="value">ognl:calcLeftValue</binding> </component> <component id="text002WithinForm001" type="TextField"> <binding name="value">ognl:calcRightValue</binding> </component> <component id="answerWithinForm001" type="Insert"> <binding name="value">ognl:calcAnswerValue</binding> </component> <!-- Submitコンポーネント サブミットボタンの生成を担当する. このコンポーネントは、必ずFormコンポーネントの内部に 指定しなければならない。 Formコンポーネントと同様にこのコンポーネントも ボタン押下イベント時に指定したコールバックメソッドを 指定できるようになっている。 また、上記で指定したボタンのコールバックメソッドは FormコンポーネントのSubmit時にコールされるコールバックメソッド よりも先に起動される。 --> <component id="calcButton" type="Submit"> <!-- ボタンが押下された際にコールされるコールバックメソッド を指定. (ここで指定したコールバックメソッドはフォームのsubmit時に コールされるコールバックメソッドよりも先に走る) ognlの指定の方法は、 ognl:listeners.コールバックメソッド名 なお、コールバックメソッドは通常、戻り値が いらない場合は public void xxxxCallBackMethod(org.apache.tapestry.IRequestCycle cycle){ } という形式で作成する。 --> <binding name="action">ognl:listeners.doCalc</binding> <!-- ひとつのForm内に複数のSubmitコンポーネントが存在する場合、 どのボタンが押下されたのかを判別するために、各ボタンに 紐づくタグ名を保持するプロパティを指定する。 通常、タグ名を保持するプロパティの名前は、submitTagと するのが慣習の模様。 --> <binding name="selected">ognl:submitTag</binding> <!-- 実際にボタンが押下された際に上記のselected属性で 指定されたプロパティにセットされる値。 通常、タグ名は文字列で指定するのが慣習の模様。 --> <binding name="tag">literal:calc</binding> </component> <component id="clearButton" type="Submit"> <binding name="action">ognl:listeners.doClear</binding> <binding name="selected">ognl:submitTag</binding> <binding name="tag">literal:clear</binding> </component> <component id="currentStatus" type="Insert"> <binding name="value">ognl:currentStatus</binding> </component> </page-specification>
[テンプレートファイル]
<html jwcid="@Shell"> <body jwcid="@Body"> <!-- フォームを使用したコンポーネント連携 (Formコンポーネント, Submitコンポーネントを使用) --> <br/> <hr/> <div id="form_submit_001" align="center"> <form jwcid="myForm001" name="form1" method="post" action=""> <b> Formコンポーネント, Submitコンポーネントを使用して、リクエストを処理する. <br/> <br/> <font color="red"> ここでは、Formコンポーネントでのコールバックと、Submitコンポーネントの<br/> コールバックの動作を確認するために、以下の動作としている。<br/> <br/> <br/> <table> <tr> <td> <li>Submitコンポーネントのコールバックにて入力された2つの値を足す.</li> </td> </tr> <tr> <td> <li>Formコンポーネントのコールバックにて上で算出された結果に1000を足す.</li> </td> </tr> </table> </font> </b> <br/> <br/> <table border="1"> <tr> <th colspan="4" align="center">計算</th> </tr> <tr> <td> <input jwcid="text001WithinForm001" type="text" name="textfield1" value="" size="4" maxlength="3"/> + <input jwcid="text002WithinForm001" type="text" name="textfield2" value="" size="4" maxlength="3"/> + 1000 = </td> <td> <span jwcid="answerWithinForm001">0</span> </td> <td> <input jwcid="calcButton" type="submit" name="calcButton" value="計算"/> </td> <td> <input jwcid="clearButton" type="submit" name="clearButton" value="値をクリア"/> </td> </tr> </table> <br/> 現在の状況: <b><font color="red"><span jwcid="currentStatus">状況・・・</span></font></b> </form> </div> <br/> <hr/> </body> </html>
[ページコンポーネントクラス]
// vim:set ts=4 sw=4 et ws ft=java fenc=cp932 ff=dos: package gsf.samples.tapestry; import java.util.*; import java.text.*; import org.apache.tapestry.*; import org.apache.tapestry.html.*; /** * Homeページ用のページコンポーネントクラス.<br/> * <br/> * ページコンポーネントクラスは、org.apache.tapestry.html.BasePage<br/> * クラスを継承して、作成する。tapestryには、バイトコードを実行時に<br/> * 拡張するフレームワークが存在するので、ページコンポーネントクラスは<br/> * abstractで宣言してもよい。その際は、セッターゲッターをabstractで<br/> * 宣言すると実行時にtapestry側で実装を拡張してくれる。<br/> * * <pre> * (クラス宣言例) * public abstract class Home extends BasePage{ * } * * (メソッド宣言例) * public abstract String getName(); * public abstract void setName(String name); * </pre> * * <br/> * また、コンポーネントのリファレンスに * 型がIActionListnerとなっている場合は、 * ページコンポーネントクラスで任意のメソッドを * 定義し、そのコンポーネントの属性に設定すれば * そのメソッドが呼ばれる。 * (Tapestryは、実行時にlistner属性に指定されている * メソッドをリフレクションを使用してページクラスもしくは * コンポーネントクラスより探し出し、IActionListenerインターフェース * を実装したオブジェクトを作成してくれる。) * <br/> * <pre> * (コールバックメソッド宣言例) * [ページ仕様ファイル] * <component id="myForm" type="Form"> * <binding name="listener">ognl:listeners.callBackMethod</binding> * </component> * * [ページクラス(javaファイル)] * public void callBackMethod(org.apache.tapestry.IRequestCycle cycle){ * // * // process........ * // * } * </pre> */ public class Home extends BasePage{ private Date currentDate; private Format dateFormat; private String largeStrings; private Integer calcLeftValue; private Integer calcRightValue; private Integer calcAnswerValue; private String currentStatus; private String submitTag; public Home(){ this.currentDate = new Date(); this.dateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss"); this.largeStrings = "改行付きの文字列<>&''[0]\n改行付きの文字列<>&''[1]\n改行付きの文字列<>&''[2]\n"; this.calcLeftValue = 0; this.calcRightValue = 0; this.calcAnswerValue = 0; this.currentStatus = ""; this.submitTag = null; } /** * jwcidが"myForm001"のFormコンポーネントがSubmit<br/> * された際に呼ばれるコールバックメソッド.<br/> * * @param cycle tapestryリクエストサイクルオブジェクト * */ public void doForm001Submit(IRequestCycle cycle){ // // ボタンが押下された際に紐づいているタグ名が // submitTagにセットされている。 // その値を用いて、どのボタンが押下されたのかを // 判断. // String selectedTag = (this.getSubmitTag() != null) ? this.getSubmitTag().toLowerCase() : ""; if("calc".equals(selectedTag)){ // // ボタン押下のコールバックの際に計算された // 値に1000を足す。 // this.setCalcAnswerValue(this.getCalcAnswerValue() + 1000); // ステータスを更新 this.setCurrentStatus("計算を行いました。"); }else if("clear".equals(selectedTag)){ // ステータスを更新 this.setCurrentStatus("値をクリアしました。"); } } /** * jwcidが"calcButton"のSubmitコンポーネントが押下された際に<br/> * 呼ばれるコールバックメソッド.<br/> * * @param cycle tapestryリクエストサイクルオブジェクト * */ public void doCalc(IRequestCycle cycle){ // // フィールドの値を足し、答えをセット // Integer answer = this.getCalcLeftValue() + this.getCalcRightValue(); this.setCalcAnswerValue(answer); } /** * jwcidが"clearButton"のSubmitコンポーネントが押下された<br/> * 際にコールされるコールバックメソッド.<br/> * * @param cycle tapestryリクエストサイクルオブジェクト * */ public void doClear(IRequestCycle cycle){ // // フィールドの値をクリア // this.setCalcLeftValue(0); this.setCalcRightValue(0); this.setCalcAnswerValue(0); } /** * Get currentDate. * * @return currentDate as Date. */ public Date getCurrentDate(){ return this.currentDate; } /** * Get dateFormat. * * @return dateFormat as Format. */ public Format getDateFormat(){ return this.dateFormat; } /** * Get largeStrings. * * @return largeStrings as String. */ public String getLargeStrings(){ return this.largeStrings; } /** * Get calcLeftValue. * * @return calcLeftValue as Integer. */ public Integer getCalcLeftValue(){ return this.calcLeftValue; } /** * Set calcLeftValue. * * @param calcLeftValue the value to set. */ public void setCalcLeftValue(Integer calcLeftValue){ this.calcLeftValue = calcLeftValue; } /** * Get calcRightValue. * * @return calcRightValue as Integer. */ public Integer getCalcRightValue(){ return this.calcRightValue; } /** * Set calcRightValue. * * @param calcRightValue the value to set. */ public void setCalcRightValue(Integer calcRightValue){ this.calcRightValue = calcRightValue; } /** * Get calcAnswerValue. * * @return calcAnswerValue as Integer. */ public Integer getCalcAnswerValue(){ return this.calcAnswerValue; } /** * Set calcAnswerValue. * * @param calcAnswerValue the value to set. */ public void setCalcAnswerValue(Integer calcAnswerValue){ this.calcAnswerValue = calcAnswerValue; } /** * Get submitTag. * * @return submitTag as String. */ public String getSubmitTag(){ return this.submitTag; } /** * Set submitTag. * * @param submitTag the value to set. */ public void setSubmitTag(String submitTag){ this.submitTag = submitTag; } /** * Get currentStatus. * * @return currentStatus as String. */ public String getCurrentStatus(){ return this.currentStatus; } /** * Set currentStatus. * * @param currentStatus the value to set. */ public void setCurrentStatus(String currentStatus){ this.currentStatus = currentStatus; } }