Articles
日本オラクル株式会社
システム製品統括本部 Fusion Middleware技術部 SOA/Javaグループ
エンジニア 智野 潤子
JDeveloperが本になります。『Oracle JDeveloper 10g JSF/EJB3.0アプリケーション開発』というタイトルで2007年4月出版予定です。
こちらもよろしくお願いします。
今回は、JSFコンポーネントを用いたWebアプリケーションのユーザー・インタフェース開発の2回目として、データを表形式で表示するための方法を紹介します。
Oracle ADF Faces(以下、ADF Faces)では、データを表形式で表示するためにTableコンポーネント(af:tableタグ)を使用します。af:tableタグは、JSFリファレンス実装により提供されるDataTableコンポーネント(h:dataTableタグ)には含まれていない、次のような機能を備えています。
<サンプル 1>は、af:tableタグの基本的な使用方法です。
<サンプル 1>
<af:table value=”#{managed_bean.list}” var=”row”>
<af:column headerText=”従業員番号”>
<af:outputText value=”#{row.empno}”/>
</af:column>
<af:column headerText=”名前”>
<af:commandLink text=”#{row.ename}”/>
</af:column>
<af:column headerText=”職種”>
<af:outputText value=”#{row.job}”/>
</af:column>
</af:table>
af:tableタグはh:dataTableタグと同様に、value属性を使用して表示するデータのコレクションをEL式で指定します。af:tableタグのvalue属性には、次のようなコレクションを指定できます。
var属性には、コレクション内の個々のオブジェクトにアクセスするための変数名を指定します。<サンプル 1>では「row」が指定されています。
af:tableタグは1つ以上のaf:columnタグを含みます。af:columnタグは表の列を表し、headerText属性では、列ヘッダーとして表示するテキストを指定することができます。また、af:columnタグの子タグは、その列のデータを表示する際に使用するUIコンポーネントです。<サンプル 1>では、それぞれの列が表 1のように設定されています。
表 1:<サンプル 1>における各列の設定
| 列 | 列ヘッダー・テキスト | UIコンポーネント | データ |
|---|---|---|---|
| 1列目 | 従業員番号 | af:outputText | #{row.empno} |
| 2列目 | 名前 | af:commandLink | #{row.ename} |
| 3列目 | 職種 | af:outputText | #{row.job} |
この章では次の2つのクラスを使用して、af:tableタグのさらに詳しい使用方法を説明します。EmpServiceBeanには、従業員を表すEmpオブジェクトのリストを返すgetEmpListが実装されており、「emp_service」という名前でマネージドBeanとして登録されていることを前提にしています。
JDeveloperでは、ページにaf:tableタグを容易に追加することができる「表の挿入」ウィザードを提供しています。このウィザードは次のように使用します。
af:tableタグには、次の5つのファセットが用意されています。
本章では、detailStampファセットとselectionsファセットの使用法について説明します。
detailStampファセットによる詳細データの表示
af:tableタグにdetailStampファセットを追加すると、図 10のように「詳細」列が加わり、各行に「表示/非表示」リンクが入ります。detailStampファセット内に記述されたコンポーネントは「表示」リンクをクリックしたときにのみ表示されるようになります。
JDeveloperで、af:tableタグにdetailStampファセットを追加する方法は、次の2通りがあります。
a. 構造ウィンドウでdetailStampを追加するaf:tableをダブルクリックし、起動した「Tableのプロパティ」ダイアログの「書式設定」ページで、「詳細の開示を含める」をチェック
b. 図11のように、構造ウィンドウでdetailStampを追加するaf:tableを右クリックし、コンテキスト・メニューから「ファセット - Table」→「Detail Stamp」を選択
給与のデータ(Empオブジェクトのsalプロパティ)を詳細情報として表示する場合は、salプロパティを表示していたcolumnタグを削除し、代わりに<サンプル 2>の太字部分のようにコードを変更します。
<サンプル 2>
<af:table value=”#{managed_bean.list}” var=”row”>
<af:column headerText=”社員番号”>
<af:outputText value=”#{row.empno}”/>
</af:column>
<af:column headerText=”名前”>
<af:outputText value=”#{row.ename}”/>
</af:column>
<!-- 中略 -->
<f:facet name=”detailStamp”>
<af:outputText value=”${row.sal}”/>
</f:facet>
</af:table>
TableSelectOneコンポーネントによるデータの単一選択
Webアプリケーションでは、テーブル形式で表示されたデータの中から選択されたデータの詳細情報を、表示するページや編集ページに遷移させることがよくあります。そのような場合、af:tableタグのselectionsファセットにTableSelectOneコンポーネント(af:tableSelectOneタグ)を追加します。af:tableSelectOneタグを使用すると、図 12のように「選択」列が追加され、それぞれの行にラジオボタンが表示されます。
selectionsファセットにTableSelectOneファセットを追加するには、構造ウィンドウでaf:tableをダブルクリックし、起動された「Tableのプロパティ」ダイアログの「書式設定」ページで、「選択列を含める」をチェックしてから「単一選択」を選択します。
選択されたデータに対する処理を実装するためには、次のような手順が必要です。
「JSF JSPの作成」ウィザードのステップ2で、「新規マネージドBeanでUIコンポーネントの自動公開」または「既存のマネージドBeanでUIコンポーネントの自動公開」オプションを選択した場合は、af:tableタグはマネージドBeanのプロパティとして自動的に公開されています。「マネージドBeanでUIコンポーネントを自動公開しない」を選択した場合には、手動での設定が必要です。af:tableタグをマネージドBeanのプロパティとして公開するには、af:tableタグをビジュアル・エディタまたは構造ウィンドウで選択し、プロパティ・インスペクタで「Binding」の右のフィールドをクリックすると表示される「...(編集)」をクリックします。
これにより、「Binding」ダイアログが表示されるので、af:tableをプロパティとして公開するマネージドBeanとプロパティ名を指定し、「OK」ボタンをクリックします。
図 14では、マネージドBeanとして「emp_service」を、プロパティとして「table」を指定しています。これにより、af:tableタグのbinding属性の値として「#{emp_service.table}」が指定され、EmpServiceBeanクラスには<サンプル 3>のようにtableプロパティとsetter/getterメソッドが追加されます。
<サンプル 3>
public class EmpServiceBean {
private oracle.adf.view.faces.component.core.data.CoreTable table;
// 中略
public void setTable(CoreTable table) {
this.table = table;
}
public CoreTable getTable() {
return table;
}
}
次に、処理を起動するためのUIコンポーネントを追加します。図15のように構造ウィンドウで、追加されたaf:tableSelectOneを右クリックし、コンテキスト・メニューから「af:tableSelectOneの中に挿入」→「CommandButton」を選択します。
これにより、af:commandButtonタグが追加され、図16のようにテーブルの一番上に表示されます。このaf:commandButtonがクリックされたときに起動されるActionメソッドを実装するには、ビジュアル・エディタでaf:commandButtonをダブルクリックします。
JDeveloperでは、af:commandButtonなどのボタンをビジュアル・エディタでダブルクリックすると、「バインドActionプロパティ」ダイアログが起動されます。ボタンがクリックされたときに起動されるActionメソッドを実装する場合は、「マネージドBean」とメソッドの名前を指定します。図 17では、マネージドBeanとして「emp_service」を、メソッドとして「commandAciton」を指定しています。
「バインドActionプロパティ」ダイアログで「OK」ボタンをクリックすると、af:commandButtonタグのaction属性に「#{emp_service.commandAction}」が指定され、マネージドBeanのJavaソース(EmpServiceBean.java)にメソッドの雛形が追加されます。<サンプル 4>は、テーブルから選択された従業員の名前を標準出力に出力しています。
<サンプル 4>
public String commandAction() {
Emp emp = (Emp) getTable().getRowData(); // 選択されたオブジェクト
System.out.println(emp.getEname());
Return null;
}
TableSelectManyコンポーネントによるデータの複数選択
テーブル内のデータを一括で削除する場合など、アプリケーションの要件によってはテーブル内に表示されたデータから複数のものを選択する必要がある場合があります。そのようなときには、af:tableタグのselectionsファセットにTableSelectManyコンポーネント(af:tableSelectManyタグ)を追加すると、図 18のように各行にチェックボックスが追加されます。
selectionsファセットにTableSelectOneファセットを追加するには、構造ウィンドウでaf:tableをダブルクリックし、起動された「Tableのプロパティ」ダイアログの「書式設定」ページで、「選択列を含める」をチェックしてから「複数選択」を選択します。
af:tableSelectOneと同様に、ユーザーが選択したデータを取得するには、次の3つのステップが必要です。
それぞれの手順の詳細は、af:tableSelectOneで説明しているため、ここではActionメソッドの実装例のみを紹介します。<サンプル 5>は、af:tableSelectManyタグによって選択したEmpオブジェクトの名前を標準出力に出力します。
<サンプル 5>
public class EmpServiceBean {
private oracle.adf.view.faces.component.core.data.CoreTable table;
public void setTable(CoreTable table) { this.table = table; }
public CoreTable getTable() { return table; }
// 中略
public String commandAction() {
// 選択された行のキーを取得
Iterator iter = table.getselectionState().getKeySet().iterator();
Object oldKey = table.getRowKey();
while (iter.hasNext()) {
Object key = iter.next();
table.setRowKey(key); // 備考参照
Emp emp = (Emp) table.getRowData(); //選択されたオブジェクトの1つ
System.out.println(emp.getEname());
}
table.setRowKey(oldKey);
return null;
}
}
<note>
af:tableタグで表示される行のデータには、それぞれキーが割り振られており、ユーザーが選択した行のキーはrowKeyプロパティで管理しています。getRowDataメソッドは、rowKeyプロパティにセットされているキーに応じてデータを戻します。af:tableSelectOneタグで選択された行のキーは、自動的にrowKeyプロパティに設定されます。しかし、rowKeyプロパティはキーを1つだけしか保持できません。af:tableSelectManyタグによって複数の行が選択されている場合は<サンプル 5>のように選択された行のキーのコレクションを取得し、getRowDataメソッドをコールする前に、rowKeyプロパティを設定する必要があります。
</note>
前回から2回にわたり、ADF Facesを使用したWebアプリケーションのユーザー・インタフェースの開発について説明しました。ADF Facesが提供するUIコンポーネントを使用すると、これまでJavaScriptによるプログラミングが必要だった機能を簡単に実現することがご確認いただけたのではないでしょうか。
ADF Facesはほかにも、入力フォーム用のコンポーネントや部分ページレンダリングなどの多彩な機能を備えています。マニュアルなどを参考にして、ぜひ実際にお試しください。
<note>次世代ADF Faces
オラクルではすでに、ADF Facesの次期バージョンの開発プロジェクトを進めています。この次世代ADF Facesの最大の目標は、デスクトップ・アプリケーションのもつ操作性をWebページで実現するためのUIコンポーネントを提供することです。
次世代ADF Facesのコンポーネントでは、次のような機能が提供される予定です。
</note>