ヘッダーをスキップ
Oracle® Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド
11g リリース2(11.1.2.4.0)
B66719-05
  目次へ移動
目次

前
 
次
 

12 表およびツリーの使用

この章では、ADF FacesのtabletreeおよびtreeTableコンポーネントを使用して表およびツリーを表示する方法を説明します。アプリケーションでFusionテクノロジ・スタックを使用する場合は、データ・コントロールを使用して表とツリーを作成できます。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の「ADFによるデータバインドされた表の作成」および「マスター/ディテール・データの表示」の章を参照してください。

この章では、次の項目について説明します。

12.1 表、ツリーおよびツリー表について

構造化データは、ADF Facesの表コンポーネントを使用して、行と列で構成される表として表示できます。階層データは、ADF Facesのツリー・コンポーネントを使用してツリー構造として表示することも、ADF Facesのツリー表コンポーネントを使用して表形式で表示することもできます。図12-1に、ADF Facesの表およびツリー・コンポーネントを示します。

図12-1 ADF Facesの表およびツリー・コンポーネント

ADF Facesの表、ツリーおよびツリー表

ヒント:

表は使用しないが、同じスタンプ設定機能が必要な場合には、イテレータ・タグを使用できます。たとえば、元素周期表のリストを表示し、各元素に対して名前、原子番号、記号およびグループを表示するとします。次の例に示すように、イテレータ・タグを使用できます。

<af:iterator var="row" first="3" rows="3" varStatus="stat"     
             value="#{periodicTable.tableData}" >
  <af:outputText value="#{stat.count}.Index:#{stat.index} of
                                   #{stat.model.rowCount}"/>
  <af:inputText label="Element Name" value="#{row.name}"/>
  <af:inputText label="Atomic Number" value="#{row.number}"/>
  <af:inputText label="Symbol" value="#{row.symbol}"/>
  <af:inputText label="Group" value="#{row.group}"/>
</af:iterator>

各子には、必要に応じて何度でもスタンプ設定できます。反復は、first属性で指定された索引から開始され、row属性で指定された索引まで行われます。row属性が0に設定されている場合、反復は基礎となるデータにそれ以上要素がなくなるまで続けられます。


12.1.1 表およびツリーのユースケースと例

表、ツリーおよびツリー表は、構造化された情報の表示に使用されます。たとえば、図12-2に示すように、File Explorerアプリケーションの表タブでは、選択されたディレクトリのコンテンツの表示に表が使用されています。

図12-2 File Explorerアプリケーションの表コンポーネント

File Explorerの表コンポーネント

File Explorerアプリケーションのディレクトリなど、階層データ(親子関係のあるデータ)は、ツリー・コンポーネントを使用して展開可能なツリーとして表示できます。項目は、データの親子構造をミラー化するノードとして表示されます。各最上位レベル・ノードを展開して子ノードを表示でき、子ノードを展開してその子ノードを表示できます。展開された各ノードを縮小して、子ノードを非表示にできます。図12-3に、ツリー・コンポーネントを使用して表示されるFile Explorerアプリケーションのファイル・ディレクトリを示します。

図12-3 File Explorerアプリケーションのツリー・コンポーネント

ADF Facesのツリー・コンポーネント

ツリー表コンポーネントを使用して階層データを表示することもできます。ツリー表でも、展開および縮小可能な親子のノードを表示できますが、これは表形式で、ページにノードの属性値がデータの列として表示されます。たとえば、表コンポーネントを使用してディレクトリのコンテンツを表示するだけでなく、File Explorerアプリケーションには、図12-4に示すように、ツリー表コンポーネントを使用してコンテンツを表示する別のタブもあります。

図12-4 File Explorerアプリケーションのツリー表

ADF Facesのツリー表コンポーネント

ツリー・コンポーネント同様、ツリー表コンポーネントも、項目間の親子関係を表示できます。また、表コンポーネントと同じように、ツリー表コンポーネントでも列の項目の属性値を表示できます。ツリー表コンポーネントでも、表コンポーネントで使用可能なほとんどの機能を使用できます。

表、ツリーおよびツリー表をpanelCollectionコンポーネントで囲むことにより、ツールバーおよびステータス・バーを表に追加できます。上部のパネルには、メニューとメニュー・オプション、ツールバーとツールバー・ボタン、およびステータス・バーなど、メニュー・タイプのコンポーネントを保持するツールバーのみでなく、標準のメニュー・バーも含まれます。デフォルトで追加されているボタンおよびメニューもあります。たとえば、表、ツリーまたはツリー表をpanelCollectionコンポーネントで囲むと、「表示」メニューを含むツールバーが追加されます。このメニューには、表、ツリーまたはツリー表コンポーネントに固有のメニュー項目が含まれます。

図12-5に、panelCollectionコンポーネントを使用して作成されたツールバー、メニューおよびツールバー・ボタンのあるFile Explorerアプリケーションのツリー表を示します。

図12-5 パネル・コレクションを使用したTreeTable

ツールバーを保持するpanelCollection

12.1.2 表およびツリーの追加機能

表およびツリー・コンポーネントを実装する前に、他のADF Faces機能を理解することが役立つ場合があります。また、ページにツリーまたは表コンポーネントを追加した後で、検証やアクセシビリティなどの機能を追加することが必要になる場合があります。表およびツリー・コンポーネントで使用できる他の機能へのリンクを次に示します。

  • ツールバーのカスタマイズ: 表およびツリー表コンポーネントのメニュー、ツールバーおよびステータス・バーを提供するpanelCollectionコンポーネントに含まれるツールバーをカスタマイズできます。メニュー、ツールバー、ツールバー・ボタンの詳細は、第16章「メニュー、ツールバーおよびツールボックスの使用方法」を参照してください。

  • 表の幅のジオメトリ管理: 表が、子を拡大するコンポーネントの子である場合、この幅の設定はオーバーライドされ、表はコンテナに合うように自動的に拡大されます。コンポーネントが拡大される方法の詳細は、9.2.1項「ジオメトリ管理およびコンポーネントの拡大」を参照してください。

  • アクティブ・データ: アプリケーションでアクティブ・データを使用する場合は、データ・ソースのデータが変更されるたびに、表およびツリーのデータを自動的に更新できます。詳細は、第35章「非同期バックエンドでのアクティブ・データ・サービスの使用方法」を参照してください。


    注意:

    アクティブ・データを使用し、アプリケーションでADFビジネス・コンポーネントを使用する場合は、表が次の条件に適合する必要があります。

    • 表またはツリーが、単一の属性のみ含む同種データにバインドされていること。

    • 表でフィルタを使用しないこと。

    • ツリー・コンポーネントのnodeStampファセットに、単一のoutputTextタグが含まれ、他のタグが含まれていないこと。


  • イベント: 表およびツリー・コンポーネントでは、なんらかのロジックを実行することにより、アプリケーションを反応させることができるサーバー側およびクライアント側の両方のイベントを起動します。詳細は、第6章「イベントの処理」を参照してください。

  • 部分ページ・レンダリング: 表またはツリーをリフレッシュして、ページの別のコンポーネントで実行されたアクションに基づく新しいデータを表示できます。詳細は、5.3項「最適化されたライフサイクルの使用」を参照してください。

  • パーソナライズ: 列の並替えや列幅の変更など、ユーザーは実行時に表が表示される方法を変更できますが、アプリケーションがユーザーのカスタマイズを許可するように構成されていないかぎり、ユーザーがページを終了するとそれらの値は保持されません。詳細は、第32章「JSFページでのユーザー・カスタマイズの許可」を参照してください。

  • アクセシビリティ: 表およびツリー・コンポーネントをアクセス可能にできます。詳細は、第30章「アクセス可能なADF Facesページの開発」を参照してください。

  • 自動データ・バインディング: アプリケーションでFusionテクノロジ・スタックを使用する場合は、ADFビジネス・コンポーネントがどのように構成されているかに基づいて、バインドされた表およびツリーを自動的に作成できます。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「ADFによるデータバインドされた表の作成」および「マスター/ディテール・データの表示」の章を参照してください。

12.2 表およびツリーの共通機能

ツリーと表は、データの配信方法やデータの表示および編集方法など、多くの同じ機能を共有します。これらのコンポーネントを使用する前に、この共有機能と、その構成方法を理解することが重要です。

12.2.1 行およびノードへのデータの表示

表示される各レコード用に子コンポーネントを含め、それらのコンポーネントを個々のレコードにバインドするかわりに、表、ツリーおよびツリー表コンポーネントが完全なコレクションにバインドされ、各レコードの値にスタンプを設定することにより、1つのコンポーネント(outputTextコンポーネントなど)が繰り返しレンダリングされます。たとえば、表に子の列コンポーネントが2つ含まれるとします。各列には、出力コンポーネントを使用して行の単一の属性値が表示され、4つのレコードが表示されます。データを表示するために、2つの出力コンポーネントの4セットをバインドするかわりに、表自体が4つすべてのレコードのコレクションにバインドされ、1セットの出力コンポーネントが単純に4回スタンプ設定されます。各行にスタンプが設定されると、現在行のデータが表のvar属性にコピーされ、出力コンポーネントが行の正しい値を取得できるようになります。特に、クライアント・コンポーネントでスタンプ設定がどのように機能するかの詳細は、12.2.6項「クライアントの表、ツリーおよびツリー表コンポーネントへのアクセス」を参照してください。

例12-1に、var属性の値がrowである表のJSFコードを示します。値が変数の特定のプロパティにバインドされているため、列の各outputTextコンポーネントにより行のデータが表示されます。

例12-1 値へのアクセスにvar属性を使用する表のJSFコード

<af:table var="row" value="#{myBean.allEmployees}">
  <af:column>
    <af:outputText value="#{row.firstname}"/>
  </af:column>
  <af:column>
    af:outputText value="#{row.lastname}"/>
  </af:column>
</af:table>

12.2.2 コンテンツの配信

表、ツリーおよびツリー表コンポーネントは仮想化されており、サーバーのコンポーネントに存在するすべての行がクライアントに配信されて表示されるわけではありません。表、ツリーおよびツリー表を構成して、データ・ソースから一度に一定数の行をフェッチします。レンダリング時にすぐにデータをコンポーネントに配信することも(使用可能な場合)、コンポーネントのシェルがレンダリングされた後に遅延フェッチすることもできます(デフォルトでは、コンポーネントはデータが使用可能な場合にデータをフェッチします)。

即時配信では、データは初期リクエスト時にフェッチされます。遅延配信では、ページに表またはツリー・コンポーネントが1つ以上含まれる場合、ページでは最初は標準のライフサイクルが実行されます。ただし、最初のリクエスト時にデータがフェッチされるのではなく、特別な個別の部分ページ・レンダリング(PPR)リクエストが実行され、表のフェッチ・サイズの値として設定された行数が戻されます。ページのレンダリング直後であるため、レンダー・レスポンス・フェーズのみがコンポーネントに対して実行され、対応するデータのフェッチおよび表示が可能になります。ユーザーのアクションにより後続のデータ・フェッチが実行される場合(別の行セットのために表をスクロールするなど)、別のPPRリクエストが実行されます。

コンテンツが使用可能な場合に配信されるようにコンテンツ配信が構成されている場合、フレームワークでは初期リクエスト時にデータの可用性がチェックされ、使用可能な場合にはデータが表に送信されます。使用可能でない場合、データは遅延配信と同じように、別のPPRリクエスト時にロードされます。


注意:

アプリケーションでFusionテクノロジ・スタックが使用されない場合は、whenAvailableのサポートをCollectionModel実装に明示的に追加する必要があります。たとえば、Facesデモ・アプリケーションのWhenAvailableData.javaマネージドBeanを参照してください。

アプリケーションでFusionテクノロジ・スタックを使用する場合は、作成されたCollectionModel実装でこれらのAPIが自動的に使用されます。



パフォーマンスのヒント:

遅延配信は、データ・フェッチがコストの高い(低速な)操作と予想される場合、たとえば低速で待機時間の長いデータベース接続や、Webサービスなどの低速な非データベース・ソースからのデータのフェッチなどに使用する必要があります。ページに表、ツリーまたはツリー表以外のコンポーネントが複数含まれる場合も、遅延配信を使用する必要があります。遅延配信を使用すると、データが使用可能になる前に、初期ページのレイアウト・コンポーネントおよびその他のコンポーネントが最初にレンダリングされます。

即時配信は、表、ツリーまたはツリー表がページの唯一のコンテキストである場合、またはコンポーネントが大きなデータ・セットを返さないと予想される場合に使用する必要があります。この場合、ユーザー・レスポンス時間がより高速で、サーバーCPU利用率がより高ければ、2番目のリクエストはサーバーに移動しないため、レスポンス時間は遅延配信を使用する場合よりも高速になります(または、場合によっては高速に感じます)。ただし、フェッチ・ブロックとして構成された行数のみが最初に返されます。遅延配信と同様に、ユーザーのアクションが後続のデータ・フェッチの原因となる場合は、次の行セットが配信されます。

使用可能な場合、配信は、データが初期レンダリング時に使用可能な場合には即時を使用し、データが最初は使用可能でない場合は遅延にフォールバックするという追加の柔軟性を提供します。


クライアントに表示されるのは、ブラウザに表示される際にページに収まる行数のみです。ユーザーがコンポーネントを垂直にスクロールすると、行がさらにフェッチされます。コンポーネントを埋めるために1回でクライアントからサーバーにリクエストされる行数は、fetchSize属性により決定されます。デフォルト値は25です。そのため、表の高さが低ければ、フェッチ・サイズ25はコンポーネントを埋めるのに十分です。ただし、コンポーネントの高さが高い場合、サーバーからのデータのリクエストは複数回になります。そのため、fetchSize属性は大きな数に設定しておく必要があります。たとえば、表の高さが600ピクセルで、各行の高さが18ピクセルの場合、表を埋めるのに少なくとも45行必要です。fetchSizeが25の場合、表を埋めるために、表はサーバーに対してリクエストを2回実行する必要があります。この例では、フェッチ・サイズを50に設定します。

ただし、フェッチ・サイズを大きくしすぎると、サーバーとクライアントの両方に影響を与えます。サーバーでは、データ・ソースから必要以上に行がフェッチされ、時間とメモリー使用量が増加します。クライアント側では、それらの行の処理とコンポーネントへのアタッチに時間がかかります。

displayRow属性を使用して、最初に表示されるデータのセットを構成することもできます。デフォルトで、データ・ソースの最初のレコードが一番上の行またはノードに表示され、後続のレコードはそれより下の行またはノードに表示されます。また、ソースの最後のレコードを最初に表示するように、コンポーネントを構成することもできます。この場合、最後のレコードはコンポーネントの下の行またはノードに表示され、ユーザーは上にスクロールして先行するレコードを表示できます。また、選択した行を表示するように、コンポーネントを構成することも可能です。これは、ユーザーが表にナビゲートし、複数のパラメータに基づいて、特定の行がプログラムで選択される場合に便利です。選択された行を表示するように構成した場合、その行は表の先頭に表示され、ユーザーは上または下にスクロールして他の行を表示できます。


注意:

JavaScriptを使用して、表またはツリーを動的にサイズ変更することはできません。表、ツリーおよびツリー表の高さは初めてレンダリングされるときに設定され、JavaScript APIを使用して変更することはできません。


12.2.3 行の選択

rowSelection属性を使用して、表、ツリーおよびツリー表が行なし、単一行または複数行のいずれかになるように選択を構成できます。この設定により、選択した行に対してロジックを実行できます。たとえば、ユーザーが表の行またはツリーのノードを選択して、選択された行のデータが表示される別のページにナビゲートするコマンド・ボタンをクリックし、その値を編集できるようにするとします。

表、ツリーまたはツリー表の選択した行(またはノード)が変更されると、コンポーネントにより選択イベントが起動されます。このイベントにより、選択解除された行や選択された行が報告されます。コンポーネントにより選択が宣言的に処理される際、選択された行でロジックを実行する必要がある場合は、それらの行にアクセスしてロジックを実行するコードを実装する必要があります。これは、マネージドBeanの選択リスナー・メソッドで実行できます。詳細は、12.3.8項「表の選択された行でのアクションの実行について」を参照してください。


注意:

複数の選択を実行できるようにコンポーネントを構成した場合、ユーザーが行を1つ選択し、[Shift]キーを押して別の行を選択すると、間にあるすべての行が選択されます。この選択は、選択が複数のデータ・フェッチ・ブロックにまたがる場合でも保持されます。同様に、[Ctrl]キーを使用して、隣接していない行を選択することもできます。

たとえば、表が一度に25行のみフェッチするように構成されている場合に、ユーザーが100行選択すると、フレームワークにより選択が追跡されます。


12.2.4 表、ツリーおよびツリー表のデータの編集

表、ツリーまたはツリー表の実際のデータの表示に使用するコンポーネントを選択できます。たとえば、データを読取り専用にする場合は、データの表示にoutputTextコンポーネントを使用します。反対に、データを編集できるようにする場合にはinputTextコンポーネントを使用し、リストから選択する場合にはSelectOneコンポーネントを1つ使用します。これらのコンポーネントはすべて、列コンポーネントの子として配置されるか(表およびツリー表の場合)、nodeStampファセットに配置されます(ツリーの場合)。

値の編集が可能なコンポーネントを使用してデータを表示する場合、表、ツリーまたはツリー表で、すべての行を編集可能として一度に表示するか、現在アクティブな行以外のすべての行を読取り専用として表示するかを、editingMode属性を使用して選択できます。たとえば、図12-6に、行をすべて編集できる表を示します。ページは、ページに追加されたコンポーネント(inputTextinputDateおよびinputComboBoxListOfValuesコンポーネントなど)を使用してレンダリングされます。

図12-6 すべての行を編集できる表

表の各セルを編集できます

図12-7は同じ表(つまり、inputTextinputDateおよびinputComboBoxListOfValuesコンポーネントを使用してデータを表示する)を示していますが、この表はアクティブな行にのみ編集可能なコンポーネントが表示されるように構成されています。ユーザーは、別の行をクリックして編集可能にできます(一度に1行のみ編集可能になります)。ページを作成するために図12-6と同じ入力コンポーネントが使用されていても、編集可能でない行のデータの表示に、outputTextコンポーネントが使用されていることに注意してください。これらのコンポーネントを実際にレンダリングしている行は、アクティブな行のみです。

図12-7 表で一度に編集できるのは1行のみ

表で一度に編集できるのは1行のみです

現在アクティブな行は、表のactiveRowKey属性によって決定されます。デフォルトでは、この属性の値は表の最初に表示される行です。表(またはツリーやツリー表)がリフレッシュされると、アクティブな行が表示されていなければ、そのコンポーネントがスクロールしてアクティブな行が表示されます。ユーザーがコンテンツを編集するために行をクリックすると、その行がアクティブな行になります。

編集できる行(またはノード)を1つのみにする場合、ユーザーがある行(またはノード)から次の行へ移動し、一度に1行のデータを送信(および検証)すると、表(またはツリーやツリー表)ではPPRが実行されます。すべての行を編集できるようにする場合、現在表示されている行またはノードを超えてスクロールするなど、PPRが実行されるイベントが発生するとデータが送信されます。

編集可能なコンポーネントがすべて、クリックして編集するモードで表示されるわけではありません。たとえば、HTMLの入力要素を複数行表示するコンポーネントがこれに当たります。次のコンポーネントが含まれます。

  • SelectManyCheckbox

  • SelectManyListBox

  • SelectOneListBox

  • SelectOneRadio

  • SelectManyShuttle


パフォーマンスのヒント:

レンダリングおよびポストバック中のパフォーマンスを向上させるには、表での編集を1行のみに構成する必要があります。

出力コンポーネントは入力コンポーネントよりも少ないHTMLを生成するため、一度に1行のみ編集することを選択した場合、ページはより迅速に表示されます。また、クライアント・コンポーネントは読取り専用行に対して作成されません。表(またはツリーやツリー表)はユーザーがある行から次の行に移動したときにPPRを実行するため、その行のデータのみ送信されます。これにより、すべてのセルの編集を許可して一度に表のすべての行のすべてのデータを送信する表よりもパフォーマンスが向上します。単一行の編集のみ許可すると、単一行のデータのみが検証のために送信され、その行のエラーのみ表示されるため、検証もより直感的になります。


12.2.5 表、ツリーおよびツリー表でのポップアップ・ダイアログの使用

表、ツリーまたはツリー表は、ユーザーのアクションに基づいてポップアップ・ダイアログが表示されるように構成できます。たとえば、ユーザーがセルまたはノード上にマウスを置いた場合に、選択された行の一部のデータが表示されるようにポップアップ・ダイアログを構成できます。ユーザーが表やツリー表の行、またはツリーのノードを右クリックした場合のために、ポップアップ・メニューを作成することも可能です。また、表やツリー表では、ユーザーが特定の行ではなく、表の任意の場所を右クリックした場合のために、ポップアップ・メニューを作成できます。

すべての表、ツリーおよびツリー表には、contextMenuファセットが含まれます。ポップアップ・メニューをこのファセットに配置すると、ユーザーが行を右クリックした場合に、関連するメニューが表示されます。サーバーでポップアップ・メニューがフェッチされると、コンポーネントにより、ポップアップ・メニューが表示されている行に対しての現行性が自動的に確立されます。現行性の確立とは、表のモデルの現行行が、ポップアップ・メニューが表示されている行を指すことです。これを実現するには、表示されるたびにメニューをフェッチできるように、メニューが含まれるpopupコンポーネントのcontentDelivery属性がlazyUncachedに設定されている必要があります。


ヒント:

選択された行に基づいて、ポップアップ・メニューにコンテンツが動的に表示されるようにするには、ポップアップ・コンテンツの配信をlazyUncachedに設定します。また、現在行を取得し、その現在行に基づいてデータを表示できるマネージドBeanのメソッドにsetPropertyListenerタグを追加します。

<af:tree value="#{fs.treeModel}" 
         contextMenuSelect="false" var="node" ..>
  <f:facet name="contextMenu">
    <af:popup id="myPopup" contentDelivery="lazyUncached">
      <af:setPropertyListener from="#{fs.treeModel.rowData}"
               to="#{dynamicContextMenuTable.currentTreeRowData}"
               type="popupFetch" />
      <af:menu>
       <af:menu text="Node Info (Dynamic)">
         <af:commandMenuItem actionListener=
           "#{dynamicContextMenuTable.alertTreeRowData}" 
           text=
     "Name - #{dynamicContextMenuTable.currentTreeRowData.name}" />
         <af:commandMenuItem actionListener=
           "#{dynamicContextMenuTable.alertTreeRowData}" 
           text=
     "Path - #{dynamicContextMenuTable.currentTreeRowData.path}" />
         <af:commandMenuItem actionListener=
           "#{dynamicContextMenuTable.alertTreeRowData}" 
           text="Date -
     #{dynamicContextMenuTable.currentTreeRowData.lastModified}" />
       </af:menu>
    </af:menu>
  </af:popup>
  </f:facet>
...
</af:tree>

バッキングBeanのコードは次のようになります。

public class DynamicContextMenuTableBean
{
  ...
  public void setCurrentTreeRowData(Map currentTreeRowData)
  {
    _currentTreeRowData = currentTreeRowData;
  }
 
  public Map getCurrentTreeRowData()
  {
    return _currentTreeRowData;
  }
 
  private Map _currentTreeRowData;
}

表およびツリー表には、bodyContextMenuファセットが含まれます。メニューが含まれるポップアップをこのファセットに追加すると、ユーザーが特定の行ではなく、表をクリックした場合に表示されます。

ポップアップ・メニューの作成の詳細は、15.2項「ポップアップの宣言的な作成」を参照してください。

12.2.6 クライアントの表、ツリーおよびツリー表コンポーネントへのアクセス

ADF Facesでは、表、ツリーまたはツリー表のコンテンツはサーバーでレンダリングされます。次のような場合には、クライアントがサーバー上のそのコンテンツにアクセスする必要があります。

  • クライアント側のアプリケーション・ロジックが、行固有のコンポーネントの状態を読み取る必要がある場合。たとえば、行の選択の変更に応じて、ページ内のその他のコンポーネント(通常はメニュー項目やツールバー・ボタン)の無効化や表示の状態をアプリケーションで更新する必要がある場合です。このロジックは、スタンプ設定されたinputHiddenコンポーネントを使用してクライアントに送信される、行固有のメタデータに依存している場合があります。これを有効化するために、アプリケーションでは、スタンプ設定されたコンポーネントから行固有の属性値を取得できる必要があります。

  • クライアント側のアプリケーション・ロジックが、行固有のコンポーネントの状態を変更する必要がある場合。たとえば、表の行にあるスタンプ設定されたコマンド・リンクをクリックすると、同じ行のその他のコンポーネントの状態が更新される場合です。

  • ピアはコンポーネント・インスタンスにアクセスしてイベント処理動作を実行することが必要な場合があります(詳細は、4.1項「ADF Facesアーキテクチャの使用について」を参照してください)。たとえば、マウスのクリックに対してクライアント側アクション・イベントを配信するには、AdfDhtmlCommandLinkPeerクラスに、イベント・ソースとして機能するコンポーネント・インスタンスへの参照が必要です。コンポーネントでは、クライアント・リスナーや、イベント配信動作を制御するdisabledpartialSubmitなどの属性を含め、関連状態が保持されます。

ADF Facesフレームワークでは、クライアント側でELがサポートされないのみでなく、クライアントへの表モデル全体の送信もサポートされていないため、クライアント側のコードは、値にアクセスするようスタンプ設定されているコンポーネントに依存できません。各行で同じコンポーネント・インスタンスを再利用するかわりに、各行に新しいJavaScriptクライアント・コンポーネントが作成されます(どの行にもコンポーネントが1つ作成される必要があると仮定しています)。

そのため、クライアント上の行固有のデータにアクセスするには、それ自体がスタンプ設定されたコンポーネントを使用して値にアクセスする必要があります。クライアント側のデータ・モデルを使用せずにこれを実現するには、クライアント側の選択変更リスナーを使用します。詳細な手順は、12.11項「スタンプ設定を使用するコンポーネントからクライアント上の選択された値へのアクセス」を参照してください。

12.2.7 ジオメトリ管理と表、ツリーおよびツリー表コンポーネント

デフォルトでは、表、ツリーおよびツリー表は子を拡大するコンポーネント(たとえば、panelStretchLayoutコンポーネントの内部のpanelCollectionコンポーネント)に配置され、表、ツリーまたはツリー表は既存の領域に合せて拡大されます。ただし、列を表に合せて拡大するには、columnStretching属性を使用して、未使用の領域に合せて拡大される単一の列を指定する必要があります。そうしないと、表はできるだけ多くの行に合せて垂直にのみ拡大されます。図12-8に示すように列は拡大されません。

図12-8 表は拡大されるが列は拡大されない

拡大された表

子を拡大しないコンポーネント(たとえば、verticalに設定されたpanelGroupLayoutコンポーネントの内部のpanelCollectionコンポーネント)に配置される場合、デフォルトでは、図12-9に示すように、表の幅は300px(11pxフォント設定で300pxに換算される27.27em単位)に設定され、デフォルトのフェッチ・サイズは25行を返すように設定されます。

図12-9 表は拡大されない

表は拡大されない

子を拡大しないコンポーネントに表を配置する場合は、autoHeightRows属性を使用して、指定した行数より多く表示されないように表の高さを制御できます。この属性を正の整数に設定した場合、表の高さは行セットの数によって決定されます。その数値がfetchSize属性より大きい場合は、fetchSize属性の行数のみ返されます。autoHeightRowsを-1(デフォルト)に設定して、自動サイズ設定をオフにできます。

自動サイズ設定は、子を拡大するコンポーネントと拡大しないコンポーネントの両方で同じ表を使用する場合に役立つことがあります。たとえば、6列があり、12行を表示できる表があるとします。これを子を拡大するコンポーネントで使用する場合は、表を使用可能な領域に合せて拡大します。その表を、子を拡大しないコンポーネントで使用する場合は、表の高さを6行に"固定"できます。ただし、表の高さを設定した場合、その表は他のコンポーネントに配置されるときに拡大されません。この問題を解決するには、autoHeightRows属性を設定します。前述の例の表が、拡大されるコンポーネントに配置される場合、表は(autoHeightRows属性を無視して)拡大されます。拡大されないコンポーネントに配置される場合、表はautoHeightRows属性に対して設定された行数である6行の高さになります。

12.3 表コンポーネントの使用方法

表コンポーネントでは、CollectionModelクラスを使用して基礎となるコレクションのデータにアクセスします。このクラスは、JSF DataModelクラスを拡張し、行キーおよびソートのサポートを追加します。DataModelクラスでは、行は索引によって完全に識別されます。他のユーザーが行を追加したことにより、ある行を削除するユーザー・リクエストで異なる行が削除されてしまうなど、あるリクエストから次のリクエストまでに基礎となるデータが変更される場合、この識別方法が原因で問題が発生する可能性があります。これを回避するため、CollectionModelクラスは索引ではなく行キーに基づいています。

java.util.Listarrayおよびjavax.faces.model.DataModelなど、別のモデル・クラスも使用できます。これらのクラスのいずれかを使用する場合は、表コンポーネントにより、インスタンスがCollectionModelクラスに自動的に変換されますが、機能は追加されません。CollectionModelクラスの詳細は、http://myfaces.apache.org/trinidad/trinidad-1_2/trinidad-api/apidocs/index.htmlにあるMyFaces TrinidadのJavadocを参照してください。


注意:

アプリケーションでFusionテクノロジ・スタックを使用する場合は、データ・コントロールを使用して表を作成すると、コレクション・モデルが作成されます。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「ADFによるデータバインドされた表の作成」の章を参照してください。


表コンポーネントの直接的な子は、columnコンポーネントである必要があります。表示されるそれぞれの列コンポーネントは、表の個別の列として表示されます。列コンポーネントには、コンテンツやイメージの表示、またはその他の機能の提供に使用されるコンポーネントが含まれます。列コンポーネントで使用可能な機能の詳細は、12.3.1項「列および列データ」を参照してください。

各列の子コンポーネントは、その列の各行のデータを表示します。列では、子コンポーネントは行ごとには作成されませんが、表では各行のレンダリングにスタンプ設定機能が使用されます。各子には、行ごとに一度スタンプが設定され、これがすべての行に対して繰り返されます。各行にスタンプが設定されると、現在行のデータが、EL式を使用して特定可能なプロパティにコピーされます。このプロパティに使用する名前を、表のvarプロパティを使用して指定します。表のレンダリングが完了したら、このプロパティは削除されるか前の値に戻ります。

このスタンプ設定動作のため、一部のコンポーネントが列内で機能しない場合があります。入力および出力コンポーネントなど、大部分のコンポーネントは問題なく機能します。セル内に複数のコンポーネントを使用する必要がある場合は、それらをpanelGroupLayoutコンポーネントでラップします。表内の表など、それ自体がスタンプ機能をサポートしているコンポーネントはサポートされていません。実行時に値が動的に決定されるコンポーネントの使用方法の詳細は、12.3.9項「表の選択コンポーネント値の動的な決定について」を参照してください。

表にdetailStampファセットを使用して、オプションで表示または非表示にできるデータを指定できます。このファセットにコンポーネントを追加すると、表の各行に、展開および縮小するためのアイコンが付いた追加の列が表示されます。ユーザーがアイコンをクリックして開くと、図12-10に示すように、ファセットに追加されたコンポーネントが表示されます。

図12-10 オプションで表示可能な追加のデータ

縮小に設定された展開アイコン - 詳細は表示されない

ユーザーが開かれた状態のアイコンをクリックして閉じると、図12-11に示すように、コンポーネントが非表示になります。

図12-11 追加のデータを非表示にすることが可能

追加のデータを非表示にすることが可能

detailStampファセットの使用方法の詳細は、12.4項「表への非表示機能の追加」を参照してください。

12.3.1 列および列データ

列には、データの表示に使用されるコンポーネントが含まれます。前述したように、各項目の表示に必要な子コンポーネントは1つのみで、値は表のレンダリング時にスタンプ設定されます。列をソートすることも、列にフィルタ要素を含めることも可能です。ユーザーがフィルタに値を入力すると、フィルタに入力した値に一致するデータ・セットが戻されます。フィルタは、大文字と小文字を区別する、または大文字と小文字を区別しないように設定できます。これが許可されるように表が構成されている場合、ユーザーは列を並べ替えることもできます。列には、ヘッダー・ファセットとフッター・ファセットの両方があります。ヘッダー・ファセットは、列のヘッダー・テキスト属性のかわりに使用できるため、スタイル設定可能なコンポーネントを使用できます。フッター・ファセットは、列の下部に表示されます。たとえば、図12-12では、フッター・ファセットを使用して、2つの列の下部に合計が表示されています。戻された行数が表示可能な範囲を超えている場合、フッター・ファセットは表示されますが、ユーザーは最後の行までスクロールできます。

図12-12 列のフッター・ファセット

列のフッター・ファセット

12.3.2 表の書式設定

表コンポーネントには、ユーザーを支援する書式設定や視覚的な補助が多数用意されています。これらの機能を有効にし、どのように表示するかを指定できます。次の機能が含まれます。

  • 行の選択: デフォルトでは、ユーザーは実行時に行を選択できません。ページのその他の場所または別のページにおいて、行でアクションを実行するために、ユーザーが行を選択できるようにするには、rowSelection属性を設定して、表で行の選択を有効化します。表は、単一の行または複数の行を選択できるように構成できます。選択された行でプログラムを使用してアクションを実行する方法の詳細は、12.3.8項「表の選択された行でのアクションの実行について」を参照してください。

  • 表の高さ: 表の高さを絶対的(300ピクセルなど)に設定することも、autoHeightRows属性を使用して、一度に表示する行数に基づいて表の高さを決定することもできます。詳細は、12.2.7項「ジオメトリ管理と表、ツリーおよびツリー表コンポーネント」を参照してください。


    注意:

    表がpanelSplitterコンポーネントなどのレイアウト管理コンテナに配置されている場合、表はコンテナによりサイズ設定され、autoHeightRowsは適用されません。



    注意:

    JavaScriptを使用して、表を動的にサイズ変更することはできません。表の高さは初めてレンダリングされるときに設定され、JavaScript APIを使用して変更することはできません。


  • グリッド線: デフォルトで、ADF表コンポーネントには、水平および垂直の両方のグリッド線が描画されます。これらは、horizontalGridVisibleおよびverticalGridVisible属性を使用して個別に無効化できます。

  • バンディング: columnBandingInterval属性を使用して、行または列のグループが異なる背景色で交互に表示されます。これは、隣り合う行または列のグループを区別する際に役立ちます。デフォルトでは、バンディングは無効化されています。

  • 列グループ: 表の列は、列コンポーネントをネストさせることで、列グループにグループ化できます。各グループには、すべての列をリンクする独自の列グループ・ヘッダーを設定できます。

  • 編集可能セル: 表へのデータの表示に入力テキスト・コンポーネントを使用する場合は、すべてのセルを編集できるように表を構成することも、ユーザーが明示的にセルをクリックして編集するように構成することもできます。詳細は、12.2.4項「表、ツリーおよびツリー表のデータの編集」を参照してください。


    パフォーマンスのヒント:

    ユーザーがクリックした場合にのみセルの編集を可能にすると、表は最初はより早くロードされます。これは、表に大量のデータを表示する場合に便利です。


  • 列の拡大: 列の幅すべてを合せても表全体に満たない場合は、columnStretching属性を設定し、領域を埋めるために列を拡大するかどうか、拡大する場合はどの列を拡大するかを決定できます。列の最小の幅を設定して、表に多くの列があり、拡大を有効にする場合に、列が設定した最小幅より小さくならないようにすることができます。拡大する各列の幅の割合を設定して、列が拡大されたときに占める領域の量を決定することもできます。


    注意:

    列の最小幅の合計がビューポートの表示可能領域以上である場合、表はビューポートの外部に拡張され、ビューポートの外部にアクセスするためのスクロールバーが表示されます。



    パフォーマンスのヒント:

    列の拡大はデフォルトで無効化されています。この機能を有効化すると、複雑な表(データ量の多い表や、列がネストしている表など)に使用した場合には、クライアントのレンダリング時間のパフォーマンスに影響があります。



    注意:

    行ヘッダーとして構成された列または固定として構成された列は拡大されません。拡大すると、ユーザーが表のスクロール可能な本体にアクセスできなくなる可能性が高くなるためです。


  • 列の選択: ユーザーにデータの列の選択を許可できます。行の選択同様、単一の列または複数の列を選択できるように構成できます。columnSelectionListenerを使用して、新しい列がユーザーによって選択されたときに呼び出されるColumnSelectionEventに応答することもできます。このイベントにより、選択解除された列や選択された列が報告されます。

  • 列の並替え: ユーザーは、実行時に列ヘッダーをドラッグ・アンド・ドロップして列を並べ替えられます。デフォルトでは、列の並替えが許可されており、panelCollectionコンポーネントのメニュー項目で処理されます。詳細は、12.9項「表メニュー、ツールバーおよびステータス・バーの表示」を参照してください。

12.3.3 列の書式設定

各列コンポーネントにも、ユーザーを支援する書式設定や視覚的な補助が多数用意されています。これらの機能を有効にし、どのように表示するかを指定できます。次の機能が含まれます。

  • 列のソート: ユーザーが、指定された列を基準とし、sortable属性を使用して昇順または降順にコンテンツをソートできるよう列を構成できます。列ヘッダーの特別なインジケータにより、ユーザーは列がソート可能であることがわかります。

    ユーザーがアイコンをクリックして、前にソートされていない列をソートすると、列のコンテンツは昇順でソートされます。次に同じヘッダーをクリックすると、コンテンツは降順でソートされます。表をソートできるようにするには、基礎となるデータ・モデルでもソートがサポートされている必要があります。詳細は、12.3.7項「プログラムを使用した表の列のソートの有効化について」を参照してください。

  • コンテンツの位置合せ: align属性を使用して、列内のコンテンツをstart、end、left、rightまたはcenterに位置合せできます。


    ヒント:

    アプリケーションで複数の読み方向がサポートされている場合は、leftおよびrightではなく、startおよびendを使用します。


  • 列の幅: width属性を使用して、列の幅をピクセル単位の絶対値として指定できます。列を拡大可能として構成する場合、幅を割合として設定することもできます。

  • 行折返し: noWrap属性を使用し、行を越えて列のコンテンツを折り返すかどうかを定義できます。デフォルトでは、コンテンツは折り返されません。

  • 行ヘッダー: rowHeader属性を使用して、一番左の列を行ヘッダーに定義できます。その場合、一番左の列は列ヘッダーと同じ外観でレンダリングされますが、スクロールしてページから見えなくなることはありません。図12-13に、最初の列が行ヘッダーとして構成されている場合に部門を表示する表がどのように表示されるかを示します。

    図112-13 表の行ヘッダー

    表の行ヘッダー

    行ヘッダー列の使用を選択し、行を選択できるように表を構成した場合、ユーザーが行の上にマウスを置くと、行ヘッダー列には図12-14に示すような選択矢印が表示されます。

    図12-14 行ヘッダーの選択アイコン

    行ヘッダーの選択アイコンとしての矢印

複数選択が許可される表では、ユーザーはマウスをクリックして行ヘッダーをドラッグし、連続した行ブロックを選択できます。また、ユーザーが上または下にドラッグすると、表が垂直に自動スクロールします。


パフォーマンスのヒント:

行ヘッダーを使用すると表の複雑さが増し、パフォーマンスに悪影響が及ぶことがあります。



ヒント:

列の並替えや列幅の変更など、ユーザーは実行時に表が表示される方法を変更できますが、アプリケーションがユーザーのカスタマイズを許可するように構成されていないかぎり、ユーザーがページを終了するとそれらの値は保持されません。詳細は、第32章「JSFページでのユーザー・カスタマイズの許可」を参照してください。


12.3.4 ページへの表の表示方法

「ADF Faces Tableの作成」ダイアログを使用して、JSFページに表を追加できます。このダイアログは、表に必要な各列へのcolumnコンポーネントの追加にも使用できます。また、EL式を使用して基礎となるモデルまたはBeanに表をバインドできます。


注意:

アプリケーションでFusionテクノロジ・スタックを使用する場合は、データ・コントロールを使用して表を作成すると、バインディングが実行されます。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「ADFによるデータバインドされた表の作成」の章を参照してください。


ダイアログを完了して、表と列がページに追加されたら、プロパティ・インスペクタを使用して表または列の追加の属性を構成し、表イベントに対応するためにリスナーを追加できます。表のバインド先となるCollectionModelクラスを実装する必要があります。

始める前に:

属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、12.3項「表コンポーネントの使用方法」を参照してください。

他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、12.1.2項「表およびツリーの追加機能」を参照してください。

ページに表を表示する手順:

  1. コンポーネント・パレットで、「データ・ビュー」パネルから「表」をドラッグ・アンド・ドロップして「ADF Faces表の作成」ダイアログを開きます。

    ダイアログを使用して、既存のモデルに表をバインドします。表が有効なモデルにバインドされると、作成される列がダイアログにより自動的に表示されます。ダイアログを使用して列のheaderおよびvalue属性の値を編集し、データの表示に使用されるコンポーネントのタイプを選択します。または、手動で列を構成し、後日バインドすることもできます。ダイアログの使用方法の詳細は、[F1]を押すか「ヘルプ」をクリックします。


    注意:

    inputTextコンポーネントを使用してCharacter Large Object(CLOB)を表示する場合は、CLOBを文字列に変換するカスタム・コンバータを作成する必要があります。変換の詳細は、7.4項「カスタムJSFコンバータの作成」を参照してください。


  2. プロパティ・インスペクタで、「共通」セクションを開きます。すでに表をモデルにバインドしてある場合は、value属性を設定します。このセクションを使用して、表固有の次の属性を設定できます。

    • RowSelection: 行を選択可能にする場合に値を設定します。有効な値はnonesinglemultipleおよびmultipleNoSelectAllです。


      注意:

      ユーザーは、rowSelection属性がmultipleに設定され、その表に行ヘッダーも含まれている場合に、行ヘッダーの列ヘッダーをクリックして表のすべての行およびすべての列を選択できます。ユーザーがすべての列および行を選択できないようにするには、rowSelectionmultipleNoSelectAllに設定します。


      選択された行でプログラムを使用してアクションを実行する方法の詳細は、12.3.8項「表の選択された行でのアクションの実行について」を参照してください。

    • ColumnSelection: 列を選択可能にする場合に値を設定します。有効な値はnonesingleおよびmultipleです。

  3. 「列」セクションを開きます。「ADF Faces Tableの作成」ダイアログを使用して表をバインドしてある場合、これらの設定を完了する必要があります。このセクションを使用して、表のバインドの変更、各行のデータへのアクセスに使用される変数名の変更、および各列に使用される表示ラベルやコンポーネントの変更を実行できます。


    ヒント:

    リストされているコンポーネント以外のコンポーネントを使用する場合は、プロパティ・インスペクタで任意のコンポーネントを選択し、それを手動で変更します。

    1. 構造ウィンドウで、ダイアログで作成されたコンポーネントを右クリックします。

    2. ポップアップ・メニューから「変換」を選択します。

    3. リストから必要なコンポーネントを選択します。プロパティ・インスペクタを使用して、新しいコンポーネントを構成します。



    ヒント:

    列に複数のコンポーネントを表示する場合は、その他のコンポーネントを手動で追加し、それらをpanelGroupLayoutコンポーネントでラップします。これは次のように行います。

    1. 構造ウィンドウで、1つ目のコンポーネントを右クリックし、「前に挿入」または「後ろに挿入」を選択します。挿入するコンポーネントを選択します。

    2. デフォルトで、コンポーネントは縦に表示されます。1つの列内に複数のコンポーネントを隣接させて表示するには、[Shift]キーを押して、構造ウィンドウで両方のコンポーネントを選択します。選択内容を右クリックし、「囲む」を選択します。

    3. panelGroupLayoutを選択します。


  4. 「外観」セクションを開きます。このセクションを使用し、次に示す表固有の属性を設定して、表の外観を設定します。

    • Width: 表の幅を指定します。ピクセル数または割合で幅を指定できます。デフォルト設定は300ピクセルです。(columnStretching属性を使用して)列を拡大するように表を構成する場合は、幅を割合に設定する必要があります。


      ヒント:

      表が、子を拡大するコンポーネントの子である場合、この幅の設定はオーバーライドされ、表はコンテナに合うように自動的に拡大されます。コンポーネントの拡大方法の詳細は、12.2.7項「ジオメトリ管理と表、ツリーおよびツリー表コンポーネント」を参照してください。


    • ColumnStretching: 列の幅すべてを合せても表全体に満たない場合は、この属性を設定し、領域を埋めるために列を拡大するかどうか、拡大する場合はどの列を拡大するかも決定できます。


      注意:

      子を拡大するコンポーネントの中に表が配置されている場合、自動的に拡大されるのは表のみです。表に合うように列を拡大する場合、列の拡大は手動で構成する必要があります。



      注意:

      行ヘッダーとして構成された列または固定として構成された列は拡大されません。拡大すると、ユーザーが表のスクロール可能な本体にアクセスできなくなる可能性が高くなるためです。



      パフォーマンスのヒント:

      列の拡大はデフォルトで無効化されています。この機能を有効化すると、クライアントにおける複雑な表のレンダリング時間のパフォーマンスに影響する場合があります。


      列の拡大を次のいずれかの値に設定できます。

      • blank: 空の列を自動的に挿入して拡大する場合に使用します(表の幅全体が行の背景色になります)。

      • 名前が指定された列: 現在表にある列を拡大する列として選択できます。

      • last: 最後の列を、ウィンドウ内の使用されていない領域に合せて拡大する場合に使用します。

      • none: 何も拡大されないデフォルトのオプションです。パフォーマンスを最適化する場合に使用します。

      • multiple: 他の列が(拡大されない)幅にレンダリングされた後、width属性に割合値が設定されたすべての列がその割合に拡大されます。割合値は合計で加重されます。たとえば、これらの列のwidth属性を50%に設定した場合、各列は、他のすべての列がレンダリングされた後の残り領域の1/3を占めます。


      ヒント:

      列の幅は実行時に変更できますが、アプリケーションが変更の永続性を使用するように構成されていないかぎり、ユーザーがページを終了するとそれらの幅値は保持されません。変更の永続性の有効化および使用方法の詳細は、第32章「JSFページでのユーザー・カスタマイズの許可」を参照してください。


    • HorizontalGridVisible: 水平のグリッド線を描画するかどうかを指定します。

    • VerticalGridVisible: 垂直のグリッド線を描画するかどうかを指定します。

    • RowBandingInterval: 色のバンディングの目的で、連続する何行で行グループを形成するかを指定します。デフォルトでは、これは0に設定されており、すべての行が同じ背景色で表示されます。別の色を使用する場合は、これを1に設定します。

    • ColumnBandingInterval: 列のバンディングが行われる間隔を指定します。この値により、表の列バンディングの表示が制御されます。たとえば、columnBandingIntervalが1の場合、表内にバンディングされた列が交互に表示されます。

    • FilterVisible: 入力されたフィルタ基準に一致する行のみが表示されるように、表にフィルタを追加できます。フィルタ処理を許可するように表を構成する場合、大文字と小文字を区別する、または大文字と小文字を区別しないようにフィルタを設定できます。詳細は、12.5項「表でのフィルタ処理の有効化」を参照してください。

    • テキスト属性: アクセシビリティを目的とした表のサマリーや説明だけでなく、行を表示できない場合に表示されるテキストを決定するテキスト文字列を定義できます。

  5. 「動作」セクションを開きます。このセクションを使用し、次に示す表固有の属性を設定して、表の動作を構成します。

    • ColumnResizing: エンド・ユーザーが実行時に列の幅をサイズ変更できるようにするかどうかを指定します。disabledに設定した場合、列の幅はページがレンダリングされた後で設定され、ユーザーはそれらの幅を変更できません。


      ヒント:

      columnResizingtrueに設定されている場合、ユーザーは実行時に列幅の値を変更できますが、アプリケーションが変更の永続性を使用するように構成されていないかぎり、ユーザーがページを終了するとそれらの幅値は保持されません。変更の永続性の有効化および使用方法の詳細は、第32章「JSFページでのユーザー・カスタマイズの許可」を参照してください。


    • DisableColumnReordering: デフォルトでは、panelCollectionコンポーネントにデフォルトで含まれるメニュー・オプションを使用して、実行時に列を並べ替えられます。これは、ユーザーが列の順序を変更できないように変更できます。(panelCollectionコンポーネントには、表、ツリーおよびツリー表のデフォルトのメニューとツールバー・ボタンが用意されています。詳細は、12.9項「表メニュー、ツールバーおよびステータス・バーの表示」を参照してください。)


      注意:

      ユーザーは列の順序を変更できますが、アプリケーションがユーザーのカスタマイズを許可するように構成されていないかぎり、ユーザーがページを終了するとそれらの値は保持されません。詳細は、第32章「JSFページでのユーザー・カスタマイズの許可」を参照してください。


    • FetchSize: 各データ・フェッチで戻されるブロックのサイズを設定します。デフォルトは25です。


      ヒント:

      表に合せるには何行必要であるかを判断するには、表の高さを取得して各行の高さで割ることで、fetchSize属性の値を決定する必要があります。fetchSize属性の値が小さすぎると、表を埋めるためにサーバーと何度もやりとりすることになります。値が大きすぎると、サーバーでは、データ・ソースから必要以上に行がフェッチされ、時間とメモリー使用量が増加します。クライアント側では、それらの行の処理とコンポーネントへのアタッチに時間がかかります。詳細は、12.2.2項「コンテンツの配信」を参照してください。


    • ContentDelivery: データを送信するタイミングを指定します。contentDelivery属性がimmediateに設定されている場合、コンポーネントのレンダリングと同時にデータがフェッチされます。contentDelivery属性がlazyに設定されている場合は、後続のリクエスト中にデータがフェッチされてクライアントに送信されます。属性がwhenAvailable(デフォルト)に設定されている場合、レンダラはデータが使用可能かどうかをチェックします。使用可能な場合、コンテンツは即時に配信されます。使用可能でない場合は、遅延配信が使用されます。詳細は、12.2.2項「コンテンツの配信」を参照してください。

    • AutoHeightRows: 表が子を拡大しないコンポーネントに配置される場合に、表を特定の高さにサイズ変更するには、表に表示する最大行数を指定します。デフォルト値は-1です(何行であっても自動サイズ設定は行われません)。値を0に設定して、fetchSizeと同じ値にすることもできます。


      注意:

      autoHeightRows属性の設定について、次の点に注意してください。

      • inlineStyle属性に高さを指定しても効果はなく、autoHeightRowsの値でオーバーライドされます。

      • inlineStyle属性にmin-heightまたはmax-heightを指定することは推奨されず、autoHeightRows属性と互換性がありません。

      • コンポーネントが、panelSplitterなど、子を拡大するコンポーネントに配置される場合、そのコンポーネントはコンテナによってサイズ変更されます(自動サイズ変更は行われません)。詳細は、12.2.7項「ジオメトリ管理と表、ツリーおよびツリー表コンポーネント」を参照してください。


    • DisplayRow: 最初に表示される際に表に表示する行を指定します。使用可能な値は、表の上部に最初の行を表示する場合はfirst、表の下部に最後の行を表示する場合はlast(ユーザーが先行する行を表示するには上にスクロールする必要があります)、表で最初に選択された行を表示する場合はselectedです。


      注意:

      この属性が正常に機能するには、表モデルの合計の行数が把握されている必要があります。


    • DisplayRowKey: 最初に表示される際に表に表示する行キーを指定します。値が文字列ではない場合があるため、属性は宣言的にではなくプログラムで設定する必要があります。この属性を指定すると、displayRow属性がオーバーライドされます。


      注意:

      この属性が正常に機能するには、表モデルの合計の行数が把握されている必要があります。


    • EditingMode: 編集可能なコンポーネントに、すべての行を編集可能にするか(editAll)、ユーザーがクリックした場合に編集可能にするか(clickToEdit)を指定します。詳細は、12.2.4項「表、ツリーおよびツリー表のデータの編集」を参照してください。


      ヒント:

      clickToEditを選択した場合は、アクティブな行のみ編集できます。この行はactiveRowKey属性によって決定されます。デフォルトでは、表が最初にレンダリングされるときに、アクティブな行は最初に表示される行です。ユーザーが別の行をクリックすると、その行がアクティブな行になります。activeRowKey属性に別の値を設定することで、この動作を変更できます。


    • ContextMenuSelect: ポップアップ・メニューを開くために右クリックする際に、行を選択するかどうかを指定します。trueに設定すると、行が選択されます。ポップアップ・メニューの詳細は、第15章「ポップアップ・ダイアログ、メニューおよびウィンドウの使用方法」を参照してください。

    • FilterModel: filterVisibleとともに使用します。詳細は、12.5項「表でのフィルタ処理の有効化」を参照してください。

    • 様々なリスナー: 表で対応するイベントが起動された場合に実行されるメソッドにリスナーをバインドします。詳細は、第6章「イベントの処理」を参照してください。

  6. 構造ウィンドウで列を選択します。プロパティ・インスペクタで、「共通」セクションを開いて、列固有の次の属性を設定します。

    • HeaderText: 列のヘッダーに表示するテキストを指定します。outputTextコンポーネントを含むheaderファセットを追加する場合と等しい出力内容が生成されるため便利です。outputText以外のコンポーネントを使用する場合は、かわりに列のheaderファセットを使用する必要があります(詳細は手順11を参照してください)。headerファセットを追加すると、headerText属性の値は列ヘッダーにレンダリングされません。

    • Align: この列の配置を指定します。startendおよびcenterを使用して、左から右への文字表示でそれぞれ左揃え、右揃え、中央揃えにします。leftまたはrightの値は、左から右と右から左のどちらの文字表示であるかにかかわらず、左揃えまたは右揃えのセルが必要な場合に使用できます。デフォルト値はnullで、これはスキンに依存し、行のヘッダー列とデータ列の対比で異なることを示します。スキンの詳細は、第28章「スタイルおよびスキンを使用した外観のカスタマイズ」を参照してください。

    • Sortable: 列をソート可能にするかどうかを指定します。ソート可能な列には、クリックするとその列のプロパティで表がソートされるヘッダーがあります。列をソート可能にするには、sortable属性をtrueに設定し、この列のプロパティによるソートが、基礎となるモデルでサポートされている必要があることに注意してください。詳細は、12.3.7項「プログラムを使用した表の列のソートの有効化について」を参照してください。


      注意:

      列選択が有効になっている場合、列ヘッダーをクリックすると、列をソートするかわりに列が選択されます。この場合、列は昇順/降順ソート・インジケータをクリックすることでソートできます。


    • Filterable: 列をフィルタ処理可能にするかどうかを指定します。フィルタ処理可能な列には、列ヘッダーの上部にフィルタ・フィールドが配置されます。列をフィルタ処理可能にするには、この属性をtrueに設定し、表にfilterModel属性を設定する必要があることに注意してください。リーフ列のみがフィルタ処理可能で、フィルタ・コンポーネントは、列ヘッダーが存在する場合にのみ表示されます。この列のsortProperty属性は、filterModelクラスのfilterProperty属性のキーとして使用する必要があります。


      注意:

      フィルタ処理が有効化されている(filterable=true)列には、フィルタ基準入力フィールドとして使用する入力コンポーネントを指定できます。これを実行するには、列にフィルタ・ファセットを追加し、入力コンポーネントを追加します。詳細は、12.5項「表でのフィルタ処理の有効化」を参照してください。


  7. 「外観」セクションを開きます。このセクションを使用し、次に示す列固有の属性を使用して、列の外観を設定します。

    • DisplayIndex: 列の表示順序索引を指定します。列を並べ替えることが可能で、displayIndex属性に基づいて表に表示されます。displayIndex属性値が設定されていない列は、データ・ソースでの順序に基づいて最後に表示されます。親列の外にある子の列を並べ替えることはできないため、displayIndex属性はトップレベルの列にのみ適用されます。

    • Width: 列の幅を指定します。表で列の拡大を使用する場合は、幅の割合を入力する必要があります。

      列の拡大では、列の幅の割合が重みとして扱われます。たとえば、すべての列が50%の幅で、3つを超える列がある場合、各列には領域が均等に割り当てられますが、依然としてminWidth属性に設定された値が適用されます。

      割合としての幅は領域の実際の割合ではなく重みであるため、表で列の拡大がオンになっていて、1列のみが割合の幅で拡大されるものとしてリストされている場合、その列は、残りの列のピクセル幅で指定されていない、表の残り領域をすべて使用します。

    • MinimunWidth: 列幅の最低ピクセル数を指定します。ユーザーが列のサイズ変更を試行すると、この最小幅が強制されます。また、列がフレキシブルな場合にも、この最小幅より小さいサイズには縮小されません。ピクセル幅が定義されていて最小幅の方が大きい場合、最小幅は2つのうち小さい方の値になります。デフォルトで、最小幅は10ピクセルです。

    • ShowRequired: 対応する属性にデータが必要な場合に、列ヘッダーにアスタリスクを表示するかどうかを指定します。

    • HeaderNoWrapおよびNoWrap: コンテンツをヘッダーおよび列内で折り返すかどうかを指定します。

    • RowHeader: 列を表の行ヘッダーにする場合は、trueに設定します。


      パフォーマンスのヒント:

      行ヘッダーを使用すると表の複雑さが増し、パフォーマンスに悪影響が及ぶことがあります。


  8. 「動作」セクションを開きます。このセクションを使用し、次に示す列固有の属性を使用して、列の動作を構成します。

    • SortProperty: この列によって表示されるプロパティを指定します。これは、フレームワークによって列のデータのソートに使用されるプロパティです。

    • Frozen: スクロールする際に列がページから見えなくならないように、列を固定するかどうかを指定します。固定列までの表の列は、ヘッダーでロックされ、その他の列とともにスクロールされません。親を固定せずに子の列を単独で固定することはできないため、frozen属性はトップレベルの列にのみ適用されます。


      パフォーマンスのヒント:

      固定された列を使用すると表の複雑さが増し、パフォーマンスに悪影響が及ぶことがあります。


    • Selected: trueに設定すると、最初のレンダリング時に列が選択されます。

  9. 既存の表に列を追加するには、構造ウィンドウで表を右クリックし、ポップアップ・メニューから「表の中に挿入」「列」を選択します。

  10. 表にファセットを追加するには、表を右クリックしてポップアップ・メニューから「ファセット - 表」を選択し、追加するファセットのタイプを選択します。その後、ファセットに直接コンポーネントを追加できます。


    ヒント:

    ファセットに使用できる直接の子は1つのみです。ファセットに複数のコンポーネントを表示する場合は、まずグループ・コンポーネント(panelGroupLayoutなど)を挿入し、次にグループ・コンポーネントの子として複数のコンポーネントを挿入します。


  11. 列にファセットを追加するには、列を右クリックしてポップアップ・メニューから「ファセット - 列」を選択し、追加するファセットのタイプを選択します。その後、ファセットに直接コンポーネントを追加できます。


    ヒント:

    ファセットに使用できる直接の子は1つのみです。ファセットに複数のコンポーネントを表示する場合は、まずグループ・コンポーネント(panelGroupLayoutなど)を挿入し、次にグループ・コンポーネントの子として複数のコンポーネントを挿入します。


  12. 列にコンポーネントを子として追加し、データを表示します。

    コンポーネントの値は、表のvar属性および表示する属性の変数値セットにバインドする必要があります。たとえば、File Explorerアプリケーションの表では、var属性の値としてfileが使用されており、1列目に各行のファイル名が表示されています。そのため、ディレクトリ名の表示に使用される出力コンポーネントの値は、#{file.name}です。


    ヒント:

    列の直接の子が入力コンポーネントの場合は、その幅を列幅に適切な幅に設定してください。幅が親列にとって広すぎる大きさに設定されていると、ブラウザにより、テキスト入力カーソルが必要以上に大きく拡大され、隣接する列を隠してしまう可能性があります。たとえば、inputTextコンポーネントのサイズが80ピクセルで、その親列のサイズが20ピクセルに設定されている場合、その表の入力カーソルは、隣接する列のクリック可能領域を覆ってしまいます。

    入力コンポーネントが列の直接の子ではない場合に、サイズが自動的に設定されるようにするには、contentStyle="width:auto"を設定します。


12.3.5 ページに表を追加する場合の処理

JDeveloperを使用してページに表を追加すると、JDeveloperにより、各属性の列のある表が作成されます。表をモデルにバインドすると、列にはモデルの属性が反映されます。まだモデルにバインドしていない場合は、JDeveloperにより、デフォルト値を使用して列が作成されます。表作成ダイアログでの作業中に、または後からプロパティ・インスペクタを使用して、デフォルト値を変更(列の追加/削除、列ヘッダーの変更など)できます。

例12-2に、File Explorerアプリケーション内の表の省略形のページ・コードを示します。

例12-2 File Explorerアプリケーション内のADF Facesの表

<af:table id="folderTable" var="file"
          value="#{explorer.contentViewManager.
                                    tableContentView.contentModel}"
           binding="#{explorer.contentViewManager.
                                    tableContentView.contentTable}"
           emptyText="#{explorerBundle['global.no_row']}"
           rowselection="multiple"
           contextMenuId=":context1" contentDelivery="immediate"
           columnStretching="last"
           selectionListener="#{explorer.contentViewManager.
                              tableContentView.tableFileItem}"
           summary="table data">
  <af:column width="180" sortable="true" sortProperty="name"
             headerText="" align="start">
    <f:facet name="header">
      <af:outputText value="#{explorerBundle['contents.name']}"/>
    </f:facet>
    <af:panelGroupLayout>
      <af:image source="#{file.icon}"
                inlineStyle="margin-right:3px; vertical-align:middle;"
                shortDesc="file icon"/>
      <af:outputText value="#{file.name}" noWrap="true"/>
    </af:panelGroupLayout>
  </af:column>
  <af:column width="70" sortable="true"
             sortProperty="property.size">
    <f:facet name="header">
      <af:outputText value="#{explorerBundle['contents.size']}"/>
    </f:facet>
    <af:outputText value="#{file.property.size}" noWrap="true"/>
  </af:column>
...
  <af:column width="100">
    <f:facet name="header">
      <af:outputText value="#{explorerBundle['global.properties']}"/>
    </f:facet>
    <af:commandLink text="#{explorerBundle['global.properties']}"
                    partialSubmit="true"
                    action="#{explorer.launchProperties}"
                    returnListener="#{explorer.returnFromProperties}"
                    windowWidth="300" windowHeight="300"
                    useWindow="true"></af:commandLink>
  </af:column>
</af:table>

12.3.6 実行時の処理: データ配信

表を含むページがリクエストされ、コンテンツ配信がlazyに設定されている場合、ページでは最初は標準のライフサイクルが実行されます。ただし、そのリクエスト中にデータがフェッチされるのではなく、独立した特別なPPRリクエストが実行されます。ページのレンダリング直後であるため、レンダー・レスポンス・フェーズのみが実行され、対応するデータがフェッチおよび表示されます。ユーザーのアクションにより後続のデータ・フェッチが実行される場合(表のスクロールなど)、別のPPRリクエストが実行されます。図12-15に、2番目のPPRリクエスト中の表を含むページを示します。

図12-15 2番目のPPRリクエストでデータをフェッチする表

PPRリクエストでデータをフェッチする表

ユーザーがソート可能な列のヘッダーをクリックすると、tableコンポーネントによりSortEventイベントが生成されます。このイベントにはgetSortCriteriaプロパティがあり、それを基にして表をソートする必要のある条件が返されます。表は、基礎となるCollectionModelインスタンスにsetSortCriteria()メソッドをコールしてこのイベントに対応し、登録済の任意のSortListenerインスタンスをコールします。

12.3.7 プログラムを使用した表の列のソートの有効化について

表の列のソートを有効にできるのは、基礎となるモデルでソートがサポートされている場合のみです。モデルがCollectionModelインスタンスの場合は、次のメソッドを実装する必要があります。

  • public boolean isSortable(String propertyName)

  • public List getSortCriteria()

  • public void setSortCriteria(List criteria)

  • public java.util.Comparator getComparator(java.lang.String)

  • public void setCollator(java.lang.String, org.apache.myfaces.trinidad.model.SortableModel$Strength, org.apache.myfaces.trinidad.model.SortableModel$Decomposition)

  • public void setComparator(java.lang.String, java.util.Comparator)

詳細は、MyFaces TrinidadのWebサイト(http://myfaces.apache.org/trinidad/index.html)を参照してください。

基礎となるモデルがCollectionModelインスタンスではない場合、tableコンポーネントにより、どのプロパティがソート可能かを判断するために実際のデータが自動的に調査されます。java.lang.Comparableクラスを実装するデータがある列はソート可能です。この自動サポートは、CollectionModelに直接ソートをコーディングする(ソートをSQLのORDER BY句に変換するなど)ほど効率はよくありませんが、小規模なデータ・セットには十分です。


注意:

自動サポートは、1つの列のみソートします。複数列のソートはサポートされていません。


12.3.8 表の選択された行でのアクションの実行について

ユーザーは表の1行以上を選択し、それらの行に対してアクションを実行できます。

表の選択状態が変更されると、表により選択イベントが起動されます。selectionEventイベントは、選択解除された行と選択された行をレポートします。

表の選択イベントをリスニングするには、selectionListener属性を使用するか、addselectionListener()メソッドを使用して表にリスナーを追加して、表にリスナーを登録します。これにより、リスナーは選択された行にアクセスし、それらの行に対してアクションを実行できます。

現在の選択内容(選択された1行または複数の行)はRowKeySetオブジェクトで、表に対してgetSelectedRowKeys()メソッドをコールして取得できます。プログラムを使用して選択内容を変更するには、次のいずれかを実行します。

  • RowKeySetオブジェクトにrowKeyオブジェクトを追加するか、rowKeyオブジェクトを削除します。

  • 表に対してsetRowIndex()またはsetRowKey()メソッドをコールして、特定の行を現在行にします。その後、RowKeySetオブジェクトに対してadd()またはremove()メソッドをコールして、その行を選択内容に追加するか、選択内容から削除できます。

例12-3に、ユーザーが行を選択してから「削除」ボタンをクリックしてこれらの行を削除できる表の部分を示します。アクション・リスナーは、mybeanマネージドBeanのperformDeleteメソッドにバインドされています。

例12-3 行の選択

<af:table binding="#{mybean.table}" rowselection="multiple" ...>
  ...
</af:table>
<af:commandButton text="Delete" actionListener="#{mybean.performDelete}"/>

例12-4に、選択されたすべての行を反復し、それぞれにmarkForDeletionメソッドをコールするアクション・メソッドperformDeleteを示します。

例12-4 rowKeyオブジェクトの使用

public void performDelete(ActionEvent action)
{
  UIXTable table = getTable();
  Iterator selection = table.getSelectedRowKeys().iterator();
  Object oldKey = table.getRowKey();
  while(selection.hasNext())
  {
    Object rowKey = selection.next();
    table.setRowKey(rowKey);
    MyRowImpl row = (MyRowImpl) table.getRowData();
    //custom method exposed on an implementation of Row interface.
    row.markForDeletion();
  }
  // restore the old key:
  table.setRowKey(oldKey);
}
 
// Binding methods for access to the table.
public void setTable(UIXTable table) { _table = table; }
public UIXTable getTable() { return _table; }
private UIXTable _table;

12.3.9 表の選択コンポーネント値の動的な決定について

表にselectOneコンポーネントを使用する場合がありますが、各行でコンポーネントに異なる選択内容が表示される必要があります。そのため、実行時に項目のリストを動的に決定する必要があります。

個々の項目にスタンプを設定するにはforEachコンポーネントを使用する必要があると考える可能性がありますが、forEachCollectionModelインスタンスと連携しないため機能しません。また、表で使用されるようなコンポーネント管理のEL変数を使用するEL式にはバインドできません。forEachコンポーネントはJSFタグの実行ステップで関数を実行しますが、表では次に示すコンポーネントのエンコーディング・ステップで実行します。そのため、forEachコンポーネントは表の準備ができる前に実行され、反復関数は実行されません。

selectOneコンポーネントの場合、直接の子はitemsコンポーネントであることが必要です。itemsコンポーネントは行変数(<f:items value="#{row.Items}"/>など)に直接バインドできますが、こうすると、基礎となるモデルを変更できなくなります。

かわりに、例12-5に示すように、項目のリストを作成するマネージドBeanを作成します。

例12-5 項目のリストを戻すマネージドBean

public List<SelectItem> getItems()
{
   // Grab the list of items
   FacesContext context = FacesContext.getCurrentInstance();
   Object rowItemObj =  context.getApplication().evaluateExpressionGet(
      context, "#{row.items}", Object.class);
   if (rowItemObj == null)
     return null;
    // Convert the model objects into items 
   List<SomeModelObject> list =  (List<SomeModelObject>) rowItemObj;
   List<SelectItem> items = new ArrayList<SelectItem>(list.size());
   for (SomeModelObject entry : list)
   {
     items.add(new SelectItem(entry.getValue(), entry.getLabel());public
    }
    // Return the items
    return items;
}

例12-6に示すように、ページの1つのコンポーネントからリストにアクセスできます。

例12-6 JSFページからの項目へのアクセス

<af:table var="row">
  <af:column>
    <af:selectOneChoice value="#{row.myValue}">
      <f:Items value="#{page_backing.Items}"/>
    </af:selectOneChoice>
  </af:column>
</af:table>

12.4 表への非表示機能の追加

表にdetailStampファセットを使用して、表示または非表示にできるデータを指定できます。このファセットにコンポーネントを追加すると、表に、切替えアイコンが付いた追加の列が表示されます。ユーザーがアイコンをクリックすると、ファセットに追加されたコンポーネントが表示されます。ユーザーが再度切替えアイコンをクリックすると、コンポーネントが非表示になります。図12-16に、コンテンツがdetailStampファセットに追加された際に表示される追加の列を示します。


注意:

detailStampファセットを使用する表がスクリーン・リーダー・モードでレンダリングされると、そのファセットのコンテンツがポップアップ・ウィンドウに表示されます。アクセシビリティの詳細は、第30章「アクセス可能なADF Facesページの開発」を参照してください。


図12-16 detailStampファセットが表示されていない表

表示されていないdetailStampファセット

図12-17に、1行目のdetailStampファセットが表示されている同じ表を示します。

図12-17 表示されているdetailStampファセット

表示されているdetailStampファセット

ファセットのrendered属性にEL式を使用して、切替えアイコンと詳細を表示するかどうかを決定できます。たとえば、ショッピング・カート・ページでdetailStampファセットを使用して、ギフト・ラッピング情報を表示するとします。ただし、すべての注文アイテムにギフト・ラッピング情報があるわけではないため、注文アイテムに表示する情報がある場合にのみ切替えアイコンを表示します。表示する情報があるかどうかを決定するメソッドをマネージドBeanに作成し、rendered属性をそのメソッドにバインドできます。図12-18に、表示する情報がある行に対してのみアイコンが表示されている同じ表を示します。

図12-18 条件付きdetailStampファセット

すべての行に詳細インジケータが表示されるわけではない

注意:

列を固定できるように表を設定している場合、detailStampファセットを表示すると固定機能が働かなくなります。つまり、詳細が表示されている間、ユーザーは列を固定できません。


12.4.1 detailStampファセットの使用方法

detailStampファセットを使用するには、表示または非表示にするデータにバインドされているコンポーネントをファセットに挿入します。

始める前に:

属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、12.4項「表への非表示機能の追加」を参照してください。

他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、12.1.2項「表およびツリーの追加機能」を参照してください。

detailStampファセットを使用する手順:

  1. コンポーネント・パレットで、ファセットに表示するコンポーネントをdetailStampファセット・フォルダにドラッグします。図12-19に、構造ウィンドウのdetailStampファセット・フォルダを示します。

    図12-19 構造ウィンドウのdetailStampファセット

    構造ウィンドウのdetailStampファセット

    ヒント:

    構造ウィンドウにファセット・フォルダが表示されない場合は、表を右クリックして「ファセット - 表」詳細スタンプを選択します。


  2. 表示する属性が現在のレコードに固有の場合は、現在のレコードのデータの表示に表の変数が使用されるように、(単純にコンポーネントが属性にバインドされる)JSFコードを置き換えます。

    例12-7に、図12-17(選択した行の詳細が表示されている)に示されているdetailStampファセットの表示に使用された省略形のコードを示します。

    例12-7 detailStampファセットのコード

    <af:table rowSelection="multiple" var="test1"
              value="#{tableTestData}"
      <f:facet name="detailStamp">
        <af:panelFormLayout rows="4" labelWidth="33%" fieldWidth="67%"
                            inlineStyle="width:400px">
        <af:inputText label="Name" value="#{test1.name}"/>
          <af:group>
            <af:inputText label="Size" value="#{test1.size}"/>
            <af:inputText label="Date Modified" value="#{test1.inputDate}"/>
            <af:inputText label="Created by"/>
          </af:group>
        </af:panelFormLayout>
      </f:facet>
    </af:table>
    
  3. detailStampファセットにそのアイコンとコンポーネントを条件付きで表示する場合は、ファセットのrendered属性を、ファセットをレンダリングする必要があるかどうかを決定するマネージドBeanのメソッドに設定します。


注意:

アプリケーションでFusionテクノロジ・スタックを使用する場合、データ・コントロールから属性をドラッグし、detailStampファセットにドロップできます。コードを変更する必要はありません。


12.4.2 実行時の処理: 行データの表示

ユーザーが行の詳細を表示または非表示にすると、表によりrowDisclosureEventイベントが生成されます。このイベントは、詳細を切り替える(開くまたは閉じる)ように表に指示します。

rowDisclosureEventイベントには関連付けられたリスナーがあります。表のrowDisclosureListener属性は、マネージドBeanのメソッドにバインドできます。このメソッドは、必要な後処理を実行するためのrowDisclosureEventイベントへのレスポンスとして起動されます。

12.5 表でのフィルタ処理の有効化

値がフィルタに一致する行のみを表に表示するために使用できるフィルタを表に追加できます。有効化されて、表示に設定されている場合、検索可能な各列の上に検索条件入力フィールドが表示されます。

たとえば、図12-20の表は、Locationの値が1700である行のみを表示するようにフィルタ処理されています。

図12-20 フィルタ処理された表

フィルタ処理された表には問合せに一致する行のみが表示されています

フィルタ処理された表の検索は例による問合せに基づいており、QBEテキストまたは日付入力フィールド書式を使用します。検索基準を変更するための><などの演算子の文字を入力できるようにするため、入力バリデータは無効になっています。たとえば、数値列の検索条件として>1500を入力できます。ワイルドカード文字もサポートされています。検索は、大文字と小文字を区別する、または大文字と小文字を区別しないようにできます。列でQBEがサポートされていない場合、検索条件入力フィールドはその列にレンダリングされません。

フィルタ処理機能では、データを表にフィルタ処理するためのモデルが使用されます。表のfilterModel属性オブジェクトは、FilterableQueryDescriptorクラスのインスタンスにバインドする必要があります。


注意:

アプリケーションでFusionテクノロジ・スタックを使用する場合は、データ・コントロールを使用して表を作成すると、フィルタ処理が作成されます。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「ADFによるデータバインドされた表の作成」の章を参照してください。


例12-8では、フィルタ入力フィールドを有効にするために表のfilterVisible属性がtrueに設定されていて、filterModelインスタンスの列を識別するために列にsortProperty属性が設定されています。各列要素では、filterable属性がtrueに設定されています。

例12-8 フィルタ処理が有効にされている表コンポーネント

<af:table value="#{myBean.products}" var="row"
               ...
          filterVisible="true"
               ...
          rowselection="single">
               ...
  <af:column sortProperty="ProductID" filterable="true" sortable="true"
    <af:outputText value="#{row.ProductID}">
               ...
  </af:column>
  <af:column sortProperty="Name" filterable="true" sortable="true"
    <af:outputText value="#{row.Name}"/>
               ...
  </af:column>
  <af:column sortProperty="warehouse" filterable="true" sortable="true"
    <af:outputText value="#{row.warehouse}"/>
               ...
  </af:column>
</af:table>

12.5.1 表へのフィルタ処理機能の追加方法

表にフィルタ処理機能を追加するには、まずフィルタ処理機能を提供するクラスを作成します。次に表をそのクラスにバインドし、フィルタ処理機能を使用するよう表と列を構成します。フィルタ処理機能を使用する列では、headerText属性に値が設定されているか、headerファセットにコンポーネントが含まれている必要があります。これにより、フィルタ・コンポーネントが表示されます。また、filterModelクラスではsortProperty属性が使用されるため、列もソート可能に構成されている必要があります。

始める前に:

属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、12.5項「表でのフィルタ処理の有効化」を参照してください。

他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、12.1.2項「表およびツリーの追加機能」を参照してください。

表にフィルタ処理機能を追加する手順:

  1. FilterableQueryDescriptorクラスのサブクラスであるJavaクラスを作成します。このクラスの詳細は、ADF Faces Javadocを参照してください。

  2. 12.3項「表コンポーネントの使用方法」の説明に従って表を作成します。

  3. 構造ウィンドウで表を選択し、プロパティ・インスペクタで次の属性を設定します。

    • FilterVisible: 検索可能な列の上にフィルタ条件入力フィールドを表示する場合はtrueに設定します。

    • FilterModel: 手順1で作成したFilterableQueryDescriptorクラスのインスタンスにバインドします。


    ヒント:

    フィルタにinputTextコンポーネント以外のコンポーネント(inputDateコンポーネントなど)を使用する場合は、filterVisibletrueに設定するかわりに、filterファセットに必要なコンポーネントを追加できます。これは次のように行います。

    1. 構造ウィンドウで、フィルタ処理する列を右クリックし、「af:columnの中に挿入」「JSF Core」フィルタ・ファセットを選択します。

    2. コンポーネント・パレットから、コンポーネントをファセットにドラッグ・アンド・ドロップします。

    3. コンポーネントの値を、手順1で作成したFilterableQueryDescriptorクラス内の対応する属性に設定します。値では、次の例のように、行に使用される変数を考慮する必要があります。

      #{af:inputDate label="Select Date" id="name"
                           value="row.filterCriteria.date"}
      

  4. 構造ウィンドウで表の列を選択し、プロパティ・インスペクタで表の各列に対して次の設定を行います。

    • Filterable: trueに設定します。

    • FilterFeatures: caseSensitiveまたはcaseInsensitiveに設定します。指定されない場合、大文字と小文字の区別はモデルによって決定されます。

12.6 ツリーへのデータの表示

ADF Facesツリー・コンポーネントには、組織図や階層ディレクトリ構造などの階層データが表示されます。これらのタイプのデータには一連の最上位レベル・ノードがある場合があり、構造内の各要素は他の要素を含むように拡張できます。たとえば、組織図では、階層内の各要素(つまり各従業員)がいくつかの子要素(直属の部下)を持つ場合があります。ツリー・コンポーネントでは、複数のルート要素がサポートされます。データは構造を表す形式で表示され、各要素が適切なレベルにインデントされて階層内での適切なレベルを示し、その親に接続されます。ユーザーは、階層の一部を展開および縮小できます。図12-21に、File Explorerアプリケーションのディレクトリの表示に使用されたツリーを示します。

図12-21 File Explorerアプリケーションのツリー・コンポーネント

ADF Facesのツリー・コンポーネント

ADF Facesのツリー・コンポーネントでは、基礎となる階層のデータにアクセスするためのモデルを使用します。特定のモデル・クラスはoracle.adf.view.rich.model.TreeModelで、12.3項「表コンポーネントの使用方法」で説明されているように、CollectionModelを拡張します。

ツリーをサポートする独自のツリー・モデルを作成する必要があります。ツリー・モデルは行のコレクションです。現在行に子の行が含まれている場合にtrueを返すisContainer()メソッドがあります。現在行の子にアクセスするには、enterContainer()メソッドをコールします。このメソッドをコールすると、TreeModelインスタンスが子の行のコレクションに変わります。親のコレクションに戻すには、exitContainer()メソッドをコールします。

例12-9に示すように、TreeModelクラスの作成時には、org.apache.myfaces.trinidad.model.ChildPropertyTreeModelクラスが便利です。

例12-9 TreeModelの作成

List<TreeNode> root = new ArrayList<TreeNode>();
for(int i = 0; i < firstLevelSize; i++)
{
  List<TreeNode> level1 = new ArrayList<TreeNode>();
  for(int j = 0; j < i; j++)
  {
    List<TreeNode> level2 = new ArrayList<TreeNode>();
    for(int k=0; k<j; k++)
    {
      TreeNode z = new TreeNode(null, _nodeVal(i,j,k));  
      level2.add(z);
    }
    TreeNode c = new TreeNode(level2, _nodeVal(i,j));
    level1.add(c);
  }
  TreeNode n = new TreeNode(level1, _nodeVal(i));
  root.add(n);
}
ChildPropertyTreeModel model = new ChildPropertyTreeModel(root, "children");
private String _nodeVal(Integer... args)
{
  StringBuilder s = new StringBuilder();
  for(Integer i : args)
    s.append(i);
  return s.toString();
}

注意:

アプリケーションでFusionテクノロジ・スタックを使用する場合は、データ・コントロールを使用してツリーを作成すると、モデルが作成されます。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「マスター/ディテール・データの表示」の章を参照してください。


ツリーは、表の操作と同じような方法で操作できます。次の操作を実行できます。


注意:

JavaScriptを使用して、ツリーを動的にサイズ変更することはできません。ツリーの高さは初めてレンダリングされるときに設定され、JavaScript APIを使用して変更することはできません。


表と同様、ツリーでも、個々のノードのコンテンツを表示するためにスタンプ設定機能が使用されます。ツリーには、各ノードのデータの表示に使用されるコンポーネントのホルダーであるnodeStampファセットが含まれます。各ノードが一度ずつ、すべてのノードで繰り返しレンダリング(スタンプ設定)されます。各ノードにスタンプが設定されると、現在のノードのデータが、EL式を使用して特定可能なプロパティにコピーされます。このプロパティに使用する名前を、ツリーのvarプロパティを使用して指定します。ツリーのレンダリングが完了したら、このプロパティは削除されるか前の値に戻ります。

このスタンプ設定動作のため、ADF Facesツリーで子としてサポートされるのは、特定タイプのコンポーネントのみです。動作が設定されていないすべてのコンポーネントは、大部分がValueHolderまたはActionSourceインタフェースを実装するコンポーネントとしてサポートされています。

例12-10では、ツリーに表示されるデータを識別する変数nodeを使用して各要素のデータを参照しています。nodeStampファセットは、node変数からさらにプロパティを取得して、各要素のデータを表示します。

例12-10 ツリーへのデータの表示

<af:tree var="node">
  <f:facet name="nodeStamp">
    <af:outputText value="#{node.firstname}"/>
  </f:facet>
</af:tree>

ツリーにもpathStampファセットが含まれます。このファセットは、nodeStampファセットがツリーのコンテンツのレンダリング方法を決定するのと同じように、「階層セレクタ」ダイアログのコンテンツのレンダリング方法を決定します。「階層セレクタ」ポップアップではユーザー入力が許可されないため、pathStampファセットの内部のコンポーネントは、単純なoutputTextimageおよびoutputFormattedタグの組合せにすることができ、入力コンポーネント(EditableValueHolderコンポーネント)にすることはできません。このファセットが提供されていない場合、「階層セレクタ」アイコンはレンダリングされません。

たとえば、pathStampファセットにイメージおよびoutputTextコンポーネントを含めると、ツリーにより、「階層セレクタ」ダイアログの各ノード・レベルにイメージとoutputTextコンポーネントがレンダリングされます。値へのアクセスには同じEL式を使用します。たとえば、outputTextコンポーネントのパスの各ノードに名前を表示する場合、EL式は<af:outputText value="#{node.firstname}"/>になります。


ヒント:

panelCollectionコンポーネントにより作成されたデフォルトのツールバー・ボタンの動作方法の決定には、pathStampファセットも使用されます。ボタンを使用する場合は、ノード値にバインドされたコンポーネントを追加します。panelCollectionコンポーネントの使用方法の詳細は、12.9項「表メニュー、ツールバーおよびステータス・バーの表示」を参照してください。


12.6.1 ツリーへのデータの表示方法

ツリーを作成するには、ページにツリー・コンポーネントを追加し、表示および動作プロパティを構成します。

始める前に:

属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、12.6項「ツリーへのデータの表示」を参照してください。

他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、12.1.2項「表およびツリーの追加機能」を参照してください。

ページにツリーを追加する手順:

  1. 例12-9に示すように、org.apache.myfaces.trinidad.model.TreeModelクラスを拡張するJavaクラスを作成します。

  2. コンポーネント・パレットで、「データ・ビュー」パネルから「ツリー」をドラッグ・アンド・ドロップしてツリーの挿入ダイアログを開きます。必要に応じてツリーを構成します。ダイアログの使用方法のヘルプを参照するには、「ヘルプ」をクリックするか、[F1]を押します。

  3. プロパティ・インスペクタで、「データ」セクションを開いて次の属性を設定します。

    • Value: ツリーをバインドするオブジェクトのEL式を指定します。手順1で作成したように、org.apache.myfaces.trinidad.model.TreeModelのインスタンスであることが必要です。

    • Var: 各ノードを表す変数名を指定します。

    • VarStatus: オプションで、コンポーネントの状態の判断に使用可能な変数を入力します。レンダー・レスポンス・フェーズ中に、ツリーによりモデル行が反復され、各ノードがレンダリングされます。指定された任意のノードに対して、varStatus属性で次の情報を指定します。

      • model: CollectionModelインスタンスへの参照

      • index: 現在行の索引

      • rowKey: 現在のノードの一意キー

  4. 「外観」セクションを開き、次の属性を設定します。

    • DisplayRow: 最初に表示される際にツリーに表示するノードを指定します。使用可能な値は、最初のノードを表示する場合はfirst、最後のノードを表示する場合はlast、ツリーの最初に選択されたノードを表示する場合はselectedです。デフォルトは、firstです。

    • DisplayRowKey: 最初に表示される際にツリーに表示する行キーを指定します。この属性はプログラムのみを使用して設定する必要があります。この属性を指定すると、displayRow属性がオーバーライドされます。

    • Summary: オプションで、ツリーによって表示されるデータのサマリーを入力します。

  5. 「動作」セクションを開き、次の属性を設定します。

    • InitiallyExpanded: コンポーネントが初めてレンダリングされる際に、すべてのノードを開いておく場合はtrueに設定します。

    • EditingMode: ツリーへのデータの表示に使用された編集可能なコンポーネントで、すべてのノードを編集可能にするか(editAll)、ユーザーがノードをクリックした場合に編集可能にするか(clickToEdit)を指定します。詳細は、12.2.4項「表、ツリーおよびツリー表のデータの編集」を参照してください。

    • ContextMenuSelect: 右クリックしてポップアップ・メニューを開く際に、ノードを選択するかどうかを決定します。trueに設定すると、ノードが選択されます。ポップアップ・メニューの詳細は、第15章「ポップアップ・ダイアログ、メニューおよびウィンドウの使用方法」を参照してください。

    • RowSelection: ノードを選択可能にする場合に値を設定します。有効な値はnonesingleまたはmultipleです。選択されたノードでプログラムを使用してアクションを実行する方法の詳細は、12.6.5項「プログラムを使用したノードの選択について」を参照してください。

    • ContentDelivery: データを送信するタイミングを指定します。contentDelivery属性がimmediateに設定されている場合、コンポーネントのレンダリングと同時にデータがフェッチされます。contentDelivery属性がlazyに設定されている場合は、後続のリクエスト中にデータがフェッチされてクライアントに送信されます。属性がwhenAvailable(デフォルト)に設定されている場合、レンダラはデータが使用可能かどうかをチェックします。使用可能な場合、コンテンツは即時に配信されます。使用可能でない場合は、遅延配信が使用されます。詳細は、12.2.2項「コンテンツの配信」を参照してください。

    • FetchSize: データ・フェッチ・ブロックの行数を指定します。詳細は、12.2.2項「コンテンツの配信」を参照してください。

    • AutoHeightRows: スクロール・バーを表示する前に表示するノードの最大数に設定します。デフォルト値は-1です(いくつであっても自動サイズ設定は行われません)。値を0に設定して、fetchSizeと同じ値にすることができます。


      注意:

      autoHeightRows属性の設定について、次の点に注意してください。

      • inlineStyle属性に高さを指定しても効果はなく、AutoHeightRowsの値でオーバーライドされます。

      • inlineStyle属性にmin-heightまたはmax-heightを指定することは推奨されず、autoHeightRows属性と互換性がありません。

      • コンポーネントをpanelSplitterのようなレイアウト管理コンテナに配置すると、このコンテナによりコンポーネントのサイズが指定されます(自動のサイズ指定は発生しません)。詳細は、12.2.7項「ジオメトリ管理と表、ツリーおよびツリー表コンポーネント」を参照してください。


    • SelectionListener: オプションで、選択イベントを処理するリスナーにEL式を入力します。詳細は、12.6.5項「プログラムを使用したノードの選択について」を参照してください。

    • FocusListener: オプションで、フォーカス・イベントを処理するリスナーにEL式を入力します。

    • RowDisclosureListener: オプションで、ノードの表示イベントを処理するリスナー・メソッドにEL式を入力します。

  6. 「拡張」セクションを開き、次の属性を設定します。

  7. コンポーネントを追加してツリーにデータを表示するには、コンポーネント・パレットからnodeStampファセットに必要なコンポーネントをドラッグします。図12-22に、File Explorerアプリケーションのディレクトリの表示に使用されたツリーのnodeStampファセットを示します。

    図12-22 構造ウィンドウのnodeStampファセット

    構造ウィンドウのnodeStampファセット

    コンポーネントの値は、ツリーのvar属性および表示する属性の変数値セットにバインドする必要があります。たとえば、File Explorerアプリケーションのツリーでは、var属性の値としてfolderが使用されており、各ノードのディレクトリ名が表示されています。そのため、ディレクトリ名の表示に使用される出力コンポーネントの値は、#{folder.name}です。


    ヒント:

    ファセットに使用できる子コンポーネントは1つのみです。そのため、ノードごとに複数のコンポーネントを使用する場合は、図12-22に示すように、ファセットの直接の子にできるグループ・コンポーネント内にコンポーネントを配置します。


12.6.2 ページにツリーを追加する場合の処理

ページにツリーを追加すると、JDeveloperによりnodeStampファセットが追加され、ツリーのノードにスタンプが設定されます。例12-11に、File Explorerアプリケーション内のディレクトリ構造を表示するツリーの省略形のコードを示します。

例12-11 JSPページ内のADF Facesツリーのコード

<af:tree id="folderTree" 
         var="folder"
         binding="#{explorer.navigatorManager.foldersNavigator
                                             .foldersTreeComponent}"
         value="#{explorer.navigatorManager.foldersNavigator.
                                              foldersTreeModel}"
         disclosedRowKeys="#{explorer.navigatorManager.foldersNavigator.
                                              foldersTreeDisclosedRowKeys}"
         rowSelection="single" 
         contextMenuId=":context2"
         selectionListener="#{explorer.navigatorManager.foldersNavigator.
                                              showSelectedFolderContent}">
  <f:facet name="nodeStamp">
    <af:panelGroupLayout>
      <af:image id="folderNodeStampImg" source="#{folder.icon}"
                inlineStyle="vertical-align:middle; margin-right:3px;
                             shortDesc="folder icon"/>
      <af:outputText id="folderNodeStampText" value="#{folder.name}"/>
    </af:panelGroupLayout>
  </f:facet>
</af:tree>

12.6.3 実行時に行われる処理: ツリー・コンポーネント・イベント

ツリーは、階層でのレベルを示すためにノードがインデントされている形式で表示されます。ユーザーはクリックしてノードを開き、子ノードを表示できます。ユーザーは開いた状態のノードをクリックして閉じることもできます。ユーザーがこれらのアイコンのいずれかをクリックすると、コンポーネントによりRowDisclosureEventイベントが生成されます。このイベントに対応する処理を実行するには、カスタムのrowDisclosureListenerメソッドを登録します。詳細は、12.6.4項「プログラムを使用したノードの開閉について」を参照してください。

ユーザーがノードを選択または選択解除すると、ツリー・コンポーネントによりselectionEventイベントが起動されます。選択されたノードに基づいてツリー・コンポーネントで後処理を実行する、カスタムのselectionListenerインスタンスを登録できます。詳細は、12.6.5項「プログラムを使用したノードの選択について」を参照してください。

12.6.4 プログラムを使用したノードの開閉について

RowDisclosureEventイベントには、閉じた状態のすべてのノード用のRemovedSetオブジェクトと、開いた状態のすべてのノード用のAddedSetオブジェクトの2つのRowKeySetオブジェクトがあります。コンポーネントは、追加されたセットの全ノードの下位のサブツリーを開き、削除されたセットの全ノードの下位のサブツリーを閉じます。

例12-12に示すように、カスタムのrowDisclosureListenerメソッドは、ツリー・コンポーネントで後処理を実行できます。

例12-12 rowDisclosureListenerを含むツリー表コンポーネント

<af:treeTable id="folderTree" var="directory" value="#{fs.treeModel}"
     binding="#{editor.component}" rowselection="multiple"
     columnselection="multiple" focusRowKey="#{fs.defaultFocusRowKey}"
     selectionListener="#{fs.Table}"
     contextMenuId="treeTableMenu"
     rowDisclosureListener="#{fs.handleRowDisclosure}">

例12-13に、行公開イベントを処理するバッキングBeanメソッドを示します。例は、ツリー・ノードの展開を示しています。ツリー・ノードを縮小する場合は、getRemovedSetを使用します。

例12-13 rowDisclosureEvent用バッキングBeanメソッド

public void handleRowDisclosure(RowDisclosureEvent rowDisclosureEvent)
  throws Exception {
    Object rowKey = null;
    Object rowData = null;
    RichTree tree = (RichTree) rowDisclosureEvent.getSource();
    RowKeySet rks = rowDisclosureEvent.getAddedSet();
 
    if (rks != null) {
        int setSize = rks.size();
        if (setSize > 1) {
            throw new Exception("Unexpected multiple row disclosure  
                                 added row sets found.");
        }
        
        if (setSize == 0) {
           // nothing in getAddedSet indicates this is a node
           // contraction, not expansion. If interested only in handling
           // node expansion at this point, return.
           return;
        }
 
        rowKey = rks.iterator().next();
        tree.setRowKey(rowKey);
        rowData = tree.getRowData();
 
        // Do whatever is necessary for accessing tree node from
        // rowData, by casting it to an appropriate data structure
        // for example, a Java map or Java bean, and so forth.
   }
} 

ツリーおよびツリー表では、oracle.adf.view.rich.model.RowKeySetクラスのインスタンスを使用して、どのノードが開かれているかを追跡します。このインスタンスは、コンポーネントのdisclosedRowKeys属性として格納されます。例12-14に示すように、このインスタンスを使用して、階層内のノードの開いた状態または閉じた状態をプログラムで制御できます。RowKeySetインスタンスに含まれるノードは開かれ、その他すべてのノードは閉じられます。addAll()メソッドによりすべての要素がセットに追加され、removeAll()メソッドによりすべてのノードがセットから削除されます。

例12-14 disclosedRowKeys属性を含むツリー・コンポーネント

<af:tree var="node"
         inlineStyle="width:90%; height:300px"
         id="displayRowTable"
         varStatus="vs"
         rowselection="single"
         disclosedRowKeys="#{treeTableTestData.disclosedRowKeys}"
         value="#{treeTableTestData.treeModel}">

例12-15に、公開された行キーを処理するバッキングBeanメソッドを示します。

例12-15 行キーを処理するためのバッキングBeanメソッド

public RowKeySet getDisclosedRowKeys()
{
  if (disclosedRowKeys == null)
  {
    // Create the PathSet that we will use to store the initial
    // expansion state for the tree
      RowKeySet treeState = new RowKeySetTreeImpl();
      // RowKeySet requires access to the TreeModel for currency.
      TreeModel model = getTreeModel();
      treeState.setCollectionModel(model);
      // Make the model point at the root node
      int oldIndex = model.getRowIndex();
      model.setRowKey(null);
      for(int i = 1; i<=19; ++i)
      {
        model.setRowIndex(i);
        treeState.setContained(true);
      }
      model.setRowIndex(oldIndex);
      disclosedRowKeys = treeState;
  }
  return disclosedRowKeys;
}

12.6.5 プログラムを使用したノードの選択について

ツリーおよびツリー表コンポーネントを使用すると、単一のノードのみまたは複数のノードを選択できるようになります。コンポーネントで複数の選択が許可されている場合、ユーザーは[Ctrl]を押しながらクリックする操作、および[Shift]を押しながらクリックする操作で複数のノードを選択できます。

ユーザーがノードを選択または選択解除すると、ツリー・コンポーネントによりselectionEventイベントが起動されます。このイベントには、選択解除されたすべてのノード用のRemovedSetオブジェクトと、選択されたすべてのノード用のAddedSetの2つのRowKeySetオブジェクトがあります。

ツリーおよびツリー表コンポーネントは、クラスoracle.adf.view.rich.model.RowKeySetのインスタンスを使用して選択されたノードを追跡します。このインスタンスは、コンポーネントのselectedRowKeys属性として格納されます。このインスタンスを使用して、階層内のノードの選択状態をプログラムで制御できます。RowKeySetインスタンスに含まれるノードは選択されているとみなされ、その他すべてのノードは選択解除されているとみなされます。addAll()メソッドによりすべてのノードがセットに追加され、removeAll()メソッドによりすべてのノードがセットから削除されます。ツリーおよびツリー表ノードの選択は、表の行の選択と同じように機能します。表の行選択のサンプル・コードは、12.3.8項「表の選択された行でのアクションの実行について」を参照してください。

12.7 ツリー表へのデータの表示

ADF Facesのツリー表コンポーネントでは、表形式で階層データが表示されます。ツリー表コンポーネントでは、階層の各ツリー・ノードのデータの列を表示できるため、ツリー表コンポーネントの表示はツリー・コンポーネントの表示より複雑です。コンポーネントには、階層のノードの開閉だけでなく、メイン・ツリー内のサブツリーにフォーカスするメカニズムもあります。図12-23に、File Explorerアプリケーションで使用されるツリー表を示します。ツリー・コンポーネント同様、ツリー表でも、コレクションのファイル間の階層関係を表示できます。また、表コンポーネントと同じように、各ファイルの属性値も表示できます。

図12-23 File Explorerアプリケーションのツリー表

File Explorerアプリケーションのツリー表

ツリー表コンポーネントの直下の子は、表コンポーネントと同じように、列コンポーネントであることが必要です。表とは異なり、ツリー表コンポーネントには、階層のノードの1次識別子を含む列が配置されるnodeStampファセットがあります。treeTableコンポーネントでは、Treeコンポーネントと同じスタンプ設定動作がサポートされています(詳細は、12.6項「ツリーへのデータの表示」を参照してください)。


注意:

nodeStampファセットは、1列のみ含むことができます(これがツリーのノードになります)。


たとえば、(図12-23に示す)File Explorerアプリケーションの1次識別子はファイル名です。これは、nodeStampファセットに含まれる列です。タイプ「サイズ」などのその他の列は、1次識別子の属性値を表示し、ツリー表コンポーネントの直接の子です。このツリー表では、nodeStampファセット列の各ノードのデータ、および子の列の各コンポーネントのデータにスタンプを設定するために使用される変数の値としてnodeが使用されています。例12-16に、File Explorerアプリケーション内のツリー表の省略形のコードを示します。

例12-16 treeTableの行へのスタンプ設定

<af:treeTable id="folderTreeTable" var="file"
              value="#{explorer.contentViewManager.treeTableContentView.
                                                   contentModel}"
              binding="#{explorer.contentViewManager.treeTableContentView.
                                                   contentTreeTable}"
              emptyText="#{explorerBundle['global.no_row']}"
              columnStretching="last"
              rowSelection="single"
              selectionListener="#{explorer.contentViewManager.
                                   treeTableContentView.treeTableSelectFileItem}"
              summary="treeTable data">
  <f:facet name="nodeStamp">
    <af:column headerText="#{explorerBundle['contents.name']}"
               width="200" sortable="true" sortProperty="name">
      <af:panelGroupLayout>
        <af:image source="#{file.icon}"
                  shortDesc="#{file.name}"
                  inlineStyle="margin-right:3px; vertical-align:middle;"/>
        <af:outputText id="nameStamp" value="#{file.name}"/>
      </af:panelGroupLayout>
    </af:column>
  </f:facet>
  <f:facet name="pathStamp">
    <af:panelGroupLayout>
      <af:image source="#{file.icon}"
                shortDesc="#{file.name}"
                inlineStyle="margin-right:3px; vertical-align:middle;"/>
      <af:outputText value="#{file.name}"/>
    </af:panelGroupLayout>
  </f:facet>
  <af:column headerText="#{explorerBundle['contents.type']}">
    <af:outputText id="typeStamp" value="#{file.type}"/>
  </af:column>
  <af:column headerText="#{explorerBundle['contents.size']}">
    <af:outputText id="sizeStamp" value="#{file.property.size}"/>
  </af:column>
  <af:column headerText="#{explorerBundle['contents.lastmodified']}"
             width="140">
    <af:outputText id="modifiedStamp"
                   value="#{file.property.lastModified}"/>
  </af:column>
</af:treeTable>

ツリー表コンポーネントでは、表とツリーの両方と同じ多くの属性がサポートされています。これらの属性の詳細は、12.3項「表コンポーネントの使用方法」および12.6項「ツリーへのデータの表示」を参照してください。

12.7.1 ツリー表へのデータの表示方法

ツリー表を作成するには、ツリー表の挿入ウィザードを使用します。ウィザードが完了したら、プロパティ・インスペクタを使用して、ツリー表の追加の属性を構成します。

始める前に:

属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、12.7項「ツリー表へのデータの表示」を参照してください。

他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、12.1.2項「表およびツリーの追加機能」を参照してください。

ページにツリー表を追加する手順:

  1. コンポーネント・パレットで、「データ・ビュー」パネルから「ツリー表」をページにドラッグ・アンド・ドロップし、ツリー表の挿入ウィザードを開きます。ウィザードを完了することで表を構成します。ヘルプを参照するには、[F1]を押すか「ヘルプ」をクリックします。

  2. プロパティ・インスペクタを使用して、その他の属性を構成します。


    ヒント:

    ツリー表の属性は、表およびツリー・コンポーネントの属性と同じです。属性の構成の詳細は、12.3.4項「ページへの表の表示方法」および12.6.1項「ツリーへのデータの表示方法」を参照してください。


12.8 行を値として渡す

コレクションから行全体を値として渡すことが必要な場合があります。そのためには、表で行を表すために使用される変数、またはツリーでノードを表すために使用される変数を、pageFlowスコープのプロパティに値として渡します。別のページは、スコープからその値にアクセスできます。setPropertyListenerタグでこれを行うことができます(使用手順を含むsetPropertyListenerタグの詳細は、5.7項「ページ間の値の受渡し」を参照してください)。

たとえば、例12-17に示すように、従業員が表示された単一選択の表を含むマスター・ページがあり、ユーザーが行を1つ選択してコマンド・ボタンをクリックすると、その行のデータを編集するための新しいページにナビゲートできるようにするとします。EL変数名empは、表の1行(従業員)を表すために使用されます。commandButtonコンポーネントのaction属性値は、ユーザーによる「Employee Detail」ページへのナビゲートを可能にする静的な文字列結果showEmpDetailです。setPropertyListenerタグにはfrom値(変数emp)が使用され、toの値に格納されます。

例12-17 setPropertyListenerおよびpageFlowScopeの使用

<af:table value="#{myManagedBean.allEmployees}" var="emp"
          rowSelection="single">
  <af:column headerText="Name">
    <af:outputText value="#{emp.name}"/>
  </af:column>
  <af:column headerText="Department Number">
    <af:outputText value="#{emp.deptno}"/>
  </af:column>
  <af:column headertext="Select">
    <af:commandButton text="Show more details" action="showEmpDetail">
      <af:setPropertyListener from="#{emp}" 
                              to="#{pageFlowScope.empDetail}" 
                              type="action"/>
    </af:commandButton>
  </af:column>
</af:table> 

ユーザーが従業員行のコマンド・ボタンをクリックすると、リスナーが実行され、表の現在行(従業員)に対応する#{emp}の値が取得されます。取得された行オブジェクトは、#{pageFlowScope.empDetail} EL式を使用してpageFlowScopeempDetailプロパティとして格納されます。アクション・イベントの実行は静的結果になり、ユーザーは詳細ページにナビゲートされます。詳細ページでは、例12-18に示すように、outputTextコンポーネントは、pageFlowScope.empDetailオブジェクトから値を取得します。

例12-18 pageFlowScopeオブジェクトの取得

<h:panelGrid columns="2">
  <af:outputText value="Firstname:"/>
  <af:inputText value="#{pageFlowScope.empDetail.name}"/>
  <af:outputText value="Email:"/>
  <af:inputText value="#{pageFlowScope.empDetail.email}"/>
  <af:outputText value="Hiredate:"/>
  <af:inputText value="#{pageFlowScope.empDetail.hiredate}"/>
  <af:outputText value="Salary:"/>
  <af:inputText value="#{pageFlowScope.empDetail.salary}"/>
</h:panelGrid> 

12.9 表メニュー、ツールバーおよびステータス・バーの表示

panelCollectionコンポーネントを使用して、表、ツリーおよびツリー表にメニュー、ツールバーおよびステータス・バーを追加できます。panelCollectionコンポーネントを使用するには、表、ツリーまたはツリー表コンポーネントをpanelCollectionコンポーネントの直接の子として追加します。panelCollectionコンポーネントには、デフォルトのメニューとツールバー・ボタンが用意されています。

図12-24に、ツリー表コンポーネントを含む、File ExplorerアプリケーションのpanelCollectionコンポーネントを示します。ツールバーには、ツリー表で実行可能なアクション(ノードの開閉など)を提供するメニュー、ユーザーがツリー表を連結解除できるボタン、およびユーザーがツリー表に表示された行を変更できるボタンが含まれます。特定のツールバー項目を表示しないようにツールバーを構成できます。たとえば、ユーザーがツリーまたは表をデタッチできるボタンをオフにすることができます。メニュー、ツールバー、ツールバー・ボタンの詳細は、第16章「メニュー、ツールバーおよびツールボックスの使用方法」を参照してください。

図12-24 メニューおよびツールバーのあるツリー表のパネル・コレクション

メニューおよびツールバーのあるpanelCollection

panelCollectionコンポーネントには、メニュー・コンポーネントを保持するmenuファセット、ツールバー・コンポーネント用のtoolbarファセット、別のツールバー・コンポーネント・セット用のsecondaryToolbarファセット、およびステータス項目用のstatusbarファセットが含まれています。

デフォルトのトップレベルのメニューおよびツールバー項目は、panelCollectionコンポーネントの子として使用されているコンポーネントにより異なります。

例12-19に、panelCollectionコンポーネントにどのようにメニューおよびツールバーが含まれるかを示します。

例12-19 表、メニューおよびツールバーを含むpanelCollectionコンポーネント

<af:panelCollection
    binding="#{editor.component}">  
  <f:facet name="viewMenu">
    <af:group>
      <af:commandMenuItem text="View Item 1..."/>
      <af:commandMenuItem text="View Item 2.."/>
      <af:commandMenuItem text="View Item 3..." disabled="true"/>
      <af:commandMenuItem text="View Item 4"/>
    </af:group>
  </f:facet>

  <f:facet name="menus">
    <af:menu text="Actions">
      <af:commandMenuItem text="Add..." />
      <af:commandMenuItem text="Create.." />
      <af:commandMenuItem text="Update..." disabled="true"/>
      <af:commandMenuItem text="Copy"/>
      <af:commandMenuItem text="Delete"/>              
      <af:commandMenuItem text="Remove" accelerator="control A"/>
      <af:commandMenuItem text="Preferences"/>
    </af:menu>
  </f:facet>
  <f:facet name="toolbar">
    <af:toolbar>
      <af:commandToolbarButton shortDesc="Create" icon="/new_ena.png">
      </af:commandToolbarButton>
      <af:commandToolbarButton shortDesc="Update" icon="/update_ena.png">
      </af:commandToolbarButton>
      <af:commandToolbarButton shortDesc="Delete" icon="/delete_ena.png">
      </af:commandToolbarButton>
    </af:toolbar>
  </f:facet>
  <f:facet name="secondaryToolbar">
  </f:facet>
  <f:facet name="statusbar">
    <af:toolbar>
      <af:outputText id="statusText" ... value="Custom Statusbar Message"/>
    </af:toolbar>
  </f:facet>
  <af:table rowselection="multiple" columnselection="multiple" 
                        ...
  <af:column 
                        ...
  </af:column>

ヒント:

panelCollectionコンポーネント内で、メニューを連結解除可能にできます。詳細は、16.2項「メニュー・バーでのメニューの使用方法」を参照してください。ユーザーに次のいずれかを期待する場合は、連結解除可能メニューの使用を検討してください。

  • ページで類似のコマンドを繰り返し実行する場合。

  • 大規模な表、ツリー表またはツリーにおいて、異なる行のデータで類似のコマンドを実行する場合。

  • 長くて幅の広い表やツリー表、およびツリーでデータを表示する場合。ユーザーは一度クリックすることで、表示または非表示にする列やブランチを選択できます。

  • 長くて幅の広い表、ツリー表またはツリーでデータを書式設定する場合。


12.9.1 表、ツリーまたはツリー表を含むpanelCollectionの追加方法

panelCollectionコンポーネントを追加してから、panelCollectionコンポーネントに表、ツリーまたはツリー表を追加します。その後、メニューおよびツールバーを追加および変更できます。

始める前に:

属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、12.9項「表メニュー、ツールバーおよびステータス・バーの表示」を参照してください。

他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、12.1.2項「表およびツリーの追加機能」を参照してください。

集約表示のコンポーネントを含むpanelCollectionコンポーネントを作成する手順:

  1. コンポーネント・パレットで、「レイアウト」パネルから「パネル・コレクション」をページにドラッグ・アンド・ドロップします。表、ツリーまたはツリー表をそのコンポーネントの子として追加します。

    または、ページに表、ツリーまたはツリー表がすでに存在している場合は、コンポーネントを右クリックして「囲む」を選択します。次に「パネル・コレクション」を選択して、panelCollectionコンポーネントでコンポーネントを囲みます。

  2. オプションで、特定のツールバーおよびメニュー項目をオフにして、panelCollectionツールバーをカスタマイズします。そのためには、構造ウィンドウでpanelCollectionコンポーネントを選択します。プロパティ・インスペクタで、featuresOff属性を設定します。表12-1に、有効な値とツールバーでのそれぞれの効果を示します。

    表12-1 featuresOff属性の有効値

    表示されないもの

    statusBar

    ステータス・バー

    viewMenu

    「表示」メニュー

    formatMenu

    「書式設定」メニュー

    columnsMenuItem

    「表示」メニューの「列」メニュー項目

    columnsMenuItem:colId

    例:
    columnsMenuItem:col1, col2

    「列」メニュー内の一致するIDを持つ列

    たとえば、左の値はIDがcol1およびcol2の列を表示しません。

    freezeMenuItem

    「表示」メニューの「固定」メニュー項目

    detachMenuItem

    「表示」メニューの「連結解除」メニュー項目

    sortMenuItem

    「表示」メニューの「ソート」メニュー項目

    reorderColumnsMenuItem

    「表示」メニューの「列の並替え」メニュー項目

    resizeColumnsMenuItem

    「書式設定」メニューの「列のサイズ変更」メニュー項目

    wrapMenuItem

    「書式設定」メニューの「折返し」メニュー項目

    showAsTopMenuItem

    ツリーの「表示」メニューの「先頭として表示」メニュー項目

    scrollToFirstMenuItem

    ツリーの「表示」メニューの「最初にスクロール」メニュー項目

    scrollToLastMenuItem

    ツリーの「表示」メニューの「最後にスクロール」メニュー項目

    freezeToolbarItem

    「固定」ツールバー項目

    detachToolbarItem

    「連結解除」ツールバー項目

    wrapToolbarItem

    「折返し」ツールバー項目

    showAsTopToolbarItem

    「先頭として表示」ツールバー項目

    wrap

    「折返し」メニューおよびツールバー項目

    freeze

    「固定」メニューおよびツールバー項目

    detach

    「連結解除」メニューおよびツールバー項目


  3. コンポーネントにカスタムのメニューおよびツールバーを追加します。

    • メニュー: menuファセットにmenuコンポーネントを追加します。

    • ツールバー: toolbarまたはsecondaryToolbarファセットにtoolbarコンポーネントを追加します。

    • ステータス項目: statusbarファセットに項目を追加します。

    • ビュー・メニュー: viewMenuファセットにcommandMenuItemコンポーネントを追加します。複数項目の場合は、commandMenuItemコンポーネントのコンテナとしてgroupコンポーネントを使用します。

    コンポーネント・パレットから、ファセットにコンポーネントをドラッグ・アンド・ドロップします。たとえば、menuファセットに「メニュー」をドロップし、同じファセットに「メニュー項目」をドロップしてメニュー・リストを作成します。メニューおよびツールバーの詳細は、第16章「メニュー、ツールバーおよびツールボックスの使用方法」を参照してください。

12.10 表、ツリーまたはツリー表からのデータのエクスポート

表、ツリーまたはツリー表から、あるいはDVTプロジェクトのガント・チャートの表領域から、Microsoft Excelスプレッドシートにデータをエクスポートできます。ユーザーが表をエクスポートできるようにするには、コマンド・ボタンやコマンド・リンクなど、エクスポートの起動に使用するアクション・ソースを作成し、exportCollectionActionListenerコンポーネントを追加して、エクスポートするデータに関連付けます。すべての行がエクスポートされるように、またはユーザーが選択した行のみがエクスポートされるように表を構成できます。


ヒント:

DVTピボット表からデータをエクスポートすることもできます。詳細は、24.8項「ピボット・テーブルからのエクスポート方法」を参照してください。


たとえば、図12-25に、ユーザーがExcelのスプレッドシートにデータをエクスポートできるコマンド・ボタン・コンポーネントが含まれるADF Facesデモの表を示します。

図12-25 データをエクスポートするためのコマンド・ボタンがある表

コマンド・ボタンを使用するとデータをエクスポートできます

ユーザーがコマンド・コンポーネントをクリックすると、リスナーにより、すべての行のExcelへのエクスポートが処理されます。図12-25に示すように、ユーザーが選択する行のみがエクスポートされるように、exportCollectionActionListenerコンポーネントを構成することも可能です。


注意:

次の値のみエクスポートできます

  • 値ホルダー・コンポーネント(inputコンポーネントやoutputコンポーネントなど)の値。

  • selelctOneChoiceおよびselectOneListboxコンポーネントで使用されるselectItemコンポーネントの値(他の選択コンポーネントのselectItemコンポーネントの値はエクスポートされません)。

  • コマンド・コンポーネントのtext属性の値。


ブラウザ、およびリスナーの構成によって異なりますが、図12-26に示すように、ユーザーがスプレッドシートを開くか保存することができるダイアログがブラウザによって開かれるか、ブラウザにスプレッドシートが表示されます。たとえば、ユーザーがMicrosoft Internet Explorerでページを表示していて、exportCollectionActionListenerコンポーネントにファイル名が指定されていない場合、ファイルはブラウザに表示されます。Mozilla Firefoxでは、ダイアログが開かれます。

図12-26 Excelへのエクスポート・ダイアログ

Excelへのエクスポート・ダイアログ

ユーザーがファイルの保存を選択した場合、図12-27に示すように、後からExcelで開くことができます。ユーザーがファイルを開くことを選択した場合、その後の動作はブラウザにより異なります。たとえば、ユーザーがMicrosoft Internet Explorerでページを表示している場合、ブラウザ・ウィンドウにスプレッドシートが表示されます。ユーザーがMozilla Firefoxでページを表示している場合は、スプレッドシートがExcelで開かれます。

図12-27 Excelにエクスポートされたデータファイル

データがExcelで表示されています

注意:

ファイルがファイル拡張子で指定されたフォーマットとは異なることを示す警告がExcelに表示されることがあります。この警告は無視して問題ありません。


12.10.1 表、ツリーまたはツリー表データの外部形式へのエクスポート方法

ボタン、リンク、メニュー項目などのコマンド・コンポーネントを作成し、そのコンポーネントの内部にexportCollectionActionListenerを追加します。その後、exportCollectionActionListenerコンポーネントのexportedId属性を、データをエクスポートするコレクション・コンポーネントIDに設定して、エクスポートするデータ・コレクションを関連付けます。

始める前に:

属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、12.10項「表、ツリーまたはツリー表からのデータのエクスポート」を参照してください。

他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、12.1.2項「表およびツリーの追加機能」を参照してください。

ページに表、ツリーまたはツリー表が存在している必要があります。ない場合は、この章の指示に従って表、ツリーまたはツリー表を作成します。たとえば、表を追加するには、12.3項「表コンポーネントの使用方法」を参照してください。


ヒント:

ユーザーがエクスポートする行を選択できるようにするには、選択が許可されるよう表を設定します。詳細は、12.3.2項「表の書式設定」を参照してください。


外部形式にコレクション・データをエクスポートする手順:

  1. コンポーネント・パレットで、「一般コントロール」パネルからボタンなどのコマンド・コンポーネントをページにドラッグ・アンド・ドロップします。


    ヒント:

    表、ツリーまたはツリー表にコマンド・コンポーネントのあるツールバーを作成する場合は、コレクション・コンポーネントをpanelCollectionコンポーネントで囲みます。このコンポーネントにより、ツールバー機能が追加されます。詳細は、12.9項「表メニュー、ツールバーおよびステータス・バーの表示」を参照してください。


    コマンド・コンポーネントのデフォルトのラベルを、意味のある名前(Export to Excelなど)に変更することが必要な場合があります。

  2. コンポーネント・パレットで、「操作」パネルから「エクスポート・コレクション・アクション・リスナー」をコマンド・コンポーネントに子としてドラッグします。

  3. エクスポート・コレクション・アクション・リスナーの挿入ダイアログで、次の設定を行います。

    • ExportedId: エクスポートする表、ツリーまたはツリー表のIDを指定します。手動で入力するか、ドロップダウン・メニューを使用して「編集」を選択します。「プロパティの編集」ダイアログを使用して、コンポーネントを選択します。

    • Type: excelHTMLに設定します。

  4. exportCollectionActionListenerコンポーネントが選択された状態で、プロパティ・インスペクタで次の設定を行います。

    • Filename: エクスポートするコンテンツの選択したファイル名を指定します。この属性を設定すると、通常は「ファイルの保存」ダイアログが表示されますが、最終的にはブラウザにより異なります。この属性を設定しない場合、通常、コンテンツはブラウザにインライン表示されます(可能な場合)。

    • Title: エクスポートするドキュメントのタイトルを指定します。タイトルが表示されるかどうかや、どのように表示されるかは、Excelに依存します。

    • ExportedRows: すべての行が自動的に選択されてエクスポートされるようにするには、allに設定します。ユーザーが選択した行のみがエクスポートされるようにする場合は、selectedに設定します。

例12-20に、表およびそのexportCollectionActionListenerコンポーネントのコードを示します。exportedId値が、表のid値に設定されていることに注意してください。

例12-20 exportCollectionActionListenerを使用した表のエクスポート

<af:table contextMenuId="thePopup" selectionListener="#{fs.Table}"
          rowselection="multiple" columnselection="multiple"
          columnBandingInterval="1"
          binding="#{editor.component}" var="test1" value="#{tableTestData}"
          id="table" summary="table data">
  <af:column>
  . . .
  </af:column>
</af:table>
<af:commandButton text="Export To Excel" immediate="true">
  <af:exportCollectionActionListener type="excelHTML" exportedId="table"
                               filename="export.xls" title="ADF Faces Export"/>

12.10.2 実行時の処理: 行の選択がエクスポートされるデータに与える影響

エクスポートされるデータは、選択したキーの順序ではなく、索引順でエクスポートされています。つまり、選択した行のエクスポートを可能にして、ユーザーが8、4、2(という順序で)行を選択すると、行はExcelに2、4、8という順序でエクスポートされて表示されます。

12.11 スタンプ設定を使用するコンポーネントからクライアント上の選択された値へのアクセス

ADF Facesフレームワークでは、クライアント側でELがサポートされないのみでなく、クライアントへの表モデル全体の送信もサポートされていないため、JavaScriptを使用してクライアント上の値にアクセスする必要がある場合、クライアント側のコードは、値にアクセスするためにスタンプ設定するコンポーネントに依存できません。各行で同じコンポーネント・インスタンスを再利用するかわりに、完全に解決されるEL式を使用して、各行に新しいJavaScriptコンポーネントが作成されます(どの行にもコンポーネントが1つ作成される必要があると仮定しています)。

そのため、クライアント上の行固有のデータにアクセスするには、それ自体がスタンプ設定されたコンポーネントを使用して値にアクセスする必要があります。クライアント側のデータ・モデルを使用せずにこれを実現するには、クライアント側の選択変更リスナーを使用します。

12.11.1 スタンプ設定されたコンポーネントの選択内容から値へのアクセス方法

スタンプ設定されたコンポーネントからクライアント上の値にアクセスするには、まず、コンポーネントにクライアント表現があることを確認する必要があります。次に、クライアントに選択変更リスナーを登録し、そのリスナーで、選択された行の判断、その行に関連付けられているスタンプ設定されたコンポーネントの検索、スタンプ設定されたコンポーネントを使用した行固有の名前の判断、最後に、選択されたデータとの必要に応じた対話を行う必要があります。

始める前に:

他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、12.1.2項「表およびツリーの追加機能」を参照してください。

スタンプ設定されたコンポーネントから選択された値にアクセスする手順:

  1. ページの構造ウィンドウで、スタンプ設定された行に関連付けられたコンポーネントを選択します。たとえば、例12-21の表では、outputTextコンポーネントを使用してスタンプ設定された行が表示されています。

    例12-21 スタンプ設定された行にoutputTextコンポーネントが使用されている表コンポーネント

    <af:table var="row" value="#{data}" rowSelection="single">
      <af:column headerText="Name">
        <af:outputText value="#{row.name}"/>
      </af:column>
    </af:table>
    

    コンポーネントに次の設定を行います。

    • プロパティ・インスペクタの「共通」セクションを開き、Id属性を使用してコンポーネントに一意のIDを設定します(まだ定義されていない場合)。

    • 「拡張」セクションを開き、ClientComponentTrueに設定します。

  2. コンポーネント・パレットで、「操作」パネルから「クライアント・リスナー」を表に子としてドラッグ・アンド・ドロップします。

  3. クライアント・リスナーの挿入ダイアログで、「メソッド」フィールドに関数名(次の手順でこの関数を実装します)を入力し、「タイプ」ドロップダウンから「selection」を選択します。

    たとえば、関数としてmySelectedRowを入力した場合、JDeveloperにより、例12-22に太字で示されたコードが入力されます。

    例12-22 選択を登録するためのclientListenerの使用

    <af:table var="row" value="#{data}" rowSelection="single">
      <af:clientListener type="selection" method="mySelectedRow"/>
      ...
    </af:table>
    

    このコードにより、mySelectedRow関数は、選択内容が変更されるたびにコールされます。

  4. JavaScriptライブラリで、前の手順で入力された関数を実装します。この関数により、次の操作が実行されます。

    • どの行が選択されているかを調べます。そのためには、リスナーに渡されるイベント・オブジェクトを使用します。選択イベントの場合、イベント・オブジェクトのタイプはAdfSelectionEventです。このタイプは、選択された各行キーのプロパティを含むPOJSO (plain old JavaScript object)を返すgetAddedSet()メソッドを介して、新規に選択された行キーへのアクセスを可能にします。このオブジェクトへのアクセスが可能になったら、"for in"ループを使用して行キーを反復できます。たとえば、例12-23のコードは最初の行キー(この場合は唯一の行キー)を抽出します。

      例12-23 "for" inループを使用した行キーの反復

      function showSelectedName(event)
      {
        var firstRowKey;
        var addRowKeys=event.getAddedSet();
      
        for(var rowKey in addedRowKeys)
        {
          firstRowKey=rowKey;
          break;
        }
      }
      
    • 選択された行に関連付けられているスタンプ設定されたコンポーネントを検索します。クライアント側コンポーネントAPIのAdfUIComponentは、検索するコンポーネントのIDを受け取ってAdfUIComponentインスタンスを返すfindComponent()メソッドを公開します。スタンプ設定されたコンポーネントを使用している場合は、そのIDだけでなく、行キーでもコンポーネントを検索する必要があります。これをサポートするために、AdfUITableクラスは、IDと行キーの両方を受け取るfindComponent()のオーバーロード・メソッドを提供します。

      選択イベントの場合、コンポーネントはイベントのソースです。そのため、イベントのソースから表を取得し、表を使用して、IDと行キーでインスタンスを検索できます。例12-24にこれを示します。nameStampは表のIDです。

      例12-24 選択された行を指定したスタンプ設定されたコンポーネント・インスタンスの検索

      // We need the table to find our stamped component.
      // Fortunately, in the case of selection events, the
       // table is the event source.
       var table = event.getSource();
       
       // Use the table to find the name stamp component by id/row key:
       var nameStamp = table.findComponent("nameStamp", firstRowKey);
      
  5. コンポーネントを使用するために必要なその他のコードを追加します。スタンプ設定されたコンポーネントを検出したら、その他のコンポーネントの場合と同じように通信できます。たとえば、例12-25に、スタンプ設定されたコンポーネントを使用してname属性の行固有の値(例12-21で示したスタンプ設定された値)を取得し、アラートに名前を表示する方法を示します。

    例12-25 スタンプ設定されたコンポーネントの行の名前の取得

    if (nameStamp)
      {    // This is the row-specific name
        var name = nameStamp.getValue();
    
        alert("The selected name is: " + name);
      }
    

例12-26にJavaScriptの全コードを示します。

例12-26 選択された行の値へのアクセスに使用されるJavaScript

function showSelectedName(event)
{
  var firstRowKey;
  var addedRowKeys = event.getAddedSet();

  for (var rowKey in addedRowKeys)
  {
    firstRowKey = rowKey;
    break;
  }
  // We need the table to find our stamped component.
  // Fortunately, in the case of selection events, the
  // table is the event source.
  var table = event.getSource();
 
  // We use the table to find the name stamp component by id/row key:
  var nameStamp = table.findComponent("nameStamp", firstRowKey);
 
  if (nameStamp)
  {
    // This is the row-specific name
    var name = nameStamp.getValue();
 
     alert("The selected name is: " + name);
  }
}

12.11.2 選択された値へのアクセスについて

行キーはサーバー上のtokenizedで、これはクライアント上の行キーとサーバー上の行キーに類似点がない可能性があることを意味します。そのため、クライアント側APIによって処理される行キー(AdfSelectionEvent.getAddedSet()など)のみ有効です。

また、対応する行がスクロールされて画面から見えなくなっていて、クライアントで使用できない場合には、AdfUITable.findComponent(id, rowKey)メソッドによりnullが戻される可能性があることに注意してください。AdfUITable.findComponent()メソッドの戻り値にnullがないか必ず確認してください。