<textbox style="text-transform:uppercase" id="idx" />
2008年12月4日木曜日
ZK: 小文字の入力時に自動で大文字に変換するtextbox
小文字の入力が入力と同時に大文字に変換される。
2008年12月3日水曜日
ZK: Textboxのテキストを選択状態にする
<window title="Button window" border="normal">
<vbox>
<button label="Left" width="125px">
<attribute name="onClick">
Messagebox.show("Textboxのテキストを選択状態にします");
txt.focus();
txt.setSelectionRange(0, txt.getText().length());
</attribute>
</button>
<textbox id="txt" value="123456"/>
</vbox>
</window>
ZK: Window幅のリサイズに自動で追随するリストボックス
listboxのfixedLayoutプロパティをtrueにするとwindowのリサイズに合わせ列幅を自動調整する。
<window title="Window幅のリサイズに自動で追随するリストボックス"
width="300px" height="100px" id="win" sizable="true" mode="modal">
<button label="FILL" onClick="fillList()"/>
<zscript>
public void fillList(){
Listitem item = new Listitem();
new Listcell("Cell Data 1").setParent(item);
new Listcell("Cell Data 2").setParent(item);
new Listcell("Cell Data 3").setParent(item);
item.setParent(lbx);
}
</zscript>
<listbox width="100%" id="lbx" fixedLayout="true">
<listhead sizable="true">
<listheader label="Column 1" />
<listheader label="Column 2" />
<listheader label="Column 3" />
</listhead>
</listbox>
</window>
2008年12月2日火曜日
ZK: タイムアウト時間を設定する
WEB-INF/zk.xmlでタイムアウト時間を設定することができる。
<zk>
<desktop-config>
<desktop-timeout>3600</desktop-timeout> <!--秒単位、マイナスはタイムアウト無し。 -->
</desktop-config>
</zk>
ZK: no empty制約付きのテキストボックスをクリアする
no empty制約付きのテキストボックスをクリアするときは
textbox.setRawValue("")を使用すると制約を回避しテキストボックスをクリアできる。
textbox.setRawValue("")を使用すると制約を回避しテキストボックスをクリアできる。
<window title="no empty制約付きのテキストボックスをクリアする"
width="300px" height="200px" border="normal">
<zscript><![CDATA[
public void save(){
alert("テキストボックスの値 "+tb1.value+" を保存しました。");
tb1.setValue(""); //no empty制約にひっかかりクリアできない
//tb1.setRawValue(""); //制約を回避しクリアできる。
}
]]></zscript>
<vbox>
<textbox id="tb1" constraint="no empty" ></textbox>
<button label="保存" onClick="save()" />
</vbox>
</window>
2008年12月1日月曜日
ZK: Windowをスクリーントップを越えて移動させない
<window id="win" border="normal" title="隠れません!!"
mode="overlapped" width="350px" onMove="resetTop()">
<zscript><![CDATA[
void resetTop(){
String top = win.getTop();
if (top != null){
float winTop = Float.parseFloat((top.substring(0,top.lastIndexOf("px"))));
if (winTop < 0.0){
win.setTop(0 + "px");
}
}
}
]]></zscript>
<label value="ウィンドウはスクリーントップを越えて上には移動しません!!"/>
</window>
ZK: 親ウィンドウの中だけ移動するパネル
パネルを親ウィンドウの中だけしか移動できないようにするには親ウィンドウでcontentStyle="position:relative;"を指定する。
<window width="500px" height="200px" title="親ウィンドウ
contentStyle="position:relative;"" border="normal"
contentStyle="position:relative;" >
<panel id="panel" height="100px" width="300px" title="親ウィンドウの中だけ移動するパネル"
maximizable="true" border="normal" collapsible="true" floatable="true" movable="true">
<panelchildren>
最大化しても親ウィンドウの中に収まります。
</panelchildren>
</panel>
</window>
ZK: リストボックスの行の背景色をカスタマイズする
<style>
/* 偶数行の背景色 */
tr.z-list-item, tr.z-row td.z-row-inner, tr.z-row td.z-group-inner,
tr.z-row td.z-group-foot-inner, tr.z-row {
background: #EEEEEE none repeat scroll 0 0;
}
/* 奇数行の背景色 */
tr.odd td.gc, tr.odd, tr.z-listbox-odd, tr.z-grid-odd td.z-row-inner,
tr.z-grid-odd {
background: #FFFFFF none repeat scroll 0 0;
}
/* 選択されていない行の上をマウスが通過する時の背景色 */
tr.overd, td.overd, tr.z-list-item-over {
background: #D3DBFC none repeat scroll 0 0;
}
/* 選択された行の背景色 */
tr.seld, td.seld, tr.z-list-item-seld {
background: #B8BFDC none repeat scroll 0 0;
}
/* 選択された行の上をマウスが通過する時の背景色 */
tr.overseld, td.overseld, tr.z-list-item-over-seld {
background: #D3DBFC none repeat scroll 0 0;
}
</style>
ZK: リクエスト・パラメータを取得する
ZK: Borderlayout 折り畳みアイコン表示
Boderlayoutの子コンポーネントはcollapsible="true"で折り畳めるようになるが、折り畳みアイコンを表示させるにはtitleを設定しタイトルバーを表示する必要がある。
<borderlayout height="500px">
<north title="「折り畳みアイコン」を表示するには何かタイトルが必要 →"
size="20%" splittable="true" collapsible="true"/>
<east size="20%" splittable="true" collapsible="true"/>
<center border="normal"/>
<west title="→" size="20%" splittable="true" collapsible="true"/>
<south size="30%" border="normal" splittable="true" collapsible="true"/>
</borderlayout>
2008年6月21日土曜日
ZK: Pagingコンポーネントでライブデータ表示
Smalltaksの記事Use Load-On-Demand to Handle Huge Dataを試してみました。
リストボックスに一度に大量なデータを表示するとWEBアプリにもサーバにも大きな負担がかかります。
Pagingコンポーネントを明示的に使いオンデマンドでページ単位にクエリーを実行し、取得したライブデータでリストボックスの表示を効果的に処理する方法が紹介されていました。
Windowを継承したクラスでインターフェースAfterComposeを実装します。
afterComposeメソッドでは
データのトータル行数をセット
最初のページにデータを表示
pagingコンポーネントに onPaging イベントリスナを登録
を行います。
大量なデータでも paging コンポーネントを用いライブデータで処理を行うとアプリの動作は非常に軽快ですね。
リストボックスに一度に大量なデータを表示するとWEBアプリにもサーバにも大きな負担がかかります。
Pagingコンポーネントを明示的に使いオンデマンドでページ単位にクエリーを実行し、取得したライブデータでリストボックスの表示を効果的に処理する方法が紹介されていました。
<window
title="Listbox with Paging Performance using ZK version: ${desktop.webApp.version}"
border="normal" use="sample.ui.EmployeeUI"
xmlns:zk="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">
<zk:toolbarbutton href="/" label="Back" />
<zk:listbox id="listEmployee" width="350px" checkmark="true">
<zk:listhead sizable="true">
<zk:listheader label="ID" sort="auto" />
<zk:listheader label="Full Name" sort="auto" />
<zk:listheader label="User Name" sort="auto" />
</zk:listhead>
</zk:listbox>
<!-- 明示的にpagingコンポーネントを使用する。 -->
<zk:paging id="pageEmployee" pageSize="30" />
</window>
Windowを継承したクラスでインターフェースAfterComposeを実装します。
afterComposeメソッドでは
を行います。
public class EmployeeUI extends SimpleWindow implements AfterCompose {
private final String LISTBOX_ID= "listEmployee"; //zulファイルの listbox コンポーネントの id
private final String PAGING_ID = "pageEmployee"; //zulファイルの paging コンポーネントのid
private JdbcManager jdbcManager; //Seasar変数
public EmployeeUI(){
DelegatingVariableResolver variableResolver = new DelegatingVariableResolver();
jdbcManager = (JdbcManager)variableResolver.resolveVariable("jdbcManager");
}
/**
* AfterComposeインターフェースのafterComposeメソッドはコンポーネント作成段階で処理される。
* コンポーネントを作成した直後に初期化できパフォーマンスの改善に役立つ。
*
*/
public void afterCompose() {
Paging page = getPaging(PAGING_ID);
//データのトータル行数を取得
page.setTotalSize((int)jdbcManager.from(Employee.class).getCount());
final int PAGE_SIZE = page.getPageSize();
// Listboxに最初のページを表示 オフセット--0 行数---PAGE_SIZE
redraw(0, PAGE_SIZE);
// onPagingイベントリスナの登録 決まり文句
page.addEventListener("onPaging", new EventListener() {
public void onEvent(Event event) {
PagingEvent pageEvent = (PagingEvent) event;
int pageNo = pageEvent.getActivePage();
int offset = pageNo * PAGE_SIZE;
// クリックされたページ番号でライブデータを取得し再表示
redraw(offset, PAGE_SIZE);
}
});
}
/**
* afterCompose及びonPagingイベントリスナから呼び出されListboxを描画する。
* コールされる度にクエリを実行しデータベースからライブデータを取得する。
*
* @param firstResult オフセット
* @param maxResults 行数
*/
private void redraw(int firstResult, int maxResults) {
Listbox listBox = getListbox(LISTBOX_ID);
listBox.getItems().clear();
// データ取得
List<Employee> emps = jdbcManager.from(Employee.class)
.orderBy("id") // 問い合わせ結果をページングするにはorder by が必要
.offset(firstResult)
.limit(maxResults)
.getResultList();
// 表示
for (Employee employee : emps) {
Listitem li = new Listitem();
li.setValue(employee);
li.appendChild(new Listcell("" + employee.id));
li.appendChild(new Listcell(employee.fullname));
li.appendChild(new Listcell(employee.username));
listBox.appendChild(li);
}
}
}
大量なデータでも paging コンポーネントを用いライブデータで処理を行うとアプリの動作は非常に軽快ですね。
2008年6月1日日曜日
ZK: Spreadsheet
以前から気になっていたZK Spreadsheetをいじってみました。ZK SpreadsheetではあらかじめExcelで作成しておいた表のテンプレートを読み込むことでZKのコンポーネントとして操作可能になるようです。つまり使い慣れたエクセルファイルがそのままZKのコンポーネントになるんですね。
Integrate ZK Spreadsheet with Springを元ネタにしてZK SpreadsheetとSeasarの統合を試して見ました。
まずはZssSpring.warをダウンロードし動作確認。
次にデモと同じ表示をさせるようにテーブルを作成。
Bean作成
キャメルケースでテーブルを作るとBeanの作成時にテーブル名と列名を一々指定しなければ
ならなかった(^^;;
つづいてzulファイルを編集。
スプレッドシートデモのWEB-INF/libより次のファイルをプロジェクトWEB-INF/libへインポート
プロジェクトのWEBルートにBalanceSheet.xlsとNewSheet.xlsを配置して実行

ZKコンポーネントとは言えExcelシートにビーンの値が表示され不思議な感じです、でもとても使い勝手がよさそうなコンポーネントです。
動作環境
Integrate ZK Spreadsheet with Springを元ネタにしてZK SpreadsheetとSeasarの統合を試して見ました。
まずはZssSpring.warをダウンロードし動作確認。
次にデモと同じ表示をさせるようにテーブルを作成。
create table FinancialData (
fyear integer,
fquarter integer,
item char(10),
liquidAssets decimal(10, 0),
fundInvestment decimal(10, 0),
fixedAssets decimal(10, 0),
intangibleAsset decimal(10, 0),
otherAssets decimal(10, 0),
currentLiabilities decimal(10, 0),
longTermLiabilities decimal(10, 0),
otherLiabilities decimal(10, 0),
capitalStock decimal(10, 0),
capitalSurplus decimal(10, 0),
retainedEarnings decimal(10, 0),
otherEquity decimal(10, 0),
treasuryStock decimal(10, 0)
);
insert into FinancialData(
fyear,
fquarter,
item,
liquidAssets,
fundInvestment,
fixedAssets,
intangibleAsset,
otherAssets,
currentLiabilities,
longTermLiabilities,
otherLiabilities,
capitalStock,
capitalSurplus,
retainedEarnings,
otherEquity,
treasuryStock
)values(
2007,
1,
'Quarter',
146504221,
23181709,
7168392,
221426,
2270018,
102515784,
3000,
456175,
33630080,
7127901,
34420905,
1826731,
-634810
);
...
Bean作成
キャメルケースでテーブルを作るとBeanの作成時にテーブル名と列名を一々指定しなければ
ならなかった(^^;;
package churazk.entity;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name="FINANCIALDATA")
public class FinancialData {
@Column(name="fYear")
public Integer fYear;
@Column(name="fQuarter")
public Integer fQuarter;
@Column(name="item")
public String item;
@Column(name="liquidAssets")
public BigDecimal liquidAssets;
@Column(name="fundInvestment")
public BigDecimal fundInvestment;
@Column(name="fixedAssets")
public BigDecimal fixedAssets;
@Column(name="intangibleAsset")
public BigDecimal intangibleAsset;
@Column(name="otherAssets")
public BigDecimal otherAssets;
@Column(name="currentLiabilities")
public BigDecimal currentLiabilities;
@Column(name="longTermLiabilities")
public BigDecimal longTermLiabilities;
@Column(name="otherLiabilities")
public BigDecimal otherLiabilities;
@Column(name="capitalStock")
public BigDecimal capitalStock;
@Column(name="capitalSurplus")
public BigDecimal capitalSurplus;
@Column(name="retainedEarnings")
public BigDecimal retainedEarnings;
@Column(name="otherEquity")
public BigDecimal otherEquity;
@Column(name="treasuryStock")
public BigDecimal treasuryStock;
}
つづいてzulファイルを編集。
<?xml version="1.0" encoding="UTF-8"?>
<?variable-resolver class="org.zkoss.zkplus.seasar.DelegatingVariableResolver"?>
<window>
Quarter:
<listbox id="quarter" mold="select" rows="1" onSelect="refreshQuarter()">
<listitem value="0" label="Select"/>
<listitem value="1" label="Quarter 1"/>
<listitem value="2" label="Quarter 2"/>
<listitem value="3" label="Quarter 3"/>
<listitem value="4" label="Quarter 4"/>
</listbox>
Style:
<listbox id="style" mold="select" rows="1" onSelect="changeStyle()">
<listitem label="Style 1" value="/BalanceSheet.xls"/>
<listitem label="Style 2" value="/NewSheet.xls"/>
</listbox>
<zscript>
import churazk.entity.FinancialData;
import org.seasar.extension.jdbc.where.SimpleWhere;
FinancialData reloadQuarter(int quarter){
FinancialData bean = jdbcManager.from(FinancialData.class)
.where(new SimpleWhere()
.eq("fYear", 2007)
.eq("fQuarter", quarter)
)
.getSingleResult();
return bean;
}
void refreshQuarter() {
Listitem listitem = quarter.getSelectedItem();
int quarter = Integer.parseInt(listitem.value);
//Call the method to reload data
dataBean = reloadQuarter(quarter);
//Call the method to refresh values of cells
balance.book.notifyChange(new String[]{"dataBean"});
}
void changeStyle() { //Change the URL of spreadsheet
balance.url = style.getSelectedItem().value;
}
dataBean = reloadQuarter(0);
</zscript>
<spreadsheet id="balance" url="/BalanceSheet.xls" maxrow="40" maxcolumn="20" height="600px" width="1300px"/>
</window>
スプレッドシートデモのWEB-INF/libより次のファイルをプロジェクトWEB-INF/libへインポート
commons-math-1.2.jar
jxl.jar
zss.jar
zssex.jar
zssjxl.jar
プロジェクトのWEBルートにBalanceSheet.xlsとNewSheet.xlsを配置して実行

ZKコンポーネントとは言えExcelシートにビーンの値が表示され不思議な感じです、でもとても使い勝手がよさそうなコンポーネントです。
動作環境
OS: Ubuntu 8.04 JDK: 1.6.0_04 Tomcat: apache-tomcat-6.0.16 Eclipse: Europa wtp-all-in-one-sdk ZK: zk-3.0.5 Seasar: DoltengプラグインよりChuraプロジェクト(Teeda+S2Dao)として S2JDBC関連: sa-struts-tutorial-1.0.2-rc4.zipより
geronimo-jpa_3.0_spec-1.0.jar
geronimo-ejb_3.0_spec-1.0.jar
s2jdbc.diconweb.xml追加
<!-- ZK -->
<listener>
<listener-class>org.zkoss.zk.ui.http.HttpSessionListener</listener-class>
</listener>
<servlet>
<servlet-name>zkLoader</servlet-name>
<servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class>
<init-param>
<param-name>update-uri</param-name>
<param-value>/zkau</param-value>
</init-param>
<load-on-startup>1</load-on-startup><!-- Must -->
</servlet>
<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zul</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>auEngine</servlet-name>
<servlet-class>org.zkoss.zk.au.http.DHtmlUpdateServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>auEngine</servlet-name>
<url-pattern>/zkau/*</url-pattern>
</servlet-mapping>
<!-- Miscellaneous -->
<session-config>
<session-timeout>120</session-timeout>
</session-config>
<!-- ZK -->
2008年3月11日火曜日
ZK: jdbcManager Seasar変数(3)
jdbcManagerを使いながらデザインとロジックを分離したいときは
こんな感じでいけそうです。
listboxのモデルにEmpWindowのプロパティemps、selectedItemにselectedをセットします。
EmpWindow.java
ZKをSeasarと組み合わせるとデータベースアクセスはjdbcManagerの使いかただけ知っていればいいみたいですね。
こんな感じでいけそうです。
listboxのモデルにEmpWindowのプロパティemps、selectedItemにselectedをセットします。
...
<window id="win" title="Emplyee list" use="zkseasar.view.EmpWindow">
<listbox id="lb" model="@{win.emps}" selectedItem="@{win.selected}">
EmpWindow.java
public class EmpWindow extends Window {
private JdbcManager jdbcManager;
private List<Emp> emps;
private Emp selected;
public EmpWindow(){
DelegatingVariableResolver variableResolver = new DelegatingVariableResolver();
jdbcManager = (JdbcManager)variableResolver.resolveVariable("jdbcManager");
emps = jdbcManager.from(Emp.class)
.where("sal between ? and ?", 2000, 3000)
.orderBy("sal").getResultList();
}
public List<Emp> getEmps(){
return emps;
}
public void setSelected(Emp emp){
selected = emp;
}
public Emp getSelected(){
return selected;
}
/*
* listboxにempを追加する
* http://sourceforge.net/forum/message.php?msg_id=4752395
*/
public void addEmp(Emp emp){
Listbox lb = ((Listbox) getFellow("lb"));
((ListModelList) lb.getModel()).add(emp);
}
}
ZKをSeasarと組み合わせるとデータベースアクセスはjdbcManagerの使いかただけ知っていればいいみたいですね。
ZK: jdbcManager Seasar変数(2)
可変長引数を持つメソッドはzscriptでは使用できないようです。
上記のスクリプトを実行すると次のエラーメッセージを吐いてしまいます。
検索条件を指定するときはSQL文字列ではなくSimpleWhereが使えます。
Rubyからは可変長引数を持つJavaメソッドでも呼び出せるか試してみました。
やはりダメですね。
<zscript>
import zkseasar.entity.Emp;
emps = jdbcManager.from(Emp.class)
.where("sal >= ?", 2000)
.orderBy("sal")
.getResultList();
</zscript>
上記のスクリプトを実行すると次のエラーメッセージを吐いてしまいます。
致命的: サーブレット zkLoader のServlet.service()が例外を投げました
org.zkoss.zk.ui.UiException: Sourced file: inline evaluation of: ``import zkseasar.entity.Emp;
emps = jdbcManager.from(Emp.class) . . . '' :
Error in method invocation: Method where( java.lang.String, int ) not found in class'org.seasar.extension.jdbc.query.AutoSelectImpl' :
検索条件を指定するときはSQL文字列ではなくSimpleWhereが使えます。
<zscript >
import zkseasar.entity.Emp;
import org.seasar.extension.jdbc.where.SimpleWhere;
emps = jdbcManager.from(Emp.class)
.where(new SimpleWhere()
.ge("sal", 2000)
)
.orderBy("sal")
.getResultList();
</zscript>
Rubyからは可変長引数を持つJavaメソッドでも呼び出せるか試してみました。
<zscript language="ruby">
import 'zkseasar.entity.Emp'
emps = $jdbcManager.from(Java::ZkseasarEntity::Emp:Class).
where("sal >= ?", 2000).
orderBy("sal").
getResultList()
emps.each{|emp| print emp.deptId, "\t", emp.empName, "\t", emp.sal, "\n"}
</zscript>
やはりダメですね。
致命的: サーブレット zkLoader のServlet.service()が例外を投げました
:1: no where with arguments matching [class java.lang.String, class java.lang.Long]
on object JavaUtilities (NameError)
...internal jruby stack elided...
ZK: jdbcManager Seasar変数
DelegatingVariableResolverでZKから直接jdbcManagerが使えるんですね。
emp.zul
これは楽ちん!!
java.util.Date および java.util.Calendar 型のプロパティには時制を指定する必要があるそうです。
EmpクラスのhiredateプロパティはDate型なので@Temporalを使い時制にTemporalType.DATEを指定します。
Emp.java
emp.zul
<?xml version="1.0" encoding="UTF-8"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<?variable-resolver class="org.zkoss.zkplus.seasar.DelegatingVariableResolver"?>
<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 ">
<zscript >
import zkseasar.entity.Emp;
emps = jdbcManager.from(Emp.class)
.orderBy("sal")
.getResultList();
</zscript>
<window title="Emplyee list" >
<listbox model="@{emps}">
<listhead>
<listheader label="id"/>
<listheader label="Emp no"/>
<listheader label="Emp name"/>
<listheader label="Hiredate"/>
<listheader label="Sal"/>
<listheader label="Dept id"/>
<listheader label="Version no"/>
</listhead>
<listitem self="@{each=emp}">
<listcell label="@{emp.id}"/>
<listcell label="@{emp.empNo}"/>
<listcell label="@{emp.empName}"/>
<listcell label="@{emp.hiredate}"/>
<listcell label="@{emp.sal}"/>
<listcell label="@{emp.deptId}"/>
<listcell label="@{emp.versionNo}"/>
</listitem>
</listbox>
</window>
</zk>
これは楽ちん!!
java.util.Date および java.util.Calendar 型のプロパティには時制を指定する必要があるそうです。
EmpクラスのhiredateプロパティはDate型なので@Temporalを使い時制にTemporalType.DATEを指定します。
Emp.java
public class Emp {
..
@Temporal(TemporalType.DATE)
@Column(name = "HIREDATE")
public Date hiredate;
..
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と言う名前で関連付けます。

次のメソッドを実行するとデータベースからリロードすることができます。
まず<?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を作成します。
RainStatsServiceに年間平均降雨量を取り出すメソッドを追加します。
DTOのプロパティ名とSQLのカラム名を統一するだけでSQLを実行した結果がDTOへ自動的にマッピングされるようです。
S2TestCaseを継承したクラスを作り動作確認します。
EclipseのメニューからRun>Debug As>JUnit Testで実行できます。
package zkseasar.dto;
public class RainfallAvgDto {
public Integer year;
public Double average;
}
DTOのプロパティ名とSQLのカラム名を統一するだけでSQLを実行した結果がDTOへ自動的にマッピングされるようです。
...
public ListselectRainfallAvg(){
return jdbcManager.selectBySql(RainfallAvgDto.class,
" select year, avg(rainfall) as average" +
" from rain_stats " +
" group by year " +
" order by year ")
.getResultList();
}
...
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");
Listresults =
rainStatsService.selectRainfallAvg();
for (RainfallAvgDto dto : results) {
System.out.println(dto.year + ":"+ dto.average);
}
}
}
2007年12月19日水曜日
ZK: ウィンドウをブラウザの中央に表示
2007年12月2日日曜日
ZK: iText
Report with ZK : Using JasperReports As an Exampleを参考に動的にPDFファイルを作成するサンプルを作ってみました。
PDF作成にはiTextライブラリを使います。まずこちらのサイトからjarファイルをダウンロードします。日本語を使うためにこちらのサイトからiTextAsian.jarをダウンロードします。
次にダウンロードしたjarファイルをWEB-INF/libへインポートして準備完了です。
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>
2007年11月19日月曜日
ZK + Seasar: JFreeChart(2)
チャートモデルにSimpleCategoryModelを使用するグラフを表示します。次のグラフのモデルにSimpleCatagoryModelが使えます。
データは降雨量ですので意味不明なグラフもありますがご愛嬌ということで(^^


- 棒グラフ
- 折れ線グラフ
- エリアグラフ
- 積み上げ棒グラフ
- 積み上げエリアグラフ
- ウォータフォールグラフ
データは降雨量ですので意味不明なグラフもありますがご愛嬌ということで(^^
<?xml version="1.0" encoding="UTF-8"?>
<?variable-resolver class="org.zkoss.zkplus.seasar.DelegatingVariableResolver"?>
<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 title="東京 年間降雨量デモ" width="500px" border="normal">
<vbox>
<chart id="myChart" title="月別降雨量 (mm)" width="500" height="250" type="bar" threeD="false" fgAlpha="128"/>
<radiogroup>
<radio label="棒グラフ" id="bar" onCheck="myChart.type=self.id" checked="true"/>
<radio label="折れ線グラフ" id="line" onCheck="myChart.type=self.id" />
<radio label="エリアグラフ" id="area" onCheck="myChart.type=self.id" />
<radio label="積み上げ棒グラフ" id="stacked_bar" onCheck="myChart.type=self.id" />
<radio label="積み上げエリアグラフ" id="stacked_area" onCheck="myChart.type=self.id" />
<radio label="ウォータフォール" id="waterfall" onCheck="myChart.type=self.id" />
</radiogroup>
<checkbox label="3D チャート" checked="false" onCheck="myChart.setThreeD(self.isChecked())"/>
</vbox>
<zscript>
model = new SimpleCategoryModel();
model.clear();
// 年を指定して降雨量をセット
void processYear(String year) {
rainStats = rainStatsService.selectAll(year);
for(data: rainStats){
model.setValue(year, data.month, data.rainfall);
}
}
processYear("2003");
processYear("2004");
processYear("2005");
myChart.setModel(model);
</zscript>
</window>
</zk>


登録:
投稿 (Atom)

