MyFaces 1.1.0(tomahawk)をS2JSFで使う (newspaperTable編)
たまには役に立つことでも書こうということで、MyFaces 1.1.0のtomahawkをS2JSFで使う方法を書いていきたいと思います。
ここでいうtomahawkとは、北米インディアンの投げても使える戦斧のこと……ではなく、米軍の長距離巡航ミサイルのこと……でもなく、JSFの標準仕様にはない、MyFaces独自の便利な拡張UIコンポーネント群のことです。何はともあれ物騒な名前ですね。
このtomahawkを利用することにより、簡単に、よりリッチなUIを作成することができます。利用しない手はありません。
では、すでにS2JSFが使える環境にあるという前提でお話を進めます。ちなみに私は新規作成する場合はS2JSFBlankを愛用させていただいています。
まずは、MyFacesをhttp://myfaces.apache.org/からダウンロードしてきましょう。
そして、WEB-INF/libにMyFaces関連のライブラリを入れます。ここで注意。これを書いている時点での話ですが、myfaces-all.jarは罠です! なんとなく、myfaces-api.jarとmyfaces-impl.jarとtomahawk.jarの合計サイズとmyfaces-all.jarが同じっぽいという理由でmyfaces-all.jarを使うとハマります(っていうかハマった)。myfaces-api.jarとmyfaces-impl.jarとtomahawk.jarを使いましょう。そして、S2JSFに入っているmyfaces.jarは消してしまいましょう。……っと、MyFaces 1.1.0にしてこれまでのS2JSFアプリケーションが完全に動作するかどうかは私は知りませんので、このあたりは自己責任でお願いしますね。
次に、タグライブラリをjsf.diconに登録します。
<initMethod name="addTaglibUri"> <arg>"s"</arg> <arg>"http://www.seasar.org/jsf"</arg> </initMethod>
↑これの下あたりに↓これを追加します。
<initMethod name="addTaglibUri"> <arg>"t"</arg> <arg>"http://myfaces.apache.org/tomahawk"</arg> </initMethod> <initMethod name="addTaglibUri"> <arg>"wap"</arg> <arg>"http://myfaces.apache.org/wap"</arg> </initMethod>
以前は、MyFacesの拡張UIのプレフィックスには「x」が使われてましたが、tomahawkという名前がついたので「t」になったようですね。
さてさて。それでは、今回は、newspaperTableコンポーネントを使ってみましょう。何故今回これを選んだかといいますと、こんな経験はないですか? リストを表示するんだけど、横に3つずつならべて表示したい。なんてこと。こういうとき困るんですよね〜。バッキングビーンで二次元配列に変換してforEachでまわそうか、そうするとビジネスロジックにビューの事情が入り込んで美しくない!ってなるし、ビューのほうでこねこねするのもあまりにバカらしい。そんなときに役にたつのがこのnewspaperTableコンポーネントなのです。
とりあえず、リストの要素として以下のようなものがあったとします。
package newspaper; public class NewspaperDto { private String name; private String value; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
初期化アクションは↓こんな感じです。東北6県の県庁所在地のリストです(^^;
package newspaper; import java.util.ArrayList; import java.util.List; public class NewspaperAction { private List dtoList; public String initialize() { ArrayList al = new ArrayList(); NewspaperDto nd; nd = new NewspaperDto(); nd.setName("青森県"); nd.setValue("青森市"); al.add(nd); nd = new NewspaperDto(); nd.setName("秋田県"); nd.setValue("秋田市"); al.add(nd); nd = new NewspaperDto(); nd.setName("岩手県"); nd.setValue("盛岡市"); al.add(nd); nd = new NewspaperDto(); nd.setName("宮城県"); nd.setValue("仙台市"); al.add(nd); nd = new NewspaperDto(); nd.setName("山形県"); nd.setValue("山形市"); al.add(nd); nd = new NewspaperDto(); nd.setName("福島県"); nd.setValue("福島市"); al.add(nd); dtoList = al; return null; } public List getDtoList() { return dtoList; } }
初期化アクションをdiconに登録します。サンプルなので、app.diconに直接書いちゃいますね。
<?xml version="1.0" encoding="Shift_JIS"?> <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN" "http://www.seasar.org/dtd/components21.dtd"> <components> <include path="jsf.dicon"/> <component name="newspaperAction" class="newspaper.NewspaperAction" /> </components>
それでは注目のHTMLテンプレートです。
<html xmlns:m="http://www.seasar.org/maya" m:action="#{newspaperAction.initialize}"> <head> <meta http-equiv="Content-Type" content="text/html; charset=Windows-31J"> <meta http-equiv="Content-Style-Type" content="text/css"> <title>newspaper</title> </head> <body> <div m:inject="t:newspaperTable" m:newspaperColumns="3" m:value="#{dtoList}" m:var="e"> この部分はtomahawkを使うためプレビューできません。 <div m:inject="h:column"> <span m:value="#{e.name}">県名</span> </div> <div m:inject="h:column"> <span m:value="#{e.value}">県庁所在地</span> </div> </div> </body> </html>
私は、HTMLテンプレートをブラウザだけで見たときの挙動も大切にしたいので、「なんじゃこりゃ?」と思われないように「プレビューできません」と書いておいてます。もちろんこの注意書きは、S2JSFを通せば見えません。
どうでしょうか? S2JSFのforEachコンポーネントに似ているかと思います。m:newspaperColumnsで列数を指定するのですが、うれしいのはh:columnの子タグをひとまとめにして「1つ」と扱っているところです。ちなみに実行結果は以下のようになります。
それでは次回にもう少し詳しい使い方をやりたいと思います。