2008年12月24日水曜日

ZK: MVC ラベルの日付を和暦で表示する

DateUserを参考に日付を和暦(元号)で表示する。(Java6)

public class DateUserWAREKI implements TypeConverter {

@Override
public Object coerceToBean(Object arg0, Component arg1) {
// TODO Auto-generated method stub
return null;
}

@Override
public Object coerceToUi(Object arg0, Component arg1) {
if (arg0 == null) {
return null;
}
Locale locale = Locale("ja","JP","JP");
SimpleDateFormat sdf = new SimpleDateFormat("GGGGyy年M月d日", locale);
Date date = (Date) arg0;
return sdf.format(date);
}
}



<listcell label="@{employee.hireDate, converter='org.zkforge.converters.DateUserWAREKI'}"/>

ZK: MVC ラベルの日付をyyyy/MM/dd形式で表示する

http://www.pichelhofer.at/ZKDemoで紹介されているTypeConverterを利用し日付をロケールに合わせて表示する。

http://www.pichelhofer.at/ZKDemo/src/DateUser.java.html


<listcell label="@{employee.hireDate, converter='org.zkforge.converters.DateUser'}"/>

ZK: MVC 変数selectedにアクセスする

ビューの変数selectedにコントローラからアクセスする。


public void onClick$selectedBtn(Event e) throws Exception{
Employee selected =(Employee)win.getVariable("selected", true);
if (selected != null){
alert(selected.firstName);
}
}

ZK: MVC リストボックスをクリアする

データバインドされているリストボックスをクリアするにはbeanにnullを代入し、
データバインダを使用してデータロードする。


public void onClick$clearBtn(Event e) throws Exception{
empData = null;
empListbox.unsetVariable("selected", true);
binder = (AnnotateDataBinder)page.getVariable("binder");
binder.loadAll();
}

ZK: MVC 選択を解除する

unsetVariableメソッドを使いlistboxからselected変数を取り除いた後、
データバインダを使用してデータをロードし直すことでリストボックスの選択を解除し、
明細をクリアできる。
   
public void onClick$clearSelBtn(Event e) throws Exception{
empListbox.unsetVariable("selected", true);
binder = (AnnotateDataBinder)page.getVariable("binder");
binder.loadAll();
}

2008年12月10日水曜日

ZK: MVC

GenericFowardComposerを拡張したコントローラ・クラスを作成しwindowのapply属性の値に設定すると、イベント・リスナーが自動的に登録されると同時にzulコンポーネントとコントローラのフィールドが自動的に紐つけられる。このためコントローラのコードが非常にすっきり記述できるようになった。

ボタンをクリックすると2個のintboxの値を足し算しlabelへ表示するサンプル
ビュー

<window id="win" title="MVCサンプル" border="normal" width="300px" apply="Controler1">
<hbox>
<intbox id="arg1"/> + <intbox id="arg2"/> <button label=" = " id="addBtn" /> <label id = "ans"/>
</hbox>
</window>


コントローラ

public class Controler1 extends GenericForwardComposer {
private Intbox arg1; //ビューの<intbox id="arg1"/>コンポーネントと自動的に紐付けされる
private Intbox arg2; //ビューの<intbox id="arg2"/>コンポーネントと自動的に紐付けされる
private Label ans; //ビューの<label id="and"/>コンポーネントと自動的に紐付けされる

// addBtnボタンの onClickイベント・リスナー
public void onClick$addBtn(Event e) throws Exception{
ans.setValue(String.valueOf(arg1.getValue() + arg2.getValue()));
}
}

コントローラでビューのzulコンポーネントと同じ型でidと同じ名称のフィールドを宣言するとzulコンポーネントと自動的に紐つけされる。
onイベント名$コンポーネント名の形でイベント・リスナーを書いておけば自動的に登録され対応するビューのコンポーネントのイベントが処理できる


データバインド
S2JDBCを使いFirebirdに付属のemployeeテーブルをリストと明細で表示するサンプル。

データバインダを利用するにはビューを<?init class="org.zkoss.zkplus.AnnotateDataBinderInit" ?>で初期化する。
バリアブル・リゾルバにorg.zkoss.zkplus.seasar.DelegatingVariableResolverを使用しSeasar変数jdbcManagerを利用できるようにする。

ビュー

<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>
<?variable-resolver class="org.zkoss.zkplus.seasar.DelegatingVariableResolver"?>
<window id="win" title="Employee" border="normal" width="300px" apply="MyControler">
<listbox id="empListbox" width="200px" rows="10" multiple="true" height="100%"
checkmark="true" model="@{controler.empData}" selectedItem="@{selected}">
<!--
controlerはMyControlerのdoAfterComposeメソッドでWindow変数に追加されている。
aWindow.setVariable("controler", this, true); //aWindowはdoAfterComposeの引数
empDataはcontrolerで定義されているList<Employee>型のプロパティ
-->
<listhead>
<listheader label="姓" />
<listheader label="名" />
</listhead>
<listitem self="@{each=employee}">
<listcell label="@{employee.lastName}"/>
<listcell label="@{employee.firstName}"/>
</listitem>
</listbox>
<vbox>
<hbox>姓: <label value="@{selected.lastName}"/></hbox>
<hbox>名:<label value="@{selected.firstName}"/></hbox>
<hbox>内線番号: <label value="@{selected.phoneExt}"/></hbox>
<hbox>入社日:<label value="@{selected.hireDate}"/></hbox>
</vbox>
</window>


コントローラ

public class MyControler extends GenericForwardComposer {
private List<Employee> empData;
private JdbcManager jdbcManager; //super.doAfterComposeのコール後Seasar変数と自動で紐付けされる

@Override
public void doAfterCompose(Component aWindow) throws Exception {
super.doAfterCompose(aWindow);

// 自分自身をwindowの変数に追加するとビューからアクセス可能なオブジェクトになる。
aWindow.setVariable("controler", this, true);
empData = jdbcManager.from(Employee.class).getResultList();
}

//zulのListboxのmodelプロパティには controler.empData を設定する
public List<Employee> getEmpData() {
return empData;
}
}

2008年12月5日金曜日

ZK: forEach属性のeach変数の値へコンポーネント生成後にアクセス

コンポーネントのeach属性はforEach属性で配列を使用してコンポーネントを表示するときに使われる一時変数なので、あとからonXXXイベント等でこの値にアクセスしたい場合はコンポーネントを表示すると同時にcustom-attributesを使用しeachの値を保存して置く。

<window width="100%">
<zscript>
// コンポーネントのforEach属性を利用して生成するボタンの国名ラベルの配列
String[] countries = {"China", "France", "Germany", "United Kindom", "United States", "Japan"};
</zscript>
<hbox>
<button label="${each}" forEach="${countries}">
<!-- eachの値をcustom-attributesのcountryに保存する -->
<custom-attributes country="${each}"/>
<attribute name="onClick">
{
//countryにアクセスする。
alert(componentScope.get("country"));
}
</attribute>
</button>
</hbox>
</window>

2008年12月4日木曜日

ZK: Listitemのフォントサイズを変更する


<style>
div.cell-inner{
font-size:xx-small;
//font-size:xx-large;
}
</style>

ZK: 小文字の入力時に自動で大文字に変換するtextbox

小文字の入力が入力と同時に大文字に変換される。

<textbox style="text-transform:uppercase" id="idx" />

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("")を使用すると制約を回避しテキストボックスをクリアできる。


<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: リクエスト・パラメータを取得する


<window title="リクエスト・パラメータの取得"
width="250px" height="200px" border="normal">
<label value="${param.q}"/>
</window>

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>