Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド 11gリリース1 (11.1.1.7.0) B52028-05 |
|
前 |
次 |
この章では、ADF FacesコンポーネントおよびADFデータバインディングを使用してデータバインドされた表を作成するための、「データ・コントロール」パネルの使用方法を説明します。
この章の内容は次のとおりです。
フォームとは異なり、表を使用すると、コレクションのデータ・オブジェクトを一度に複数表示できます。図23-1は、StoreFrontモジュール・アプリケーションの注文内容ページの注文品目タブを示しており、特定の注文の品目を表示するための表の参照が使用されています。
単にデータを表示する表を作成することも、データの編集または作成が可能な表を作成することもできます。コレクションを表としてドロップすると、選択した行に対してなんらかのロジックを実行するアクションにバインドされたコマンド・ボタンを追加できます。また、必要に応じてデフォルトのコンポーネントを変更することもできます。
フォームを構成する個々のUIコンポーネントをコレクション上の個々の属性にバインドするフォームとは異なり、表では、ADF Facesのtable
コンポーネントをコレクション全体にバインドするか、コレクションから一度にnデータ・オブジェクトのレンジにバインドします。その結果、列にデータを表示するために使用される個々のコンポーネントが属性にバインドされます。イテレータ・バインディングによって各オブジェクトの適切なデータが表示され、table
コンポーネントによって各オブジェクトが1行で表示されます。JDeveloperを使用すると、宣言的にこの処理を実行できるため、コードを記述する必要がありません。
データ・コントロールを使用して表を作成するには、table
コンポーネントをコレクションにバインドします。JDeveloperでは、「データ・コントロール」パネルからコレクションをドラッグ・アンド・ドロップして、宣言的にこの処理を実行できます。
ヒント: また、コンポーネント・パレットから表コンポーネントをドラッグし、ADF Faces Tableの作成ウィザードを完了しても表を作成できます。 |
データバインドされた表を作成するには:
「データ・コントロール」パネルから、コレクションを選択します。
たとえば、システム内の製品を表示する簡単な表をStoreFrontモジュールで作成するには、Products
コレクションを選択します。
コレクションをJSFページにドラッグし、ポップアップ・メニューから適切な表を選択します。
コレクションをドラッグする場合は、次の表のタイプから選択できます。
ADF表: 編集可能な表列に表示する特定の属性、およびデータの表示に使用するUIコンポーネントを選択できます。デフォルトでは、ADF inputText
コンポーネントはほとんどの属性で使用され、このコンポーネントにより、表は編集可能となります。日付である属性ではinputDate
コンポーネントが使用されます。さらに、属性にコントロール・タイプのコントロール・ヒントが作成されている場合、または属性がリストとして構成されている場合、ヒントにより設定されたコンポーネントが使用されます。
ADF読取り専用表: 「ADF表」と同じですが、各属性は、outputText
コンポーネントに表示されます。
ADF読取り専用動的表: 返されて表示される属性が実行時に動的に決定される表を作成できます。このコンポーネントは、対応するオブジェクトの属性が実行時まで不明な場合、あるいはJSFページに列名をハードコーディングしない場合に適しています。
次に表示される「表の列の編集」ダイアログには、コレクション内の各属性が表示されます。また、これらの属性がどのように動作し、表の列としてどのように表示されるかを定義できます。
注意: コレクションに構造化属性(Javaのプリミティブ・タイプまたはコレクションのいずれでもない属性)が含まれる場合、その構造化属性の属性も同様にダイアログに表示されます。 |
ダイアログを使用すると、次の操作ができます。
「行選択」チェック・ボックスの選択による、ADFモデル・レイヤーでの選択の処理。このオプションを選択すると、イテレータ・バインディングがイテレータにアクセスして選択した行を決定します。表での選択を実行しない場合以外は、このオプションを選択してください。
「ソート」チェック・ボックスの選択による、ADFモデル・レイヤーでの列のソート処理。このオプションを選択すると、イテレータ・バインディングがイテレータにアクセスし、order-by問合せを実行して順序を決定します。列のソートを実行しない場合以外は、このオプションを選択してください。
「フィルタリング」チェック・ボックスの選択による、入力した基準を使用した、表の列のフィルタリングの実行。このオプションを選択すると、各列の上にあるテキスト・フィールドに基準を入力できます。その後で、この基準を使用してコレクションへのQuery-by-Example (QBE)検索を作成すると、問合せによって戻された結果のみが表に表示されます。詳細は、27.5項「スタンドアロンのフィルタ処理された検索表を名前付きビュー基準から作成」を参照してください。
目的の属性(ダイアログでは行として表示)の選択およびグループ化ボタンのクリックによる、親列の下の選択した属性の列のグループ化。図23-2は、表の作成後にグループ化された3つの列がビジュアル・エディタでどのように表示されるかを示しています。
列の表示ラベルを変更できます。デフォルトでは、ラベルは表バインディング上の属性に定義されたすべてのコントロール・ヒントのlabels
プロパティにバインドされます。このバインディングにより、ビュー・オブジェクトのラベル・テキストの値を1回変更することで、そのラベルが表示されるすべてのページに、その変更を同様に表示できます。
このデフォルトを使用するかわりにテキストまたはEL式を入力し、ラベル値のバインド先をリソース・ファイルのキーなど、別のものにすることができます。
列の値バインディングの変更。異なる属性にバインドされるように列を変更できます。単に列を並べ替える場合は、順序ボタンを使用してください。列の属性バインディングを変更すると、列のラベルも変更されます。
属性の表示に使用されるUIコンポーネントの変更。UIコンポーネントは、コレクションをページにドロップしたときに選択した表と、対応する属性のタイプ(たとえば、日付である属性にはinputDate
コンポーネントを使用)、および対応するビュー・オブジェクトにおいてデフォルト・コンポーネントがコントロール・ヒントとして設定されているかどうかに基づいて設定されます。ドロップダウン・メニューを使用して別のコンポーネントに変更できます。
ヒント: 表の属性の1つが主キーでもある場合、ユーザーが値を変更できないUIコンポーネントを選択します。 |
ヒント: ドロップダウン・メニューに表示されないコンポーネントを使用する場合は、このダイアログを使用して |
順序ボタンを使用した列の順序の変更。
「追加」アイコンを使用した列の追加。追加できる列の数に制限はありません。最初にアイコンをクリックすると、JDeveloperではダイアログの下部に新規列の行が追加され、そこにバインドされたコレクションの最初の属性の値が移入されます。後続の新規列には順序内の次の属性の値が移入され、その後も同様に続きます。
「削除」アイコンを使用した列の削除。
表をページにドロップした後は、プロパティ・インスペクタを使用して表に他の表示プロパティを設定できます。たとえば、表の幅を特定の割合またはサイズに設定できます。表示プロパティの詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「表、ツリーおよびその他のコレクションベースのコンポーネントの使用方法」を参照してください。
ヒント: 表の幅を100%に設定すると、表には境界が含まれないため、表の実際の幅はさらに大きくなります。コンテナの幅の100%に表を設定するには、プロパティ・インスペクタの「スタイル」セクションを展開し、「ボックス」タブを選択して |
ユーザーが表の情報を編集し、変更を保存できるようにするには、変更を発行して保存する方法を指定する必要があります。詳細は、23.3項「編集可能な表の作成」を参照してください。ユーザーによるデータ入力が可能な表の作成手順は、23.4項「入力表の作成」を参照してください。
「データ・コントロール」パネルから表をドロップすると、テキスト・フィールドまたはフォームをドロップするのと同じ効果があります。要約すると、Jdeveloperによって行われる処理は次のとおりです。
表のバインディングを作成し、ページ定義ファイルにそのバインディングを追加します。
UIコンポーネントに必要なコードをJSFページに追加します。
詳細は、22.2.2項「テキスト・フィールドの作成時の処理」を参照してください。
「データ・コントロール」パネルから表をドロップすると、ツリーの値バインディングが作成されます。ツリーはノードの階層で構成され、各サブノードは上位レベルのノードから分岐します。表の場合、フラット化された階層であり、各属性(列)は表のサブノードになります。フォームで使用される属性バインディングと同様で、ツリーの値バインディングによってイテレータ・バインディングが参照されると同時に、イテレータ・バインディングによってデータ・コレクションのイテレータが参照されるため、コレクションのデータ・オブジェクト全体の反復が円滑に行われます。属性ごとに異なるバインディングが作成されるのではなく、表ノードへのツリー・バインディングのみが作成されます。ツリー・バインディングでは、表の各行で表示または参照に使用する各属性の子要素が、nodeDefinition
要素のAttrNames
要素に含まれています。
ツリーの値バインディングは、FacesCtrlHierBinding
クラスのインスタンスです。このクラスは、コアのJUCtrlHierBinding
クラスを拡張して、次の2つのJSF固有のプロパティを追加します。
collectionModel
: JSFおよびADF Facesで表などのコレクション値コンポーネントに使用するjavax.faces.model.DataModel
オブジェクトを拡張するオブジェクトによってラップされたデータを戻します。
treeModel
: collectionModel
を拡張し、実質的に階層構造であるデータを戻します。詳細は、第24章「マスター/ディテール・データの表示」を参照してください。
例23-1に、Products
コレクションをドロップすると作成される表の値バインディングを示します。
例23-1 ページ定義ファイルにおける表の値バインディング・エントリ
<bindings> <tree IterBinding="ProductsIterator" id="Products"> <nodeDefinition DefName="oracle.fodemo.storefront.store.queries.ProductsVO"> <AttrNames> <Item Value="ProductId"/> <Item Value="SupplierId"/> <Item Value="CategoryId"/> <Item Value="ProductName"/> <Item Value="CostPrice"/> <Item Value="ListPrice"/> . . . </AttrNames> </nodeDefinition> </tree> </bindings>
データにアクセスする必要があるのは表のみであるため、(列または個々のセル内のテキスト・コンポーネントではなく)モデルにバインドする必要があるのは表コンポーネントのみです。表のツリー・バインディングは表の個々の構造化属性にドリルダウンするので、表の列は表コンポーネントからその情報を導出できます。
「データ・コントロール」パネルを使用してJSFページに表をドロップすると、表バインディングで指定された各属性に対するADF Facesのcolumn
コンポーネントが含まれたADF Facesのtable
コンポーネントがJDeveloperによって挿入されます。各列には、属性の値にバインドされた別のコンポーネント(inputText
コンポーネントやoutputText
コンポーネントなど)が含まれます。各列のヘッダーは、属性のコントロール・ヒントのlabels
プロパティにバインドされます。
ヒント: 関連するビューまたはエンティティ・オブジェクトで属性が非表示としてマークされている場合、対応するUIは作成されません。 |
例23-2に、Products
コレクションを読取り専用の表としてドロップして作成した表から抜粋した、簡略化されたコードを示します。
例23-2 ADF Faces表の簡略化されたJSFコード
<af:table value="#{bindings.Products.collectionModel}" var="row" rows="#{bindings.Products.rangeSize}" emptyText="#{bindings.Products.viewable ? 'No data to display.': 'Access Denied.'}" fetchSize="#{bindings.Products.rangeSize}" selectedRowKeys="#{bindings.Products.collectionModel.selectedRow}" selectionListener="#{bindings.Products.collectionModel.makeCurrent}" rowSelection="single" id="t1"> <af:column sortProperty="ProductId" sortable="true" headerText="#{bindings.Products.hints.ProductId.label}" id="c1"> <af:outputText value="#{row.ProductId}" id="ot1"/> </af:column> <af:column sortProperty="SupplierId" sortable="true" headerText="#{bindings.Products.hints.SupplierId.label}" id="c2"> <af:outputText value="#{row.SupplierId}" id="ot2"> <af:convertNumber groupingUsed="false" pattern="#{bindings.Products.hints.SupplierId.format}"/> </af:outputText> </af:column> <af:column sortProperty="CostPrice" sortable="true" headerText="#{bindings.Products.hints.CostPrice.label}" id="c3"> <af:outputText value="#{row.CostPrice}" id="ot3"> <af:convertNumber groupingUsed="false" pattern="#{bindings.Products.hints.CostPrice.format}"/> </af:outputText> </af:column> . . . </af:table>
ツリー・バインディングは、イテレータ・バインディングによって公開されたデータ全体を反復します。表の値は、collectionModel
オブジェクトにアクセスするcollectionModel
プロパティにバインドされています。表は、イテレータ・バインディングからの結果セットをcollectionModel
オブジェクト内にラップします。collectionModel
により、コレクションの各アイテムは、var
属性を使用して表コンポーネント内で使用できるようになります。
例では、表がProducts
イテレータ・バインディングの現在レンジの行全体を反復します。イテレータ・バインディングは、現在行の追跡を続行する行セット・イテレータにバインドします。表のvar
属性をrow
に設定すると、次のaf:outputText
タグの値に示すように、各列はrow
変数を使用して、表タグに示される現在行の現在データ・オブジェクトにアクセスします。
<af:outputText value="#{row.ProductId}"/>
行変数にバインドするかわりに、ADF表(ADF読取り専用表ではなく)をドロップすると、入力コンポーネントの値は、bindings
プロパティによってバインディング・コンテナ内の特定の行に暗黙的にバインドされます(例23-3を参照)。さらに、入力コンポーネントごとにバリデータ・コンポーネントとコンバータ・コンポーネントが追加されます。bindingsプロパティを使用すると、発生した例外を該当するバインド・オブジェクトにリンクできます。コントローラは、バインディング・コンテナ内のすべての例外を反復処理し、FacesMessage
オブジェクトの作成時にクライアントIDを取得するためのバインディング・オブジェクトを取得します。この取得により、特定のセルのエラーを表に表示できるようになります。この方法は、リストなどの選択コンポーネントを含め、すべての入力コンポーネントに使用されます。
例23-3 入力コンポーネントを使用したバリデータとコンバータの追加
<af:table value="#{bindings.Products.collectionModel}" var="row" rows="#{bindings.Products.rangeSize}" first="#{bindings.Products.rangeStart}" emptyText="#{bindings.Products.viewable ? 'No data to display.': 'Access Denied.'}" fetchSize="#{bindings.Products.rangeSize}" selectedRowKeys="#{bindings.Products.collectionModel.selectedRow}" selectionListener="#{bindings.Products.collectionModel.makeCurrent}" rowSelection="single" id="t1"> <af:column sortProperty="ProductId" sortable="true" headerText="#{bindings.Products.hints.ProductId.label}" id="c1"> <af:inputText value="#{row.bindings.ProductId.inputValue}" id="it1" <f:validator binding="#{row.bindings.ProductId.validator}"/> <af:convertNumber groupingUsed="false" pattern="#{bindings.Products.hints.ProductId.format}"/> </af:inputText> </af:column>
ADF Facesのバリデータとコンバータの使用方法の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「入力の検証および変換」を参照してください。
表23-1に、「データ・コントロール」パネルを使用して作成されるADF Faces表に対して、デフォルトで定義される他の属性を示します。
表23-1 ADF Faces表の属性と移入される値
属性 | 説明 | デフォルト値 |
---|---|---|
|
一度に表示する行数を決定します。 |
デフォルトで、関連付けられたイテレータ・バインディングの |
|
レンジの最初の行の索引(ベース0)。 |
関連付けられたイテレータ・バインディングの |
|
戻す行がない場合に表示するテキスト。 |
イテレータの表示可能なプロパティに評価されるEL式。表が表示可能で、戻すオブジェクトがない場合、「表示するデータがありません」と表示されます。表が表示できない場合(表に対して認可の制限が設定されている場合など)は、「アクセスが拒否されました」と表示されます。 |
|
データソースからフェッチされたデータの行数。 |
デフォルトで、関連付けられたイテレータ・バインディングの 表でのスクロール動作を向上させるため、表のイテレータ・バインディングが200超の項目で構成されるデータ・セットを管理すると想定され、ビュー・オブジェクトが範囲ページングを使用するように構成されている場合、イテレータは1つの範囲のみではなく範囲のセットを実際には戻します。範囲ページングの使用方法の詳細は、39.1.5項「範囲ページ移動を使用した大きい結果セットの効率的なスクロール」を参照してください。 |
|
表の選択の状態。 |
デフォルトでコレクション・モデルの選択された行に評価されるEL式。 |
|
選択したイベントをリスニングするメソッドへの参照。 |
デフォルトでコレクション・モデルの |
|
行が選択可能かどうかを決定します。 |
一度に1行のみ選択するには |
列の属性 |
||
|
列をソートする対象となるプロパティを決定します。 |
列の対応する属性バインディング値に設定します。 |
|
ソートできる列かどうかを決定します。 |
|
|
列の上部に表示されるテキストを決定します。 |
デフォルトで、対応する属性に設定されたラベルのコントロール・ヒントに評価されるEL式。 |
アプリケーションで表を使用し、ADFモデル・レイヤーで行選択を管理できるようにする場合、現在行はイテレータによって決定されます。ユーザーがADF Faces表で行を選択すると、表の行が影付きになり、選択された行がコンポーネントによりイテレータに通知されます。そのためには、例23-4
に示すように、表のselectedRowKeys属性をコレクション・モデルの選択した行にバインドします。
例23-4 表のselection属性
<af:table value="#{bindings.Products1.collectionModel}" var="row" . . . selectedRowKeys="#{bindings.Products.collectionModel.selectedRow}" selectionListener="#{bindings.Products.collectionModel. makeCurrent}" rowSelection="single">
このバインディングは、表の選択したキーをコレクション・モデルの選択した行にバインドします。selectionListener
属性は、コレクション・モデルのmakeCurrent
プロパティにバインドされます。このバインディングは、コレクションの選択した行をイテレータの現在行に設定します。
注意: カスタム選択リスナーを作成した場合、コレクション・モデル( |
表は選択を自動的に処理できますが、オブジェクトの現在行をイテレータにプログラムで設定する必要がある場合があります。
getKey()
メソッドをどのビュー行でコールしても、行を識別する1つ以上のキー属性をカプセル化するKey
オブジェクトを取得できます。Key
オブジェクトは、findByKey()
による行セット内のビュー行の検索にも使用できます。実行時に、setCurrentRowWithKey
またはsetCurrentRowWithKeyValue
のいずれかの組込み操作がデータ・バインディング・レイヤーによって名前で起動されると、findByKey()
メソッドを使用して、パラメータとして渡された値に基づいて行が検索された後、検索された行が現在の行として設定されます。
setCurrentRowWithKey
操作およびsetCurrentRowWithKeyValue
操作ではいずれもrowKey
という名前のパラメータが予想されますが、実行時にそのrowKey
パラメータに予想される値はそれぞれで異なります。
setCurrentRowWithKey
では、rowKey
パラメータ値に、ビュー行キーのシリアライズされた文字列表現が想定されています。これは、次のような16進エンコード文字列です。
000200000002C20200000002C102000000010000010A5AB7DAD9
キーのシリアライズされた文字列表現により、ブラウザのURL文字列またはフォーム・パラメータで単一値として渡すことができる方法で、ビュー行のキーを構成する可能性のあるすべてのキー属性がエンコードされます。実行時に、有効なシリアライズされた文字列キーではないパラメータ値を不注意に渡すと、oracle.jbo.InvalidParamException
またはjava.io.EOFException
などの例外を結果として受信する場合があります。Webページでは、ADFコントロール・バインディングのrowKeyStr
プロパティ(#{bindings.SomeAttrName.rowKeyStr}
など)またはADF Faces表の行変数(#{row.rowKeyStr}
など)を参照すると、行のシリアライズされた文字列キーの値にアクセスできます。
setCurrentRowWithKeyValue
操作では、rowKey
パラメータ値がビュー行のキーを表すリテラル値であると想定しています。たとえば、製品番号201
を検索する場合、この値は単に201
になります。
注意: アプリケーション・モジュール・クラスにカスタム・コードを記述し、クライアントから渡されたシリアライズされた文字列キーに基づいて行を検索する必要がある場合は、 static public Row getRowFromKey(RowSetIterator rsi, String sKey) 第1パラメータは、行を検索するビュー・オブジェクト・インスタンスです。第2パラメータは、キーのシリアライズされた文字列書式です。 |
ユーザーが表内の情報を編集し、その変更をデータソースにコミットできるようにする表を作成できます。そのためには、コレクション(またはデータ・コントロール自体)に関連付けられたデータ・レコードを変更できる操作を使用して、コマンド・ボタンを作成し、このボタンを表のツールバーに配置します。たとえば、Delete
操作を使用して、ユーザーが現在のレンジからレコードを削除できるボタンを作成します。または、組込みの「発行」ボタンを使用して、変更を送信できます。
重要なのは、これらの操作がADFキャッシュのオブジェクトに対してのみ実行されるという点です。ルート・データ・コントロール上でCommit
操作を使用して、任意の変更をデータソースに実際にコミットする必要があります。データ・コントロールのRollback
操作を使用して、キャッシュされたオブジェクトに対する任意の変更をロールバックします。ページが、バインド・タスク・フロー内のトランザクションの一部である場合、通常、タスク・フロー・リターン・アクティビティのトランザクションを解決するためにこの操作を使用します。詳細は、18.4項「トランザクションの管理」を参照してください。
編集可能なコンポーネントを使用してデータを表示することにした場合、一度にすべての行を変更可能として表示する表か、ユーザーが行内をダブルクリックするまですべての行を読取り専用として表示する表という選択肢があります。図23-3は、すべての行に編集可能フィールドがある表を示しています。ページは、ページに追加されたコンポーネント(inputText
、inputDate
およびinputNumberSpinbox
コンポーネントなど)を使用してレンダリングされます。
図23-4は、同じ表ですが、データを編集または入力するにはユーザーが行をダブルクリック(または行がすでに選択されている場合はシングルクリック)する必要があるように構成されています。図23-3と同じ入力コンポーネントを使用してページは作成されていますが、outputText
コンポーネントを使用して選択されていない行にデータを表示しています。これらのコンポーネントを実際にレンダリングしている行は、編集のために選択された行のみです。
ADF Facesの表コンポーネントによる編集の処理方法の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「表、ツリーおよびツリー表のデータの編集」の項を参照してください。
編集可能な表を作成するには、基本表の作成に類似した手順に従い、続いて操作にバインドされたコマンド・ボタンを追加します。ただし、表にツールバーを含めるには、表の作成に使用されたコレクションのアイテムとツールバーを関連付けるADF Facesコンポーネントを追加する必要があります。
編集可能な表を作成するには:
「データ・コントロール」パネルから、コレクションを選択します。
たとえば、システム内の製品を編集できる簡単な表をStoreFrontモジュールで作成するには、Products
コレクションを選択します。
コレクションをJSFページにドラッグし、ポップアップ・メニューから「ADF表」を選択します。
これにより、入力コンポーネントを使用して編集可能な表が作成されます。
次に表示される「表の列の編集」ダイアログを使用して、属性がどのように動作し、表の列としてどのように表示されるかを決定します。「行選択」チェック・ボックスを必ず選択することにより、ユーザーは編集する行を選択できます。
このダイアログを使用して表を構成する方法の詳細は、23.2.1項「基本表の作成方法」を参照してください。
構造ウィンドウで表を選択し、プロパティ・インスペクタの「動作」セクションを展開してEditingMode属性を設定します。全行を編集可能にする場合は、editAllを選択します。ユーザーに1行をクリックさせてその行を編集可能にする場合は、clickToEditを選択します。
構造ウィンドウで、表コンポーネントを右クリックし、ポップアップ・メニューから「囲む」を選択します。
「囲む」ダイアログでは、ドロップダウン・リストで「ADF Faces」が選択されていることを確認し、「パネル・コレクション」コンポーネントを選択して「OK」をクリックします。
panelCollection
コンポーネントのツールバー・ファセットによりツールバーが保持され、そのツールバーによりデータの更新に使用されるコマンド・コンポーネントが保持されます。
構造ウィンドウで、panelCollection
のtoolbarファセット・フォルダを右クリックし、ポップアップ・メニューから「ツールバーの内部に挿入」→「Toolbar」の順に選択します。
これにより、ユーザーが表の表示方法を変更できるデフォルトのメニューと、表全体の連結を解除する「連結解除」リンクをすでに含むツールバーが作成され、ブラウザ・ウィンドウの大部分を占めるように表示されます。panelCollection
コンポーネントの詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「表メニュー、ツールバーおよびステータス・バーの表示」の項を参照してください。
「データ・コントロール」パネルから操作の実行対象となるオブジェクトのコレクションに関連付けられている操作を選択し、構造ウィンドウのtoolbar
コンポーネントにドラッグします。これにより、データバインドされたコマンド・コンポーネントがツールバー内に配置されます。
たとえば、製品レコードを削除できるようにする場合は、Products
コレクションに関連付けられているDelete
操作をドラッグします。図23-5に、コレクションに関連付けられている操作を示します。
ポップアップ・メニューから「操作」→「ADFツールバー・ボタン」を選択します。
変更をキャッシュに送信する「送信」ボタンを作成するには、構造ウィンドウでツールバー・コンポーネントを右クリックし、「af:toolbarの内部に挿入」→「ツールバー・ボタン」の順に選択します。
ページが、バインド・タスク・フロー内のトランザクションの一部でない場合、ユーザーが変更をコミットまたはロールバックできるようにするためのボタンを作成する必要があります。「データ・コントロール」パネルから、ルートレベル・データ・コントロールに関連付けられたCommit
操作とRollback
操作をドラッグし、コマンド・ボタンまたはコマンド・リンクのいずれかとしてツールバーにドロップします。
図23-6に、StoreServiceAMDataControl
データ・コントロールのコミット操作とロール・バック操作を示します。
ページが、バインド・タスク・フロー内のトランザクションの一部である場合、タスク・フロー・リターン・アクティビティを作成する際のトランザクションを解決する値としてCommit
またはRollback
を入力します。詳細は、18.4項「トランザクションの管理」を参照してください。
編集可能な表の作成は、レコードの編集に使用するフォームの作成と類似しています。「データ・コントロール」パネルからドロップした操作に対してアクション・バインディングが作成されます。編集可能な表の作成時の処理の詳細は、22.4.2項「コマンド・ボタンの作成時の処理」を参照してください。
ユーザーが表に新しく空白行を挿入し、各列に値を追加することのできる表を作成できます(対応するエンティティ・オブジェクトまたはビュー・オブジェクトに設定されたデフォルト値は自動的に移入されます)。
入力表を作成する際に、現在の行セット内の他の行のコンテキストにある新しい空白行をユーザーに表示する必要があります。この挿入を可能にするには、フォームで使用するのと同様に、Create
操作ではなくCreateInsert
操作を使用する必要があります。CreateInsert
操作は、実際にはキャッシュのみではなく行セット内に新しい行を作成します。
ページ全体をリフレッシュするのではなく、他のコンポーネントとの対話に基づいて1つのコンポーネントをリフレッシュするようにADF Facesコンポーネントを設定できます。これは、部分ページ・レンダリングと呼ばれます。新規行を作成するためのボタンをユーザーがクリックしたときには、その新規行が表示されるように表をリフレッシュする必要があります。これを行うには、ユーザー・アクションに対応するよう表を構成する必要があります。
作業を始める前に、次のようにします。
23.3項「編集可能な表の作成」で説明しているように、編集可能な表を作成します。
表がバインド・タスク・フローの一部でない場合は、Commit
操作とRollback
操作にバインドされたボタンを必ず含めます。
入力表を作成するには:
「データ・コントロール」パネルから、ドロップされたコレクションに関連付けられたCreateInsert操作をドラッグし、ツールバー・ボタンとしてツールバーにドロップします。IDは、CreateInsertなどのわかりやすいものに変更できます。これによって、部分トリガーとして選択する際に識別しやすくなります。
構造ウィンドウで、表コンポーネントを選択します。プロパティ・インスペクタで「動作」セクションを展開します。
プロパティ・インスペクタで、PartialTriggers属性のドロップダウン・メニューをクリックし、「編集」を選択します。
「プロパティの編集」ダイアログで、panelCollection
コンポーネントのツールバー・ファセットを展開し、CreateInsert コマンド・コンポーネントを含むツールバーを展開します。そのコンポーネントを選択し、「選択済」パネルに移動します。「OK」をクリックします。これにより、表のリフレッシュがトリガーされるコンポーネントが設定されました。
CreateInsert
操作を使用して入力表を作成すると、JDeveloperによって次の処理が行われます。
コレクションのイテレータ・バインディング、CreateInsert
操作のアクション・バインディング、および表の属性バインディングの作成。CreateInsert
操作は、行セットに新しい行を作成します。Commit
操作およびRollback
操作を使用してコマンド・ボタンまたはリンクを作成した場合、JDeveloperではこれらの操作のアクション・バインディングも作成されます。
ADF Faces table
コンポーネント、column
コンポーネント、inputText
コンポーネント、および操作の場合はcommandButton
コンポーネントを使用した、JSFページへのコードの挿入。
例23-5に、Products
コレクションから作成された入力表のページ定義ファイルを示します(属性の中には、コレクションをドロップしたときに、「列の編集」ダイアログで削除されたものがあります)。
例23-5 入力表のページ定義コード
<executables> <iterator Binds="Products" RangeSize="25" DataControl="StoreServiceAMDataControl" id="ProductsIterator"/> </executables> <bindings> <tree IterBinding="ProductsIterator" id="Products"> <nodeDefinition DefName="oracle.fodemo.storefront.store.queries.ProductsVO"> <AttrNames> <Item Value="ProductId"/> <Item Value="ProductName"/> <Item Value="CostPrice"/> <Item Value="ListPrice"/> <Item Value="Description"/> <Item Value="CategoryName"/> <Item Value="CategoryDescription"/> <Item Value="ProductImageId"/> </AttrNames> </nodeDefinition> </tree> <action IterBinding="ProductsIterator" id="CreateInsert" RequiresUpdateModel="true" Action="createInsertRow"/> <action id="Commit" RequiresUpdateModel="true" Action="commitTransaction" DataControl="StoreServiceAMDataControl"/> <action id="Rollback" RequiresUpdateModel="false" Action="rollbackTransaction" DataControl="StoreServiceAMDataControl"/> </bindings>
例23-6に、CreateInsert
コマンド・ツールバー・ボタンを、表をリフレッシュするためのトリガーとして使用し、部分ページ・レンダリングを提供するJSFページに追加されたコードを示します。
例23-6 表のコマンド・ボタンに設定された部分ページ・トリガー
<af:form> <af:panelCollection id="pc1"> <f:facet name="menus"/> <f:facet name="toolbar"> <af:toolbar id="tb1"> <af:commandToolbarButton actionListener="#{bindings.CreateInsert.execute}" text="CreateInsert" disabled="#{!bindings.CreateInsert.enabled}" id="CreateInsert"/> <af:commandToolbarButton actionListener="#{bindings.Commit.execute}" text="Commit" disabled="false" id="ctb2"/> <af:commandToolbarButton actionListener="#{bindings.Rollback.execute}" text="Rollback" disabled="#{!bindings.Rollback.enabled}" immediate="true" id="ctb3"> <af:resetActionListener/> </af:commandToolbarButton> </af:toolbar> </f:facet> <f:facet name="statusbar"/> <af:table value="#{bindings.Products.collectionModel}" var="row" rows="#{bindings.Products.rangeSize}" emptyText="#{bindings.Products.viewable ? \'No data to display.\' : \'Access Denied.\'}" fetchSize="#{bindings.Products.rangeSize}" rowSelection="single" partialTriggers="CreateInsert" id="t1"> <af:column sortProperty="ProductId" sortable="false" headerText="#{bindings.Products.hints.ProductId.label}" id="c1"> <af:inputText value="#{row.ProductId}" simple="true" required="#{bindings.Products.hints.ProductId.mandatory}" columns="#{bindings.Products.hints.ProductId.displayWidth}" maximumLength="#{bindings.Products.hints. productId.precision}" id="it1"/> </af:column> . . . </af:table> </af:panelCollection> </af:form>
CreateInsert
操作にバインドされたボタンを起動すると、アクションが実行され、ページがレンダリングされることによりコレクションの新しいインスタンスが作成および挿入されます。ボタンは、表をリフレッシュするトリガーとして構成されているため、表の最上部に新しい空白行を表示して再描画されます。Commit
アクションにバインドされたボタンをユーザーがクリックすると、行セット内に作成された新しい行がデータベースに挿入されます。部分ページ・リフレッシュの詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の部分ページ・コンテンツのリフレッシュに関する項を参照してください。
表の列のソートが可能で、新規行を挿入する前にユーザーが列をソートした場合、新規行はソートされません。新規行を含めて列をソートするには、目的のソートとは逆の列ソートを行ってから再ソートする必要があります。これは、表で列がすでにソートされていると見なされるためで、最初から希望のソート順をクリックしても列には何の効果もあらわれません。
たとえば、ユーザーが列を昇順でソートし、その後行を新たに追加するとします。最初、その行は最上部に表示されます。もう一度昇順で列をソートするために最初から昇順をクリックすると、列がすでに昇順であると見なされ、表は再ソートされません。ユーザーは、降順でソートした後に昇順でソートする必要があります。
行を挿入すると、データが特定の列で特定の順に自動的にソートされるようにする場合、プログラムでコミット後にSortEvent
をキューに入れ、ソートを実行するハンドラを実装します。宣言的操作(Commit
操作など)への機能の追加に関するする詳細は、28.4項「宣言メソッドのオーバーライド」を参照してください。
Create
またはCreateInsert
操作を使用して新規行を宣言的に作成すると、次のコード行が実行されます。
// create a new row for the view object Row newRow = yourViewObject.createRow(); // mark the row as being "initialized", but not yet new newRow.setNewRowState(Row.STATUS_INITIALIZED);
ただし、CreateInsert
操作を使用している場合は、行を行セットに挿入する追加のコード行も実行されます。
// insert the new row into the view object's default rowset yourViewObject.insertRow(newRow);
行をエンティティベースのビュー・オブジェクトに作成すると、現在のアプリケーション・モジュールに関連付けられているTransaction
オブジェクトによって、その処理が即時に記録されます。ビュー行の後に作成された新規エンティティ行は、Transaction
の保留中の変更リストにすでに含まれています。作成された新規行は、初期化済状態であるとしてマーク付けされると、Transaction
の保留中の変更リストから削除され、エンド・ユーザーによるデータ値の入力がまだ行われていない空白行とみなされます。初期化済という用語が適切である理由は、基礎となるエンティティ・オブジェクトによって定義されたすべてのデフォルト値を使用して初期化された新規行がエンド・ユーザーに表示されるためです。初期化済の行のどの属性にもユーザーがデータを入力していない場合は、その行が存在していないかのように処理されます。トランザクションのコミット時には、その行がTransaction
の保留中の変更リストに含まれていないため、INSERT
文はその行に対して試行されません。
初期化済の行に1つ以上の属性が設定されると同時に、初期化済の状態から新規状態(Row.STATUS_NEW
)に自動的に遷移します。この時点で、基礎となるエンティティ行はTransaction
の保留中の変更リストに登録され、トランザクションの次回コミット時に新規行が永続的に保存されます。
注意: 多数の初期化済の行を作成してもその行にデータを移入しない手順をエンド・ユーザーが実行した場合、低速メモリー・リークが発生することがあります。ただし、新規状態に遷移しない初期化済の行で使用されるメモリーは、Java仮想マシンのガベージ・コレクタによって最終的に解放されます。 |
デフォルトでは、表コンポーネントをドロップして行選択を使用するように設定すると、ユーザーが単一行を選択できるように設定されます。表を変更してアプリケーションが同時に複数の行を処理できるようにすることで、ユーザーが[Ctrl]キーまたは[Shift]キーを使用して複数の行を選択できるようにすることが可能です。
図23-7の例はUpdateUserInfo
ページの住所タブを示しており、ログイン・ユーザーの現住所が表に表示されています。ユーザーは、複数の住所を選択して「削除」ツールバー・ボタンをクリックできます。このアクションにより、それらの住所がデータストアから削除されます。
ユーザーが複数の行を選択して操作できるようにするには、まず、rowSelection
属性をmultiple
に変更する必要があります。Fusion Webアプリケーションでは、操作(メソッドなど)は、イテレータによって追跡される現在のデータ・オブジェクトに作用します。rowSelection
属性がsingle
に設定されている場合(表の作成時に「表の列の編集」ダイアログで「行選択」チェック・ボックスを選択した場合のデフォルト設定)、表では現在のデータ・オブジェクトを選択済として表示できるほか、新たに選択された行をイテレータの現在のオブジェクトに設定することも可能です。後続のページでも同じイテレータが使用される場合(たとえば、ユーザーが行を選択してコマンド・ボタンをクリックし、オブジェクトを編集できるページに移動した場合)は、選択されたオブジェクトが表示されます。この選択およびナビゲーションが機能するのは、イテレータとコンポーネントが単一のオブジェクトと連動するためであり、異なるバインディング・コンテナ内の異なるイテレータ・バインディングが同じ行セット・イテレータにバインドされているという理由から、現在の行の概念は同じです。
一方、rowSelection
属性をmultiple
に設定した場合は、複数のオブジェクトが選択される可能性があります。ADFモデル・レイヤーには、"現在"に対する"選択済"という概念はありません。コンポーネント・インスタンスを取得し、選択された行を読み取り、選択の状態をバインディングに変換するモデル・レイヤーに、ロジックを追加する必要があります。そうすることで、選択された行に対するアクションをメソッドで実行できるようになります。
複数選択機能を追加するには、まず特定の表コンポーネントの属性を変更します。次に、マネージドBeanを使用して、選択された行を現在行になるように設定を処理します。
ヒント: 複数選択機能をツリーまたはツリー表に追加する場合は、同じ手順を実行できます。 |
作業を始める前に、次のようにします。
23.2項「基本表の作成」の説明に従って表を作成し、「行選択」チェック・ボックスが選択されていないことを確認します。
注意: 「行選択」チェック・ボックスが選択されていると、JDeveloperによって |
複数選択機能を追加するには:
構造ウィンドウで、表コンポーネントを選択し、次の属性をプロパティ・インスペクタで設定します。
行選択: multiple
ID: 表に選択するID
ページのマネージドBeanがまだ存在しない場合は、作成および登録します。選択されたすべての行に対して実行されるように、マネージドBeanを使用して、行選択を処理し、選択に対してロジック(選択された行の削除など)を実行します。マネージドBeanを作成する手順は、20.4項「Fusion WebアプリケーションでのマネージドBeanの使用」を参照してください。
表コンポーネントを表すマネージドBeanにプロパティを追加します。プロパティの値を手順1で設定した表のID値に設定し、例23-7に示すように、プロパティ・クラスをADF Facesの表コンポーネント・クラスになるように設定します。
例23-8に示すように、表のgetterメソッドとsetterメソッドをマネージドBeanに追加します。
例23-8 表コンポーネントのgetterメソッドとsetterメソッド
private RichTable _table1; public void setTable1(RichTable table1) { this.table1 = table1; } public RichTable getTable1() { return table1; }
ヒント: ADF Facesの表クラスをマネージドBeanにインポートする必要があります。例23-8のコードを追加した後で |
JSPページに戻り、構造ウィンドウで表コンポーネントを選択し、バインディング属性が手順3で作成した管理プロパティにバインドされるように設定します。例:
binding="#{myBean.table1}"
このバインディングにより、アプリケーションは表コンポーネント全体で動作します。binding
属性と、プログラムでオブジェクトへのアクセスを可能にする方法の詳細は、Sun社のWebサイト(http://www.oracle.com/technetwork/java/index.html
)のJava EE 5チュートリアルを参照してください。
ロジックを追加して、宣言的操作またはメソッドが選択された行セットに対して操作できるようにします。
例23-9に、updateUserInfo
ページの住所表から選択された行を削除するdeleteOnTable()
というメソッドを示します。
例23-9 イテレータでの複数行の削除
public void deleteOnTable(RichTable myTable) { RowKeySet rowKeySet = (RowKeySet) myTable.getSelectedRowKeys(); CollectionModel cm = (CollectionModel) myTable.getValue(); for (Object facesTreeRowKey : rowKeySet) { cm.setRowKey(facesTreeRowKey); JUCtrlHierNodeBinding rowData = (JUCtrlHierNodeBinding) cm.getRowData() rowData.getRow().remove(); } }
注意:
したがって、前述の例では、このコードを、 cm.setRowKey(facesTreeRowKey); JUCtrlHierNodeBinding rowData = (JUCtrlHierNodeBinding) cm.getRowData(); 次のコードで置き換えることができます。 JUCtrlHierNodeBinding rowData = (JUCtrlHierNodeBinding) cm.getRowData(facesTreeRowKey); |
「データ・コントロール」パネルを使用して表を作成したら、属性の削除、表示順序の変更、表示に使用されるコンポーネントの変更、コンポーネントの属性バインディングの変更ができます。新しい属性を追加したり、表を新規のデータ・コントロールに再バインドすることもできます。
「データ・コントロール」パネルを使用して作成された表は、次のような変更ができます。
行のラベルに対するバインディングの変更
UIコンポーネントがバインドされている属性の変更
属性にバインドされているUIコンポーネントの変更
表内の列の並替え
表内の列の削除
表への列の追加
選択とソート処理の有効化
表の属性を変更するには:
構造ウィンドウで、表コンポーネントを選択します。
プロパティ・インスペクタで、別のセクションを展開して表の属性を変更します。
バインディングを変更するかわりに、表がバインドされているオブジェクトを完全に変更できます。
表を再バインドするには:
構造ウィンドウで表を右クリックし、「別のADFコントロールに再バインド」を選択します。
「ADFコントロールにバインド」ダイアログで、表のバインド先とする新しいコレクションを選択します。表のバインディングを変更すると、すべての列のバインディングも変更されます。23.6.1項「表示される属性の変更方法」の手順に従って、これらのバインディングを変更できます。
ヒント: 既存の表の最上部に異なるビュー・オブジェクトをドラッグして表を再バインドすることもできます。 |
UIコンポーネントを移動または変更して単に属性の表示方法を変更すると、JSFページの対応するコードが変更されます。バインディング・エディタを使用してバインディングを追加または変更すると、JDeveloperによって、JSFページにコードが追加され、ページ定義ファイルに適切な要素が追加されます。