2007年12月24日月曜日

ZK: データバインディング

selectRainfallAvgメソッドを実行し作成したListをZKのListboxコンポーネントにデータバインドします。
まず<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>でデータバインダーを初期化します。
Seasarコンポーネントを生成後selectRainfallAvgメソッドを実行しrainfallAvgを作成します。
model="@{rainfallAvg}"でZKのListboxとJavaのListを関連付けるとロード時にデータバインダーによってJavaのListからZKのListModelに変換されます。
selectedItem="@{selected}"は選択された行に対応したビーンに関連付けられた変数selectedを準備します。選択された行を明細表示するのに変数selectedのプロパティが利用出来ます。
self="@{each=rainfall}"はListの各行に対応したビーンをrainfallと言う名前で関連付けます。

<?xml version="1.0" encoding="UTF-8"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<zk xmlns="http://www.zkoss.org/2005/zul" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.zkoss.org/2005/zul/zul.xsd ">
<window title="東京 年間降雨量デモ" width="500px" border="normal">
<zscript>
import org.seasar.framework.container.SingletonS2Container;
rainStatsService = SingletonS2Container.getComponent("rainStatsService");
rainfallAvg = rainStatsService.selectRainfallAvg();
</zscript>
<listbox model="@{rainfallAvg}" id="rainfallListbox" rows="5" selectedItem="@{selected}">
<listhead>
<listheader label="年度"/>
<listheader label="平均降雨量(mm)"/>
</listhead>
<listitem self="@{each=rainfall}">
<listcell label="@{rainfall.year}"/>
<listcell label="@{rainfall.average}"/>
</listitem>
</listbox>
<vbox>
<hbox>年度: <label value="@{selected.year}"/></hbox>
<hbox>平均降雨量:<label value="@{selected.average}"/></hbox>
</vbox>
</window>
</zk>


次のメソッドを実行するとデータベースからリロードすることができます。

void refreshRainfallListbox(){
List list = rainfallListbox.getModel();
list.clear();
list.addAll(rainStatsService.selectRainfallAvg());
}

2007年12月23日日曜日

Seasar: S2JDBC 外出しSQL

ZK + Seasar:JFreeChartで使った降雨量の年間平均をS2JDBCの外出しSQLで求めてみました。

  • 年と平均降雨量を格納するDTOを作成します。

    package zkseasar.dto;

    public class RainfallAvgDto {
    public Integer year;
    public Double average;
    }

  • RainStatsServiceに年間平均降雨量を取り出すメソッドを追加します。
    DTOのプロパティ名とSQLのカラム名を統一するだけでSQLを実行した結果がDTOへ自動的にマッピングされるようです。

    ...
    public List selectRainfallAvg(){
    return jdbcManager.selectBySql(RainfallAvgDto.class,
    " select year, avg(rainfall) as average" +
    " from rain_stats " +
    " group by year " +
    " order by year ")
    .getResultList();
    }
    ...


  • S2TestCaseを継承したクラスを作り動作確認します。
    EclipseのメニューからRun>Debug As>JUnit Testで実行できます。

    public class RainStatsServiceTest extends S2TestCase {
    private JdbcManager jdbcManager;

    protected void setUp() throws Exception {
    include("app.dicon");
    }

    public void testSelectRainfallAvg() throws Exception {
    RainStatsService rainStatsService =
    SingletonS2Container.getComponent("rainStatsService");

    List results =
    rainStatsService.selectRainfallAvg();
    for (RainfallAvgDto dto : results) {
    System.out.println(dto.year + ":"+ dto.average);
    }
    }
    }
  • 2007年12月19日水曜日

    ZK: ウィンドウをブラウザの中央に表示

    windowをブラウザの中央に表示したい時はvboxの中にwindowを配置する。

    <zk>
    <vbox height="100%" width="100%" pack="center" align="center">
    <window title="Login" border="normal"
    style="text-align: center;left-margin: 30%;right-margin: 30%; width:30%;">
    Login Window
    </window>
    </vbox>
    </zk>

    2007年12月2日日曜日

    ZK: iText

    Report with ZK : Using JasperReports As an Exampleを参考に動的にPDFファイルを作成するサンプルを作ってみました。
    PDF作成にはiTextライブラリを使います。まずこちらのサイトからjarファイルをダウンロードします。日本語を使うためにこちらのサイトからiTextAsian.jarをダウンロードします。
    次にダウンロードしたjarファイルをWEB-INF/libへインポートして準備完了です。

    <?xml version="1.0" encoding="UTF-8"?>
    <?page style="height:100%" ?>
    <zk xmlns="http://www.zkoss.org/2005/zul" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd ">
    <window width="100%" height="100%">
    <borderlayout height="100%">
    <north maxsize="24" size="24" border="0">
    <hbox>
    名前:<textbox id="name"/>
    <button label="PDF出力" onClick="doReport()"/>
    </hbox>
    </north>
    <center border="none" flex="true">
    <iframe id="report" />
    </center>
    </borderlayout>
    <zscript><![CDATA[
    import java.io.*;
    import com.lowagie.text.*;
    import com.lowagie.text.pdf.*;
    import org.zkoss.util.media.AMedia;
    import java.awt.Color;

    void doReport() {
    try {
    //iTextでは出力するPDF全体はDocumentクラスで表現される
    Document doc = new Document();
    //ゴシック体の日本語ベースフォント作成
    BaseFont bf_goth = BaseFont.createFont(
    "HeiseiKakuGo-W5", //ゴシック体
    "UniJIS-UCS2-H", //横書日本語Unicodeエンコーディング
    BaseFont.NOT_EMBEDDED);
    //明朝体の日本語ベースフォント作成
    BaseFont bf_min = BaseFont.createFont(
    "HeiseiMin-W3", //明朝体
    "UniJIS-UCS2-H", //横書日本語Unicodeエンコーディング
    BaseFont.NOT_EMBEDDED);

    //日本語フォント作成
    Font font_goth = new Font(bf_goth);
    Font font_min15 = new Font(bf_min, 15); //明朝体 15pt
    Font font_goth8red = new Font(bf_goth, 8); //ゴシック体8pt
    font_goth8red.setColor(new Color(255,0,0)); //文字色を赤に設定

    //出力用のStreamをインスタンス化し
    ByteArrayOutputStream byteout = new ByteArrayOutputStream();
    //PDFの出力先へ割り当てる。
    PdfWriter.getInstance(doc, byteout);

    doc.open();
    //本文を追加
    doc.add(new Paragraph(name.value + "さん、 " + "こんにちは!!" , font_goth));
    doc.add(new Paragraph(name.value + "さん、 " + "こんにちは!!" , font_min15));
    doc.add(new Paragraph(name.value + "さん、 " + "こんにちは!!" , font_goth8red));
    doc.close();

    //PDF出力から入力ストリームを作成し
    final InputStream mediais = new ByteArrayInputStream(byteout.toByteArray());
    //入力ストリームをiframeのコンテンツへ媒介するAMediaオブジェクトを生成
    final AMedia amedia =
    new AMedia("FirstReport.pdf", "pdf", "application/pdf", mediais);

    //iframeにコンテンツをセット
    report.setContent(amedia);
    }catch (IOException e) {
    e.printStackTrace();
    }catch (DocumentException e) {
    e.printStackTrace();
    }
    }
    ]]></zscript>
    </window>
    </zk>