Apcoordinator ユーザーズガイド |
目次 |
付録A サンプルアプリケーション |
詳細モードでは、リストと複合Beanを使用しています。
main.jsp領域はbodyひとつだけを使用しています。
<HTML> <HEAD> <TITLE>model</TITLE> <%@ page contentType= "text/html; charset=shift_jis" %> <%@ taglib uri="uji-taglib" prefix="uji" %> </HEAD> <BODY> <uji:dispatch /> <uji:include pane="body" /> </BODY> </HTML>
MeisaiBean.java一件のデータを表すデータBeanです。更新はDataManagerクラスを呼び出すことで実行します。また、更新対象でないプロパティのsetメソッドは省略しています。
package model; public class MeisaiBean extends com.fujitsu.uji.DataBean { protected DataManager dm; protected String denpyoNo; protected String chumonDate; protected String shohinCode; protected String shohinName; protected String shohinCount; protected String tantoOffice; protected String nonyuDate; protected String kokyakuWard; protected String kokyakuName; protected String kokyakuPhone; public MeisaiBean(DataManager dm, String[] data) { this.dm = dm; denpyoNo = data[0]; chumonDate = data[1]; shohinCode = data[2]; shohinName = data[3]; shohinCount = data[4]; tantoOffice = data[5]; nonyuDate = data[6]; kokyakuWard = data[7]; kokyakuName = data[8]; kokyakuPhone = data[9]; } public String getDenpyoNo() { return denpyoNo; } public String getChumonDate() { return chumonDate; } public String getShohinCode() { return shohinCode; } public String getShohinName() { return shohinName; } public String getShohinCount() { return shohinCount; } public String getTantoOffice() { return tantoOffice; } public String getNonyuDate() { return nonyuDate; } public String getKokyakuWard() { return kokyakuWard; } public String getKokyakuName() { return kokyakuName; } public String getKokyakuPhone() { return kokyakuPhone; } public void setNonyuDate(String nonyuDate) { if(this.nonyuDate != nonyuDate) { dm.setNonyuDate(this, nonyuDate); } } }
DataManager.javaデータのアクセスを提供するクラスです。 このサンプルでは、初期値を文字列で持っています。また更新時もメモリ上のデータを書き換えるだけです。
package model; import java.util.Vector; public class DataManager { Vector data; public DataManager() { } public int getDataCount() { return data.size(); } public MeisaiBean getData(int index) { return (MeisaiBean)data.elementAt(index); } public void setNonyuDate(MeisaiBean bean, String value) { // データベースの更新処理に相当 bean.nonyuDate = value; } public void prepareData() { // データベースの読み込み処理に相当 data = new Vector(); for(int i = 0; i < initialData.length; i++) { MeisaiBean bean = new MeisaiBean(this, initialData[i]); data.addElement(bean); } } private static final String initialData[][] = { { "401791","20000214","AC106W","エアコン 100V 6畳用ホワイト","1", "川崎支店","未定","川崎市中原区","田村電気","044-999-9999" }, ....(省略).... }; }
ModelBean.javaデータBeanです。summaryとdetailのプロパティがそれぞれ画面部品のインタフェースを提供します。これらのクラスの詳細は後述します。
package model; public class ModelBean extends com.fujitsu.uji.DataBean { protected SummaryModel summary; protected DetailModel detail; public SummaryModel getSummary() { return summary; } public DetailModel getDetail() { return detail; } public void initData(DataManager dm) { summary = new SummaryModel(dm); detail = new DetailModel(dm); } }
ModelHandler.javashowDetailとshowSummaryでは、表示モードを切り替える(setVerb)のみの処理をしています。 startupメソッドでは、データの初期化をして、概要モードで表示しています。
package model; import com.fujitsu.uji.DispatchContext; public class ModelHandler extends com.fujitsu.uji.GenericHandler { protected DataManager dm; public ModelHandler() { } public boolean init() { return true; } public void showDetail(DispatchContext context, ModelBean dataBean) { dataBean.setVerb("detail"); context.setResponseBean("body", dataBean); } public void showSummary(DispatchContext context, ModelBean dataBean) { dataBean.setVerb("summary"); context.setResponseBean("body", dataBean); } public void startup(DispatchContext context) { dm = new DataManager(); dm.prepareData(); ModelBean dataBean = new ModelBean(); dataBean.initData(dm); dataBean.setVerb("summary"); context.setResponseBean("body", dataBean); } }
commands.map
# commands.map model.ModelBean;showDetail=model.ModelHandler.showDetail model.ModelBean;showSummary=model.ModelHandler.showSummary ;=model.ModelHandler.startup
pages.map
# pages.map model.ModelBean;summary=summary.jsp model.ModelBean;detail=detail.jsp
web.xml
付録A.1と同じです。割愛します。
summary.jspこの入出力ページでは、
<%@ page contentType="text/html; charset=shift_jis" %> <%@ taglib uri="uji-taglib" prefix="uji" %> <uji:useBean id="body" cls="model.ModelBean" request="true" /> <P>納入予定日設定(概要モード)</P> <uji:peTextMode/> <FORM method="post"> <INPUT name="uji.verbs" type="hidden" value="showDetail"> <INPUT name="uji.id" type="hidden" value="body"> <uji:table bean="body" property="summary"> <uji:tableRenderer type="table" > <TABLE border="2" width="100%"><uji:children/></TABLE> </uji:tableRenderer> <uji:tableRenderer type="column" cls="header" > <TH bgcolor="#EEFFEE"><uji:value/></TH> </uji:tableRenderer> <uji:tableRenderer type="column" cls="editable" > <TD><INPUT name="<uji:name/>" value="<uji:value/>"></TD> </uji:tableRenderer> </uji:table> <INPUT name="showDetail" type="submit" value="詳細表示"> </FORM>
uji:table
タグを使用しています。
uji:table
タグのアトリビュートでは、TableModelインタフェースを返すプロパティ名としてsummaryを指定しています。
uji:table
の中ではレンダラとして3つのuji:tableRenderer
タグを指定しています。レンダラは表やセルのフォーマットを記述するものです。uji:table
タグは、インタフェースで得られる情報に従って表・行・セルといった単位でレンダラを呼び出し、その内容を画面に出力します。レンダラを省略した場合には、予め決まったパターンを出力します。
type="table"
)のフォーマットを指定します。ここでは、TABLEタグにborderとwidthのアトリビュートを追加しています。uji:childrenタグは下位のレンダラの処理を行う指定です。
type="column"
)で状態がヘッダ(cls="header"
)のもののフォーマットを指定しています。ここではTHタグを使い、背景色を設定しています。uji:valueはセルの値を表示する指定です。
最後のレンダラは、セル(type="column"
)で状態が編集可能(cls="editable"
)のもののフォーマットの指定です。INPUTタグで入力したデータはApcoordinatorが自動的にデータBeanに反映します。これを可能にするため、uji:name
では更新時の名前を自動生成しています。
uji:peTextMode
タグは、Apworksのページエディタに対する画面編集禁止の指定です。これは実行時は何も影響しません。
SummaryModel.java表のインタフェースの実装クラスです。
package model; public class SummaryModel implements com.fujitsu.uji.model.table.TableModel { DataManager dm; public SummaryModel(DataManager dm) { this.dm = dm; } public int getColumnCount() { return 6; } public int getRowCount() { return dm.getDataCount() + 1; } public java.lang.Object getValueAt(int row, int col) { if(row == 0) { switch(col) { case 0: return "伝票番号"; case 1: return "注文日"; case 2: return "品番"; case 3: return "数量"; case 4: return "担当支店"; case 5: return "納入予定日"; } } else { MeisaiBean bean = dm.getData(row - 1); switch(col) { case 0:return bean.getDenpyoNo(); case 1:return bean.getChumonDate(); case 2:return bean.getShohinCode(); case 3:return bean.getShohinCount(); case 4:return bean.getTantoOffice(); case 5:return bean.getNonyuDate(); } } throw new ArrayIndexOutOfBoundsException(); } public java.lang.String getColumnClass(int row, int col) { if(row == 0) return "header"; else if(col == 5) return "editable"; return null; } public java.lang.String getRowClass(int row) { return null; } public void setValueAt(java.lang.Object val, int row, int col) { if(row == 0 || col != 5 || !(val instanceof String)) throw new IllegalStateException(); MeisaiBean bean = dm.getData(row - 1); bean.setNonyuDate((String)val); } }
detail.jspこの入出力ページでは、
<%@ page contentType="text/html; charset=shift_jis" %> <%@ taglib uri="uji-taglib" prefix="uji" %> <uji:useBean id="body" cls="model.ModelBean" request="true" /> <P>納入予定日設定(詳細モード)</P> <uji:peTextMode/> <FORM method="post"> <INPUT name="uji.verbs" type="hidden" value="showSummary"> <INPUT name="uji.id" type="hidden" value="body"> <uji:list bean="body" property="detail"> <uji:listRenderer type="list"> <TABLE border="2" width="100%"> <TR> <TH bgcolor="#EEFFEE" rowspan="2">伝票番号 <TH bgcolor="#EEFFEE">注文日 <TH bgcolor="#EEFFEE">品番 <TH bgcolor="#EEFFEE">数量 <TH bgcolor="#EEFFEE" colspan="2">顧客地区 <TH bgcolor="#EEFFEE">納入予定日 <TR> <TH bgcolor="#EEFFEE" colspan="3">商品名 <TH bgcolor="#EEFFEE">担当支店 <TH bgcolor="#EEFFEE">顧客名称 <TH bgcolor="#EEFFEE">顧客電話番号 <uji:children /> </TABLE> </uji:listRenderer> <uji:listRenderer type="element"> <uji:composite> <uji:compositeRenderer> <TR> <TD rowspan="2"><uji:getProperty property="denpyoNo" /> <TD><uji:getProperty property="chumonDate" /> <TD><uji:getProperty property="shohinCode" /> <TD><uji:getProperty property="shohinCount" /> <TD colspan="2"><uji:getProperty property="kokyakuWard" /> <TD><input name="<uji:compositeName property='nonyuDate' />" value="<uji:getProperty property='nonyuDate' />" > <TR> <TD colspan="3"><uji:getProperty property="shohinName" /> <TD><uji:getProperty property="tantoOffice" /> <TD><uji:getProperty property="kokyakuName" /> <TD><uji:getProperty property="kokyakuPhone" /> </uji:compositeRenderer> </uji:composite> </uji:listRenderer> </uji:list> <INPUT name="showSummary" type="submit" value="概要表示"> </FORM>
uji:list
タグとuji:composite
タグを使用しています。
uji:list
タグのアトリビュートでは、ListModelインタフェースを返すプロパティ名としてdetailを指定しています。
uji:composite
タグではデータBeanを指定していません。これは上位の画面部品(ここではuji:list
)からデータBeanを受け取っているためです。この例では、リストのエレメントとして返される値がMeisaiBeanクラスで、これがuji:composite
タグで使うデータBeanになります。
uji:composite
タグには、アトリビュートをもたないレンダラを1つ書きます。compositeRendererの中では値の参照にuji:getProperty
タグ、また更新時の名前の指定にuji:compositeName
タグを書きます。この例はデータを2段にフォーマットし、納入予定日を更新可能にしています。
DetailModel.javaリストのインタフェースを実装するクラスです。
package model; public class DetailModel implements com.fujitsu.uji.model.list.ListModel { DataManager dm; public DetailModel(DataManager dm) { this.dm = dm; } public int getSize() { return dm.getDataCount(); } public java.lang.Object getElementAt(int pos) { return dm.getData(pos); } public java.lang.String getElementClass(int pos) { return null; } public void setElementAt(java.lang.Object obj, int pos) { throw new IllegalStateException(); } }
uji:name
タグで入力フィールドを指定するときはsetElementAtでデータを受け取りますが、この場合はuji:composite
タグを介して入力フィールドを設定しているため、MeisaiBeanのsetメソッドが直接呼ばれることになります。
目次 |