この章では、構造化データをコンポーネント内に表示する方法を説明します。このコンポーネントは、データのコレクションを反復処理してコレクション内の各行を表示できます。ADF Facesのtable
、tree
、treeTable
、listView
およびcarousel
の各コンポーネントを使用します。アプリケーションでFusionテクノロジ・スタックが使用される場合、データ・コントロールを使用してこれらのコンポーネントを作成できます。詳細は、『Oracle Application Development FrameworkによるFusion Webアプリケーションの開発』の「ADFによるデータバインドされた表の作成」、「マスター/ディテール・データの表示」および「より複雑なデータバインドADF Facesコンポーネントの使用」の各章を参照してください
この章の内容は次のとおりです。
ADFコレクションベース・コンポーネントに関する基本的な理解が説明されています。ツールバーのカスタマイズ、アクティブ・データなどの追加機能は、表およびツリー・コンポーネントとともに使用することもできます。
ADF Facesには、構造化データのコレクションの反復処理と表示に使用できるコンポーネントが用意されています。表示される各レコード用に子コンポーネントを含め、それらのコンポーネントを個々のレコードにバインドするかわりに、これらのコンポーネントがコレクション全体にバインドされ、各レコードの値にスタンプを設定することにより、1つのコンポーネント(outputText
コンポーネントなど)が繰り返しレンダリングされます。
構造化データを、複数の行と1つの列からなる単純な表として表示するにはListView
コンポーネントを使用し、複数の列に表示するにはADF Faces table
コンポーネントを使用します。階層データは、ADF Facesのツリー・コンポーネントを使用してツリー構造として表示することも、ADF Facesのツリー表コンポーネントを使用して表形式で表示することもできます。イメージのコレクションはカルーセル・コンポーネントに表示できます。図12-1に、ADF Facesのコレクションベース・コンポーネントを示します。
図12-1 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:outputText label="Element Name" value="#{row.name}"/> <af:outputText label="Atomic Number" value="#{row.number}"/> <af:outputText label="Symbol" value="#{row.symbol}"/> <af:outputText label="Group" value="#{row.group}"/> </af:iterator>
各子には、必要に応じて何度でもスタンプ設定できます。反復は、first属性で指定された索引から開始され、row
属性で指定された索引まで行われます。row
属性が0
に設定されている場合、反復は基礎となるデータにそれ以上要素がなくなるまで続けられます。
コレクションベース・コンポーネントは、構造化データの表示に使用されます。たとえば、図12-2に示すように、File Explorerアプリケーションの表タブでは、選択されたディレクトリのコンテンツの表示に表が使用されています。
図12-2 File Explorerアプリケーションの表コンポーネント
File Explorerアプリケーションのディレクトリなど、階層データ(親子関係のあるデータ)は、ツリー・コンポーネントを使用して展開可能なツリーとして表示できます。項目は、データの親子構造をミラー化するノードとして表示されます。各最上位レベル・ノードを展開して子ノードを表示でき、子ノードを展開してその子ノードを表示できます。展開された各ノードを縮小して、子ノードを非表示にできます。図12-3に、ツリー・コンポーネントを使用して表示されるFile Explorerアプリケーションのファイル・ディレクトリを示します。
図12-3 File Explorerアプリケーションのツリー・コンポーネント
ツリー表コンポーネントを使用して階層データを表示することもできます。ツリー表でも、展開および縮小可能な親子のノードを表示できますが、これは表形式で、ページにノードの属性値がデータの列として表示されます。たとえば、表コンポーネントを使用してディレクトリのコンテンツを表示するだけでなく、File Explorerアプリケーションには、図12-4に示すように、ツリー表コンポーネントを使用してコンテンツを表示する別のタブもあります。
図12-4 File Explorerアプリケーションのツリー表
ツリー・コンポーネント同様、ツリー表コンポーネントも、項目間の親子関係を表示できます。また、表コンポーネントと同じように、ツリー表コンポーネントでも列の項目の属性値を表示できます。ツリー表コンポーネントでも、表コンポーネントで使用可能なほとんどの機能を使用できます。
表、ツリーおよびツリー表をpanelCollection
コンポーネントで囲むことにより、ツールバーおよびステータス・バーを表に追加できます。上部のパネルには、メニューとメニュー・オプション、ツールバーとツールバー・ボタン、およびステータス・バーなど、メニュー・タイプのコンポーネントを保持するツールバーのみでなく、標準のメニュー・バーも含まれます。デフォルトで追加されているボタンおよびメニューもあります。たとえば、表、ツリーまたはツリー表をpanelCollection
コンポーネントで囲むと、「表示」メニューを含むツールバーが追加されます。このメニューには、表、ツリーまたはツリー表コンポーネントに固有のメニュー項目が含まれます。
図12-5に、panelCollection
コンポーネントを使用して作成されたツールバー、メニューおよびツールバー・ボタンのあるFile Explorerアプリケーションのツリー表を示します。
図12-5 パネル・コレクションを使用したTreeTable
listView
コンポーネントは単純な表であり、構造化データをリスト形式で表示できます。表とは異なり、列がないため、単純な表形式のレイアウトよりも多様なパターンでデータを表示できます。
実際のデータを表示する各コンポーネントは、1つの子listItem
コンポーネントに含まれています。図12-6に、1つの子listItem
コンポーネントを含むlistView
コンポーネントを示します。listItem
コンポーネントには、レイアウト・コンポーネント、出力コンポーネントおよびボタン・コンポーネントが混在しています。
図12-6 listItemコンポーネントを使用して各行のデータを保持するlistViewコンポーネント
listView
コンポーネントでは、階層データも表示できます。親データにバインドされたコンポーネントがgroupHeaderStamp
ファセットに配置されている場合、そのデータはヘッダーに表示されます。図12-7に、アルファベット文字(親データ)がヘッダーに表示され、子である個人のデータが親の下の各行に表示される様子を示します。
図12-7 階層データのグループ別表示が可能
カルーセル・コンポーネントは、図12-8に示すように、イメージのコレクションを回転カルーセルに表示します。ユーザーは、下部にあるスライダを使用するか、補助イメージの1つをクリックしてそのイメージを前面に移動することにより、前面のイメージを変更できます。
図12-8 ADF Facesカルーセル
コレクションベース・コンポーネントを実装する前に、ADF Facesのその他の機能を理解しておくと役立ちます。また、ページにコレクションベース・コンポーネントを追加した後で、検証やアクセシビリティなどの機能を追加することが必要になる場合があります。表およびツリー・コンポーネントで使用できる他の機能へのリンクを次に示します。
ツールバーのカスタマイズ: 表およびツリー表コンポーネントのメニュー、ツールバーおよびステータス・バーを提供するpanelCollectionコンポーネントに含まれるツールバーをカスタマイズできます。メニュー、ツールバー、ツールバー・ボタンの詳細は、 「メニュー、ツールバーおよびツールボックスの使用方法」を参照してください。
表の幅のジオメトリ管理: 表が、子を拡大するコンポーネントの子である場合、この幅の設定はオーバーライドされ、表はコンテナに合うように自動的に拡大されます。コンポーネントが拡大される方法の詳細は、「ジオメトリ管理およびコンポーネントの拡大」を参照してください。
アクティブ・データ: アプリケーションでアクティブ・データを使用する場合は、データ・ソースのデータが変更されるたびに、表およびツリーのデータを自動的に更新できます。詳細は、『Oracle Application Development FrameworkによるFusion Webアプリケーションの開発』の「アクティブ・データ・サービスの使用方法」の章を参照してください。
注意:
アクティブ・データを使用し、アプリケーションでADFビジネス・コンポーネントを使用する場合は、表が次の条件に適合する必要があります。
表またはツリーが、単一の属性のみ含む同種データにバインドされていること。
表でフィルタを使用しないこと。
ツリー・コンポーネントのnodeStamp
ファセットに、単一のoutputText
タグが含まれ、他のタグが含まれていないこと。
イベント: コレクションベース・コンポーネントは、サーバー側とクライアント側両方のイベントを起動します。これに対する応答としてアプリケーションでなんらかのロジックを実行できます。詳細は、「イベントの処理」を参照してください。
部分ページ・レンダリング: ページ上の他のコンポーネントで実行されたアクションに基づいて、コレクションベース・コンポーネントをリフレッシュして新しいデータを表示することができます。詳細は、「最適化されたライフサイクルの使用」を参照してください。
パーソナライズ: コンポーネントの表示方法は実行時にユーザーが変更できますが(列の並替えや列幅の変更など)、ユーザーがそのページから移動した後もその値を維持するには、ユーザーのカスタマイズを許可するようにアプリケーションが構成されている必要があります。詳細は、「JSFページでのユーザー・カスタマイズの許可」を参照してください。
アクセシビリティ: コンポーネントをアクセス可能にできます。詳細は、「アクセス可能なADF Facesページの開発」を参照してください。
自動データ・バインディング: アプリケーションでFusionテクノロジ・スタックを使用する場合は、ADFビジネス・コンポーネントがどのように構成されているかに基づいて、バインドされた表およびツリーを自動的に作成できます。詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』の「ADFによるデータバインドされた表の作成」および「マスター/ディテール・データの表示」の章を参照してください。
ADFコレクションベース・コンポーネントで使用可能な機能を使用して、多くの機能を実行できます。たとえば、表構造の行やツリー構造のノードでデータを表示したり、1行または複数行のコンテンツをクライアント・マシンに配信したりできます。
コレクションベース・コンポーネントには、データの配信方法やデータの表示と編集の方法など、多数の共通する機能があります。これらのコンポーネントを使用する前に、この共有機能と、その構成方法を理解することが重要です。
表示するレコードごとに1つの子コンポーネントを持ち、そのコンポーネントを個々のレコードにバインドするのではなく、コレクションベース・コンポーネントはコレクション全体にバインドされ、各レコードの値をスタンプすることによって1つのコンポーネント(たとえばoutputText
コンポーネント)が繰返しレンダリングされます。たとえば、表に子の列コンポーネントが2つ含まれるとします。各列には、出力コンポーネントを使用して行の単一の属性値が表示され、4つのレコードが表示されます。データを表示するために、2つの出力コンポーネントの4セットをバインドするかわりに、表自体が4つすべてのレコードのコレクションにバインドされ、1セットの出力コンポーネントが単純に4回スタンプ設定されます。各行にスタンプが設定されると、現在行のデータが表のvar
属性にコピーされ、出力コンポーネントが行の正しい値を取得できるようになります。特に、クライアント・コンポーネントでスタンプ設定がどのように機能するかの詳細は、「クライアントのコレクション・コンポーネントへのアクセス」を参照してください。
次の例に、var
属性の値がrow
である表のJSFコードを示します。値が変数の特定のプロパティにバインドされているため、列の各outputText
コンポーネントにより行のデータが表示されます。
<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>
コレクションベース・コンポーネントは、Collection
Model
クラスを使用して基礎となるコレクションのデータにアクセスします。このクラスは、JSF DataModel
クラスを拡張し、行キーおよびソートのサポートを追加します。DataModel
クラスでは、行は索引によって完全に識別されます。他のユーザーが行を追加したことにより、ある行を削除するユーザー・リクエストで異なる行が削除されてしまうなど、あるリクエストから次のリクエストまでに基礎となるデータが変更される場合、この識別方法が原因で問題が発生する可能性があります。これを回避するため、CollectionModel
クラスは索引ではなく行キーに基づいています。
java.util.List
、array
およびjavax.faces.model.DataModel
など、別のモデル・クラスも使用できます。これらのクラスのいずれかを使用する場合は、表コンポーネントにより、インスタンスがCollectionModel
クラスに自動的に変換されますが、機能は追加されません。CollectionModel
クラスの詳細は、http://myfaces.apache.org/trinidad/trinidad-1_2/trinidad-api/apidocs/index.html
にあるMyFaces TrinidadのJavadocを参照してください。
注意:
アプリケーションでFusionテクノロジ・スタックを使用する場合は、データ・コントロールを使用して表を作成すると、コレクション・モデルが作成されます。詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』の「ADFによるデータバインドされた表の作成」の章を参照してください。
コレクション・コンポーネントは仮想化されています。つまり、サーバーのコンポーネントに存在する一部の行のみがクライアントに配信され、表示されます。コレクション・コンポーネントは、一度に一定数の行をデータ・ソースからフェッチするように構成されます。コンポーネント上のContentDelivery
属性の設定で指定して、レンダリング時にすぐにデータをコンポーネントに配信することも(使用可能な場合)、コンポーネントのシェルがレンダリングされた後に遅延フェッチすることもできます(デフォルトでは、コンポーネントはデータが使用可能な場合にデータをフェッチします)。
即時配信では、データは初期リクエスト時にフェッチされます。遅延配信では、ページにコレクション・コンポーネントが1つ以上含まれる場合、ページで最初に標準のライフサイクルが実行されます。ただし、最初のリクエスト時にデータがフェッチされるのではなく、特別な個別の部分ページ・レンダリング(PPR)リクエストが実行され、コンポーネントのフェッチ・サイズの値として設定された行数が戻されます。ページのレンダリング直後であるため、レンダー・レスポンス・フェーズのみがコンポーネントに対して実行され、対応するデータのフェッチおよび表示が可能になります。ユーザーのアクションにより後続のデータ・フェッチが実行される場合(別の行セットのために表をスクロールするなど)、別のPPRリクエストが実行されます。
コンテンツが使用可能なときに配信されるようにコンテンツ配信を構成すると、フレームワークでは最初のリクエストの間にデータの可用性をチェックし、使用可能であれば、そのデータがコンポーネントに送信され、レンダリングのためにインラインします。使用可能でない場合、データは遅延配信と同じように、別のPPRリクエスト時にロードされます。12.2.1.0より前のJDeveloperリリースでは、データの送信およびコンポーネントのレンダリングにおけるデータのインラインに、2つの個別のリクエストが必要でした。以前のリリースのコンテンツ配信のパフォーマンスが必要な場合、ContentDelivery
属性をlazy
に設定すると、後続でのみ、データのインラインを強制できます。
注意:
アプリケーションでFusionテクノロジ・スタックが使用されない場合は、whenAvailable
のサポートをCollectionModel
実装に明示的に追加する必要があります。たとえば、Facesデモ・アプリケーションのWhenAvailableData.java
マネージドBeanを参照してください。
アプリケーションでFusionテクノロジ・スタックを使用する場合は、作成されたCollectionModel
実装でこれらのAPIが自動的に使用されます。
パフォーマンスに関するヒント
データのフェッチにコスト(時間)がかかると予想されるときは、遅延配信を使用する必要があります。たとえば、データベース接続が低速で待機時間が長い場合や、データベース以外の低速のデータ・ソース(たとえばWebサービス)からデータをフェッチする場合です。ページに表、ツリーまたはツリー表以外のコンポーネントが複数含まれる場合も、遅延配信を使用する必要があります。遅延配信を使用すると、データが使用可能になる前に、初期ページのレイアウト・コンポーネントおよびその他のコンポーネントが最初にレンダリングされます。
即時配信は、表、ツリーまたはツリー表がページの唯一のコンテキストである場合、またはコンポーネントが大きなデータ・セットを返さないと予想される場合に使用する必要があります。この場合、ユーザー・レスポンス時間がより高速で、サーバーCPU利用率がより高ければ、2番目のリクエストはサーバーに移動しないため、レスポンス時間は遅延配信を使用する場合よりも高速になります(または、場合によっては高速に感じます)。ただし、フェッチ・ブロックとして構成された行数のみが最初に返されます。遅延配信と同様に、ユーザーのアクションが後続のデータ・フェッチの原因となる場合は、次の行セットが配信されます。
使用可能な場合、配信は、データが初期レンダリング時に使用可能な場合には即時を使用し、データが最初は使用可能でない場合は遅延にフォールバックするという追加の柔軟性を提供します。JDeveloper 12.2.1.0リリース以降では、使用可能な場合はデフォルトの配信コンテンツ配信モードとなります。
クライアントに表示されるのは、ブラウザに表示される際にページに収まる行数のみです。それ以上の行は、ユーザーがコンポーネントを垂直にスクロールしたとき(スクロールではなくページ区切りが設定されている場合は、ユーザーが別の行セットに移動したとき)にフェッチされます。コンポーネントを埋めるために1回でクライアントからサーバーにリクエストされる行数は、fetchSize
属性により決定されます。表の場合のデフォルト値は25です。そのため、表の高さが低ければ、フェッチ・サイズ25はコンポーネントを埋めるのに十分です。ただし、コンポーネントの高さが高い場合、サーバーからのデータのリクエストは複数回になります。そのため、fetchSize
属性は大きな数に設定しておく必要があります。たとえば、表の高さが600ピクセルで、各行の高さが18ピクセルの場合、表を埋めるのに少なくとも45行必要です。fetchSize
が25の場合、表を埋めるために、表はサーバーに対してリクエストを2回実行する必要があります。この例では、フェッチ・サイズを50に設定します。
ただし、フェッチ・サイズを大きくしすぎると、サーバーとクライアントの両方に影響を与えます。サーバーでは、データ・ソースから必要以上に行がフェッチされ、時間とメモリー使用量が増加します。クライアント側では、それらの行の処理とコンポーネントへのアタッチに時間がかかります。
パフォーマンスに関するヒント
可能な場合は必ずfetchSize
を減らします。
デスクトップ・デバイスでは、ユーザーがデータの行をスクロールできるように、表にはスクロール・バーがデフォルトでレンダリングされます。かわりに、表をページ区切りで構成する場合は、scrollPolicy
属性にpage
を設定できます。ページ区切りの表には、図12-9に示されているように、ユーザーが特定のページの行に移動できるフッターが表示されます。
図12-9 ページ区切りの表
ビューポートが狭すぎて、フッター全体を表示できない場合は、図12-10に示すように、現在表示されているページとナビゲーション・ボタンのみを表示するコンパクトなフッターが表示されます。
図12-10 コンパクト・モードで表示されたページ区切りの表
注意:
タブレット・デバイスでは、表はデフォルトでページ区切りで表示されるようにレンダリングされるため、スクロール・バーは表示されません。かわりに、ユーザーが表を下方向にスクロールしたときに、表が次の一連の行を自動的にロードするようにスクロール・バーを有効にする場合は、scrollPolicy
属性にscroll
を設定できます。このオプションによりブレットで発生する動作は暗黙的なハイウォータマーク・スクロールと呼ばれ、タブレット・デバイスの仮想化タッチ・スクロールの動作(水平方向および垂直方向の両方にスクロールする)とよく似ています。デスクトップ・マシンでscrollPolicy
をscroll
に設定することで可能な一般的な仮想化スクロールは、タブレットでの表の仮想化スクロールに伴うパフォーマンス問題のため、タブレットでは実装されていません。ただし、ユーザーはmaxClientRows
属性の値を設定することにより、データベースのラウンドトリップが最小になるようにキャッシュする行数を指定して、暗黙的なハイウォータマーク・スクロールのキャッシュ動作をカスタマイズできます。
スクロールするように構成された表の場合、ページに表示される行の数はfetchSize
属性によって決まります。
注意:
iOSオペレーティング・システムで、表でスクロール・バーを使用するように構成すると、デフォルトではコンテンツの上にマウスを置いたときのみスクロール・バーが表示されます。他のオペレーティング・システムでもこれと同じ動作となるようにアプリケーションを構成するには、web.xml
ファイルにあるoracle.adf.view.rich.table.scrollbarBehavior
パラメータを設定します。詳細は、「表におけるスクロールバーの動作」を参照してください。
注意:
-tr-overflow-style: autohiding-scrollbar
スキニング・プロパティを使用すると、スクロールバーを非表示にできます。次に例を示します。
af|table { -tr-overflow-style: autohiding-scrollbar }
スキンの詳細は、「スタイルおよびスキンを使用した外観のカスタマイズ」を参照してください。
displayRow
属性を使用して、最初に表示されるデータのセットを構成することもできます。デフォルトで、データ・ソースの最初のレコードが一番上の行またはノードに表示され、後続のレコードはそれより下の行またはノードに表示されます。また、ソースの最後のレコードを最初に表示するように、コンポーネントを構成することもできます。この場合、最後のレコードはコンポーネントの下の行またはノードに表示され、ユーザーは上にスクロールして先行するレコードを表示できます。また、選択した行を表示するように、コンポーネントを構成することも可能です。これは、ユーザーがコンポーネントに移動したときに、複数のパラメータに基づいて、特定の行がプログラムで選択されるようにする場合に便利です。選択された行を表示するように構成した場合、その行は表の先頭に表示され、ユーザーは上または下にスクロールして他の行を表示できます。
注意:
JavaScriptを使用して、表またはツリーを動的にサイズ変更することはできません。表、ツリーおよびツリー表の高さは初めてレンダリングされるときに設定され、JavaScript APIを使用して変更することはできません。
行をまったく選択しないか、1行だけ選択するか、複数行選択するかを構成するには、rowSelection
属性を使用します(carousel
コンポーネントの場合は複数選択はできません)。この設定により、選択した行に対してロジックを実行できます。たとえば、ユーザーが表の行の1つまたはツリーのノードの1つを選択してからボタンをクリックすると、選択された行のデータが別のページに表示され、そのページでデータを編集できるようにする場合です。
注意:
複数の選択を実行できるようにコンポーネントを構成した場合、ユーザーが行を1つ選択し、[Shift]キーを押して別の行を選択すると、間にあるすべての行が選択されます。この選択は、選択が複数のデータ・フェッチ・ブロックにまたがる場合でも保持されます。同様に、[Ctrl]キーを使用して、隣接していない行を選択することもできます。
たとえば、表が一度に25行のみフェッチするように構成されている場合に、ユーザーが100行選択すると、フレームワークにより選択が追跡されます。
コンポーネントで選択されている行(またはノード)が変更されると、コンポーネントにより選択イベントが起動されます。このイベントにより、選択解除された行や選択された行が報告されます。コンポーネントにより選択が宣言的に処理される際、選択された行でロジックを実行する必要がある場合は、それらの行にアクセスしてロジックを実行するコードを実装する必要があります。これは、マネージドBeanの選択リスナー・メソッドで実行できます。詳細は、「表の選択された行でのアクションの実行に関する必知事項」を参照してください。
パフォーマンスに関するヒント
ユーザーは、マウスとスクロールバーを使用するか、キーボードの上下の矢印キーを使用して、表内を移動できます。デフォルトでは、ユーザーが行をクリックするとすぐに選択イベントが起動されます。つまり、ユーザーが矢印キーで行間を移動している場合は、ユーザーの移動に伴い、各行で選択イベントが起動されます。
ユーザーがキーを使用して表内を移動することが予想される場合は、delaySelectionEvent
属性をtrue
に設定すると、選択イベントが300ミリ秒遅れて起動されるようにできます。ユーザーが300ミリ秒以内に別の行に移動した場合、選択イベントは取り消されます。
表、ツリーまたはツリー表の実際のデータの表示に使用するコンポーネントを選択できます。たとえば、データを読取り専用にする場合は、データの表示にoutputText
コンポーネントを使用します。反対に、データを編集できるようにする場合にはinputText
コンポーネントを使用し、リストから選択する場合にはSelectOne
コンポーネントを1つ使用します。これらのコンポーネントはすべて、列コンポーネントの子として配置されるか(表およびツリー表の場合)、nodeStamp
ファセットに配置されます(ツリーの場合)。
値の編集が可能なコンポーネントを使用してデータを表示する場合、表、ツリーまたはツリー表で、すべての行を編集可能として一度に表示するか、現在アクティブな行以外のすべての行を読取り専用として表示するかを、editingMode
属性を使用して選択できます。たとえば、図12-11に、行をすべて編集できる表を示します。ページは、ページに追加されたコンポーネント(inputText
、inputDate
およびinputComboBoxListOfValues
コンポーネントなど)を使用してレンダリングされます。
図12-11 すべての行を編集できる表
図12-12は同じ表(つまり、inputText
、inputDate
およびinputComboBoxListOfValues
コンポーネントを使用してデータを表示する)を示していますが、この表は、editingMode
をclickToEdit
に設定することにより、アクティブな行にのみ編集可能なコンポーネントが表示されるように構成されています。ユーザーは、別の行をクリックして編集可能にできます(一度に1行のみ編集可能になります)。ページを作成するために図12-11と同じ入力コンポーネントが使用されていても、編集可能でない行のデータの表示に、outputText
コンポーネントが使用されていることに注意してください。これらのコンポーネントを実際にレンダリングしている行は、アクティブな行のみです。
注意:
editingMode
をreadOnly
に設定すると、表のコンポーネントは、入力コンポーネントも含めてすべて読取り専用としてレンダリングされます。また、表全体を選択しても、editingMode
はreadOnly
に設定されます。図12-12 一度に1行のみを編集できる表
現在アクティブな行は、表のactiveRowKey
属性によって決定されます。デフォルトでは、この属性の値は表の最初に表示される行です。表(またはツリーやツリー表)がリフレッシュされると、アクティブな行が表示されていなければ、そのコンポーネントがスクロールしてアクティブな行が表示されます。ユーザーがコンテンツを編集するために行をクリックすると、その行がアクティブな行になります。
編集できる行(またはノード)を1つのみにする場合、ユーザーがある行(またはノード)から次の行へ移動し、一度に1行のデータを送信(および検証)すると、表(またはツリーやツリー表)ではPPRが実行されます。すべての行を編集できるようにする場合、現在表示されている行またはノードを超えてスクロールするなど、PPRが実行されるイベントが発生するとデータが送信されます。
注意:
ツリーと表は、ブラウザのコピー・アンド・ペーストをサポートしています。コピー可能なテキスト・フィールドにマウスを置くと、カーソルがI字状になります。マウスをクリックしてテキストをコピーすると、その行が選択された状態になります。
編集可能なコンポーネントがすべて、クリックして編集するモードで表示されるわけではありません。たとえば、HTMLの入力要素を複数行表示するコンポーネントがこれに当たります。これらのコンポーネントには次が含まれます。
SelectManyCheckbox
SelectManyListBox
SelectOneListBox
Select
OneRadio
SelectManyShuttle
パフォーマンスに関するヒント
レンダリングおよびポストバック中のパフォーマンスを向上させるには、表での編集を1行のみに構成する必要があります。
出力コンポーネントは入力コンポーネントよりも少ないHTMLを生成するため、一度に1行のみ編集することを選択した場合、ページはより迅速に表示されます。また、クライアント・コンポーネントは読取り専用行に対して作成されません。表(またはツリーやツリー表)はユーザーがある行から次の行に移動したときにPPRを実行するため、その行のデータのみ送信されます。これにより、すべてのセルの編集を許可して一度に表のすべての行のすべてのデータを送信する表よりもパフォーマンスが向上します。単一行の編集のみ許可すると、単一行のデータのみが検証のために送信され、その行のエラーのみ表示されるため、検証もより直感的になります。
表、ツリーまたはツリー表は、ユーザーのアクションに基づいてポップアップ・ダイアログが表示されるように構成できます。たとえば、ユーザーがセルまたはノード上にマウスを置いた場合に、選択された行の一部のデータが表示されるようにポップアップ・ダイアログを構成できます。ユーザーが表やツリー表の行、またはツリーのノードを右クリックした場合のために、ポップアップ・メニューを作成することも可能です。また、表やツリー表では、ユーザーが特定の行ではなく、表の任意の場所を右クリックした場合のために、ポップアップ・メニューを作成できます。
すべての表、ツリーおよびツリー表には、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
ファセットが含まれます。メニューが含まれるポップアップをこのファセットに追加すると、ユーザーが特定の行ではなく、表をクリックした場合に表示されます。
ポップアップ・メニューの作成の詳細は、「ポップアップの宣言的な作成」を参照してください。
ADF Facesでは、コレクションベース・コンポーネントの内容はサーバーでレンダリングされます。次のような場合には、クライアントがサーバー上のそのコンテンツにアクセスする必要があります。
クライアント側のアプリケーション・ロジックが、行固有のコンポーネントの状態を読み取る必要がある場合。たとえば、行の選択の変更に応じて、ページ内のその他のコンポーネント(通常はメニュー項目やツールバー・ボタン)の無効化や表示の状態をアプリケーションで更新する必要がある場合です。このロジックは、スタンプ設定されたinputHidden
コンポーネントを使用してクライアントに送信される、行固有のメタデータに依存している場合があります。これを有効化するために、アプリケーションでは、スタンプ設定されたコンポーネントから行固有の属性値を取得できる必要があります。
クライアント側のアプリケーション・ロジックが、行固有のコンポーネントの状態を変更する必要がある場合。たとえば、表の行にあるスタンプ設定されたコマンド・リンクをクリックすると、同じ行のその他のコンポーネントの状態が更新される場合です。
ピアはコンポーネント・インスタンスにアクセスしてイベント処理動作を実行することが必要な場合があります(詳細は、「ADF Facesアーキテクチャの使用について」を参照してください)。たとえば、マウスのクリックに対してクライアント側アクション・イベントを配信するには、AdfDhtmlCommandLinkPeer
クラスに、イベント・ソースとして機能するコンポーネント・インスタンスへの参照が必要です。コンポーネントでは、クライアント・リスナーや、イベント配信動作を制御するdisabled
やpartialSubmit
などの属性を含め、関連状態が保持されます。
ADF Facesフレームワークでは、クライアント側でELがサポートされないのみでなく、クライアントへの表モデル全体の送信もサポートされていないため、クライアント側のコードは、値にアクセスするようスタンプ設定されているコンポーネントに依存できません。各行で同じコンポーネント・インスタンスを再利用するかわりに、各行に新しいJavaScriptクライアント・コンポーネントが作成されます(どの行にもコンポーネントが1つ作成される必要があると仮定しています)。
そのため、クライアント上の行固有のデータにアクセスするには、それ自体がスタンプ設定されたコンポーネントを使用して値にアクセスする必要があります。クライアント側のデータ・モデルを使用せずにこれを実現するには、クライアント側の選択変更リスナーを使用します。詳細な手順は、「コレクションベースのコンポーネントからクライアント上の選択された値へのアクセス」を参照してください。
デフォルトでは、表、ツリーおよびツリー表は子を拡大するコンポーネント(たとえば、panelStretchLayout
コンポーネントの内部のpanelCollection
コンポーネント)に配置され、表、ツリーまたはツリー表は既存の領域に合せて拡大されます。ただし、列を表全体に拡大するには、columnStretching
属性を使用して、特定の列が未使用の領域全体に拡大されるように指定する必要があります。そうしないと、表はできるだけ多くの行に合せて垂直にのみ拡大されます。図12-13に示すように列は拡大されません。
図12-13 表は拡大されるが列は拡大されない
子を拡大しないコンポーネント(たとえば、vertical
に設定されたpanelGroupLayout
コンポーネントの内部のpanelCollection
コンポーネント)に配置されたときは、デフォルトでは、図12-14に示すように、表の幅は300px (27.27em単位。11pxフォント設定で換算すると300px)に設定され、デフォルトのフェッチ・サイズは25行を返すように設定されます。
図12-14 表は拡大されない
子を拡大しないコンポーネントに表を配置する場合は、autoHeightRows
属性を使用して、指定した行数より多く表示されないように表の高さを制御できます。この属性を正の整数に設定した場合、表の高さは行セットの数によって決定されます。その数値がfetchSize
属性より大きい場合は、fetchSize
属性の行数のみ返されます。autoHeightRows
を-1(デフォルト)に設定して、自動サイズ設定をオフにできます。
自動サイズ設定は、子を拡大するコンポーネントと拡大しないコンポーネントの両方で同じ表を使用する場合に役立つことがあります。たとえば、6列があり、12行を表示できる表があるとします。これを子を拡大するコンポーネントで使用する場合は、表を使用可能な領域に合せて拡大します。その表を子を拡大しないコンポーネントで使用する場合は、表の高さを修正できるようにします。ただし、表の高さを設定すると、他のコンポーネントに配置した場合に、その表は拡大されません。この問題を解決するには、autoHeightRows
表は行の数に応属性を設定します(拡大するコンポーネントでは無視され、拡大しないコンポーネントでは適用されます)。
注意:
autoHeightRows
属性のデフォルト値は、DEFAULT_DIMENSIONS
web.xmlパラメータによって決まります。親が拡大可能な場合は必ず表コンポーネントが拡大され、そうでない場合はfetchSize
属性のサイズになるようにするには、autoHeightRows
属性ではなく、DEFAULT_DIMENSIONSパラメータを設定してください。autoHeightRows
属性は、グローバル設定をオーバーライドする場合に設定します。
デフォルトでは、DEFAULT_DIMENSIONSは、autoHeightRows
の値が-1
(表は拡大されない)になるように設定されます。詳細は、「レイアウトと表コンポーネントの形状管理」を参照してください。
各種の視覚的な補助を目的に、ADFコレクションベース・コンポーネントを含む表を書式設定することができます。列データは、格納とソートが可能です。表を含むページがクライアントによってリクエストされるときには、部分ページ・レンダリングのみが行われます。
表コンポーネントの直接的な子は、column
コンポーネントである必要があります。表示されるそれぞれの列コンポーネントは、表の個別の列として表示されます。列コンポーネントには、コンテンツやイメージの表示、またはその他の機能の提供に使用されるコンポーネントが含まれます。列コンポーネントで使用可能な機能の詳細は、「列および列データ」を参照してください。
各列の子コンポーネントは、その列の各行のデータを表示します。列では、子コンポーネントは行ごとには作成されませんが、表では各行のレンダリングにスタンプ設定機能が使用されます。各子には、行ごとに一度スタンプが設定され、これがすべての行に対して繰り返されます。各行にスタンプが設定されると、現在行のデータが、EL式を使用して特定可能なプロパティにコピーされます。このプロパティに使用する名前を、表のvar
プロパティを使用して指定します。表のレンダリングが完了したら、このプロパティは削除されるか前の値に戻ります。
このスタンプ設定動作のため、一部のコンポーネントが列内で機能しない場合があります。入力および出力コンポーネントなど、大部分のコンポーネントは問題なく機能します。セル内に複数のコンポーネントを使用する必要がある場合は、それらをpanelGroupLayout
コンポーネントでラップします。表内の表など、それ自体がスタンプ機能をサポートしているコンポーネントはサポートされていません。実行時に値が動的に決定されるコンポーネントの使用方法の詳細は、「表の選択コンポーネント値の動的な決定について」を参照してください。
表にdetailStamp
ファセットを使用して、オプションで表示または非表示にできるデータを指定できます。このファセットにコンポーネントを追加すると、表の各行に、展開および縮小するためのアイコンが付いた追加の列が表示されます。ユーザーがアイコンをクリックして開くと、図12-15に示すように、ファセットに追加されたコンポーネントが表示されます。
図12-15 オプションで表示可能な追加のデータ
ユーザーが開かれた状態のアイコンをクリックして閉じると、図12-16に示すように、コンポーネントが非表示になります。
図12-16 追加のデータを非表示にすることが可能
detailStamp
ファセットの使用方法の詳細は、「表への非表示機能の追加」を参照してください。
列には、データの表示に使用されるコンポーネントが含まれます。前述したように、各項目の表示に必要な子コンポーネントは1つのみで、値は表のレンダリング時にスタンプ設定されます。列はソート可能であり、ソート時に大文字と小文字を区別するかどうかを構成できます。デフォルトでは、大文字と小文字が区別されます。
列にはフィルタリング要素を入れることもできます。ユーザーがフィルタに値を入力すると、フィルタに入力した値に一致するデータ・セットが返されます。フィルタは、大文字と小文字を区別する、または大文字と小文字を区別しないように設定できます。これが許可されるように表が構成されている場合、ユーザーは列を並べ替えることもできます。
列には、ヘッダー・ファセットとフッター・ファセットの両方があります。ヘッダー・ファセットは、列のヘッダー・テキスト属性のかわりに使用できるため、スタイル設定可能なコンポーネントを使用できます。フッター・ファセットは、列の下部に表示されます。たとえば、図12-17では、フッター・ファセットを使用して、2つの列の下部に合計が表示されています。戻された行数が表示可能な範囲を超えている場合、フッター・ファセットは表示されますが、ユーザーは最後の行までスクロールできます。
図12-17 列のフッター・ファセット
表コンポーネントには、ユーザーを支援する書式設定や視覚的な補助が多数用意されています。これらの機能を有効にし、どのように表示するかを指定できます。次の機能が含まれます。
行の選択: デフォルトでは、ユーザーは実行時に行を選択できません。ページのその他の場所または別のページにおいて、行でアクションを実行するために、ユーザーが行を選択できるようにするには、rowSelection
属性を設定して、表で行の選択を有効化します。表は、単一の行または複数の行を選択できるように構成できます。選択された行でプログラムを使用してアクションを実行する方法の詳細は、「表の選択された行でのアクションの実行に関する必知事項」を参照してください。
スクロール/ページ区切り: デスクトップ・デバイスでは、ユーザーはすべての行をスクロールできるように、デフォルトで表にスクロールバーがレンダリングされます。タブレット・デバイスでは、スクロールバーのかわりに表にページ番号が付けられ、ユーザーが特定の行のあるページにジャンプできるフッターが表示されます。デフォルトは、scrollPolicy
属性を設定することで変更できます。
表の高さ: 表の高さを絶対的(300ピクセルなど)に設定することも、autoHeightRows
属性を使用して、一度に表示する行数に基づいて表の高さを決定することもできます。詳細は、「表、ツリーおよびツリー表コンポーネントのジオメトリ管理」を参照してください。
注意:
表がpanelSplitter
コンポーネントなどのレイアウト管理コンテナに配置されている場合、表はコンテナによりサイズ設定され、autoHeightRows
は適用されません。
注意:
JavaScriptを使用して、表を動的にサイズ変更することはできません。表の高さは初めてレンダリングされるときに設定され、JavaScript APIを使用して変更することはできません。
グリッド線: デフォルトで、ADF表コンポーネントには、水平および垂直の両方のグリッド線が描画されます。これらは、horizontalGridVisible
およびverticalGridVisible
属性を使用して個別に無効化できます。
バンディング: columnBandingInterval
属性を使用して、行または列のグループが異なる背景色で交互に表示されます。これは、隣り合う行または列のグループを区別する際に役立ちます。デフォルトでは、バンディングは無効化されています。
列グループ: 表の列は、列コンポーネントをネストさせることで、列グループにグループ化できます。各グループには、すべての列をリンクする独自の列グループ見出しを設定できます。詳細は、「ページへの表の表示方法」の手順14を参照してください。
編集可能セル: 表へのデータの表示に入力テキスト・コンポーネントを使用する場合は、すべてのセルを編集できるように表を構成することも、ユーザーが明示的にセルをクリックして編集するように構成することもできます。詳細は、「表、ツリーおよびツリー表のデータの編集」を参照してください。
パフォーマンスに関するヒント
ユーザーがクリックした場合にのみセルの編集を可能にすると、表は最初はより早くロードされます。これは、表に大量のデータを表示する場合に便利です。
列の拡大: 列の幅すべてを合せても表全体に満たない場合は、columnStretching
属性を設定し、領域を埋めるために列を拡大するかどうか、拡大する場合はどの列を拡大するかを決定できます。列の最小の幅を設定して、表に多くの列があり、拡大を有効にする場合に、列が設定した最小幅より小さくならないようにすることができます。拡大する各列の幅の割合を設定して、列が拡大されたときに占める領域の量を決定することもできます。
注意:
列の最小幅の合計がビューポートの表示可能領域以上である場合、表はビューポートの外部に拡張され、ビューポートの外部にアクセスするためのスクロールバーが表示されます。
パフォーマンスに関するヒント
列の拡大はデフォルトで無効化されています。この機能を有効化すると、複雑な表(データ量の多い表や、列がネストしている表など)に使用した場合には、クライアントのレンダリング時間のパフォーマンスに影響があります。
注意:
行ヘッダーとして構成された列または固定として構成された列は拡大されません。拡大すると、ユーザーが表のスクロール可能な本体にアクセスできなくなる可能性が高くなるためです。
列の選択: ユーザーにデータの列の選択を許可できます。行の選択同様、単一の列または複数の列を選択できるように構成できます。columnSelectionListener
を使用して、新しい列がユーザーによって選択されたときに呼び出されるColumnSelectionEvent
に応答することもできます。このイベントにより、選択解除された列や選択された列が報告されます。
列の並替え: ユーザーは、実行時に列ヘッダーをドラッグ・アンド・ドロップして列を並べ替えられます。デフォルトでは、列の並替えが許可されており、panelCollection
コンポーネントのメニュー項目で処理されます。詳細は、「表メニュー、ツールバーおよびステータス・バーの表示」を参照してください。
列の固定: 列を固定し、スクロールされても見えなくならないように表を構成できます。列は、表の右側または左側に固定できます。これは、表のfreezeDirection
属性で制御されます。列のfrozen
属性を使用して、固定を開始する列を選択します。
パフォーマンスに関するヒント
列の固定を使用すると表の複雑さが増し、パフォーマンスに悪影響が及ぶことがあります。
各列コンポーネントにも、ユーザーを支援する書式設定や視覚的な補助が多数用意されています。これらの機能を有効にし、どのように表示するかを指定できます。次の機能が含まれます。
列のソート: ユーザーが、指定された列を基準とし、sortable
属性を使用して昇順または降順にコンテンツをソートできるよう列を構成できます。列ヘッダーの特別なインジケータにより、ユーザーは列がソート可能であることがわかります。ユーザーがアイコンをクリックして、前にソートされていない列をソートすると、列のコンテンツは昇順でソートされます。次に同じヘッダーをクリックすると、コンテンツは降順でソートされます。
ソートでは、デフォルトで大文字と小文字が区別されます。つまり、ソートするとabc
はABC
より前になります。かわりに、abc
とABC
とを区別せずソートするように列を構成するには、sortStrength
属性を使用します。
表をソートできるようにするには、基礎となるデータ・モデルでもソートがサポートされている必要があります。詳細は、「プログラムを使用した表の列のソートの有効化に関する必知事項」を参照してください。
コンテンツの位置合せ: align
属性を使用して、列内のコンテンツをstart、end、left、rightまたはcenterに位置合せできます。
ヒント:
アプリケーションで複数の読み方向がサポートされている場合は、left
およびright
ではなく、start
およびend
を使用します。
列の幅: width
属性を使用して、列の幅をピクセル単位の絶対値として指定できます。列を拡大可能として構成する場合、幅を割合として設定することもできます。
列のまたがり: colSpan
属性を使用して、他の列にまたがる列を構成できます。ただし、通常は、spanの値にEL式を使用して、実際には列の特定のセルのみが複数列にまたがることができるようにします。たとえば、図12-18に示すツリー表では、そのノードが親ノードである場合のみに、右にあるすべての行にまたがるようにcolSpan
の値が設定されています。
図12-18 複数列にまたがるのはノードが親のときのみ
行折返し: noWrap
属性を使用し、行を越えて列のコンテンツを折り返すかどうかを定義できます。デフォルトでは、コンテンツは折り返されません。
行ヘッダー: rowHeader
属性を使用して、一番左の列を行ヘッダーに定義できます。その場合、一番左の列は列ヘッダーと同じ外観でレンダリングされますが、スクロールしてページから見えなくなることはありません。図12-19に、最初の列が行ヘッダーとして構成されている場合に部門を表示する表がどのように表示されるかを示します。
図112-19 表の行ヘッダー
行ヘッダー列の使用を選択し、行を選択できるように表を構成した場合、ユーザーが行の上にマウスを置くと、行ヘッダー列には図12-20に示すような選択矢印が表示されます。
図12-20 行ヘッダーの選択アイコン
複数選択が許可される表では、ユーザーはマウスをクリックして行ヘッダーをドラッグし、連続した行ブロックを選択できます。また、ユーザーが上または下にドラッグすると、表が垂直に自動スクロールします。
加えて、エラーが発生した結果としてその行のコンポーネントに対するメッセージが生成された場合は、重大度を表すアイコンが行ヘッダーに表示されます。複数のメッセージが存在する場合は、重大度が最も高いアイコンが表示されます。図12-21で行ヘッダーにエラーのアイコンが表示されているのは、入力された日付が正しくないからです。
図12-21 行ヘッダーに表示されるメッセージ・アイコン
パフォーマンスに関するヒント
行ヘッダーを使用すると表の複雑さが増し、パフォーマンスに悪影響が及ぶことがあります。
ヒント:
列の並替えや列幅の変更など、ユーザーは実行時に表が表示される方法を変更できますが、アプリケーションがユーザーのカスタマイズを許可するように構成されていないかぎり、ユーザーがページを終了するとそれらの値は保持されません。詳細は、「JSFページでのユーザー・カスタマイズの許可」を参照してください。
「ADF Faces Tableの作成」ダイアログを使用して、JSFページに表を追加できます。このダイアログは、表に必要な各列へのcolumn
コンポーネントの追加にも使用できます。また、EL式を使用して基礎となるモデルまたはBeanに表をバインドできます。
注意:
アプリケーションでFusionテクノロジ・スタックを使用する場合は、データ・コントロールを使用して表を作成すると、バインディングが実行されます。詳細は、『Oracle Application Development FrameworkによるFusion Webアプリケーションの開発』の「ADFによるデータバインドされた表の作成」の章を参照してください。
ダイアログでの入力が完了して、表と列がページに追加されたら、「プロパティ」ウィンドウを使用して表または列の追加の属性を構成することや、表イベントに応答するためのリスナーを追加することができます。表のバインド先となるCollectionModel
クラスを実装する必要があります。
始める前に:
属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、「表へのデータの表示」を参照してください。
他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、「コレクションベース・コンポーネントの追加機能」を参照してください。
ページに表を表示する手順:
org.apache.myfaces.trinidad.model.CollectionModel
クラスを拡張するJavaクラスを作成します。
コレクション・コンポーネントでは、Collection
Model
クラスを使用して基礎となるコレクションのデータにアクセスします。このクラスはJSFのDataModel
クラスを拡張したものですが、索引ではなく行キーに基づいて基礎となるデータの変更をサポートしています。また、ソートなど、より高度な機能もサポートします。
java.util.List
、array
およびjavax.faces.model.DataModel
など、別のモデル・クラスも使用できます。このような別のクラスのいずれかを使用する場合は、コレクション・コンポーネントにより、インスタンスがCollectionModel
クラスに自動的に変換されますが、機能は追加されません。CollectionModel
クラスの詳細は、http://myfaces.apache.org/trinidad/trinidad-1_2/trinidad-api/apidocs/index.html
にあるMyFaces TrinidadのJavadocを参照してください。
「コンポーネント」ウィンドウの「データ・ビュー」パネルから、「表」をページにドラッグ・アンド・ドロップします。
「ADF Faces表の作成」ダイアログを使用して、表を任意の既存モデルにバインドします。表が有効なモデルにバインドされると、作成される列がダイアログにより自動的に表示されます。ダイアログを使用して列のheader
およびvalue
属性の値を編集し、データの表示に使用されるコンポーネントのタイプを選択します。または、手動で列を構成し、後日バインドすることもできます。ダイアログのヘルプを参照するには、「ヘルプ」をクリックするか、[F1]を押します。
注意:
inputText
コンポーネントを使用してCharacter Large Object (CLOB)を表示する場合は、CLOBを文字列に変換するカスタム・コンバータを作成する必要があります。変換の詳細は、「カスタムADF Facesコンバータの作成」を参照してください。
「プロパティ」ウィンドウで「共通」セクションを開きます。すでに表をモデルにバインドしてある場合は、value属性を設定します。このセクションを使用して、表固有の次の属性を設定できます。
RowSelection: 行を選択可能にする場合に値を設定します。有効な値はnone
、single
、multiple
およびmultipleNoSelectAll
です。
注意:
ユーザーは、rowSelection
属性がmultiple
に設定され、その表に行ヘッダーも含まれている場合に、行ヘッダーの列ヘッダーをクリックして表のすべての行およびすべての列を選択できます。ユーザーがすべての列および行を選択できないようにするには、rowSelection
をmultipleNoSelectAll
に設定します。
選択された行でプログラムを使用してアクションを実行する方法の詳細は、「表の選択された行でのアクションの実行に関する必知事項」を参照してください。
ColumnSelection: 列を選択可能にする場合に値を設定します。有効な値はnone
、single
およびmultiple
です。
「列」セクションを開きます。「ADF Faces Tableの作成」ダイアログを使用して表をバインドしてある場合、これらの設定を完了する必要があります。このセクションを使用して、表のバインドの変更、各行のデータへのアクセスに使用される変数名の変更、および各列に使用される表示ラベルやコンポーネントの変更を実行できます。
ヒント:
リストに表示されていないコンポーネントを使用する場合は、「プロパティ」ウィンドウで任意のコンポーネントを選択してから、手動で変更してください。
「構造」ウィンドウで、ダイアログによって作成されたコンポーネントを右クリックして「変換」をクリックします。
リストから必要なコンポーネントを選択します。これで、「プロパティ」ウィンドウを使用して新しいコンポーネントを構成できます。
ヒント:
列に複数のコンポーネントを表示する場合は、その他のコンポーネントを手動で追加し、それらをpanelGroupLayout
コンポーネントでラップします。これを行うには、次の手順を実行します。
構造ウィンドウで、1つ目のコンポーネントを右クリックし、「前に挿入」または「後ろに挿入」を選択します。挿入するコンポーネントを選択します。
デフォルトで、コンポーネントは縦に表示されます。1つの列内に複数のコンポーネントを隣接させて表示するには、[Shift]キーを押して、「構造」ウィンドウで両方のコンポーネントを選択します。選択内容を右クリックし、「囲む」を選択します。
panelGroupLayout
を選択します。
「外観」セクションを開きます。このセクションを使用し、次に示す表固有の属性を設定して、表の外観を設定します。
Width: 表の幅を指定します。ピクセル数または割合で幅を指定できます。デフォルト設定は300ピクセルです。(columnStretching
属性を使用して)列を拡大するように表を構成する場合は、幅を割合に設定する必要があります。
ヒント:
表が、子を拡大するコンポーネントの子である場合、この幅の設定はオーバーライドされ、表はコンテナに合うように自動的に拡大されます。コンポーネントの拡大方法の詳細は、「表、ツリーおよびツリー表コンポーネントのジオメトリ管理」を参照してください。
ColumnStretching: 列の幅すべてを合せても表全体に満たない場合は、この属性を設定し、領域を埋めるために列を拡大するかどうか、拡大する場合はどの列を拡大するかも決定できます。
注意:
子を拡大するコンポーネントの中に表が配置されている場合、自動的に拡大されるのは表のみです。表に合うように列を拡大する場合、列の拡大は手動で構成する必要があります。
注意:
行ヘッダーとして構成された列または固定として構成された列は拡大されません。拡大すると、ユーザーが表のスクロール可能な本体にアクセスできなくなる可能性が高くなるためです。
パフォーマンスに関するヒント
列の拡大はデフォルトで無効化されています。この機能を有効化すると、クライアントにおける複雑な表のレンダリング時間のパフォーマンスに影響する場合があります。
列の拡大を次のいずれかの値に設定できます。
blank
: 空の列を自動的に挿入して拡大する場合に使用します(表の幅全体が行の背景色になります)。
名前が指定された列: 現在表にある列を拡大する列として選択できます。
last
: 最後の列を、ウィンドウ内の使用されていない領域に合せて拡大する場合に使用します。
none
: 何も拡大されないデフォルトのオプションです。パフォーマンスを最適化する場合に使用します。
multiple
: width
属性にパーセント値が設定されたすべての列がそのパーセント値まで拡大されます。これは、他の列が(拡大されない)幅にレンダリングされた後に行われます。割合値は合計で加重されます。たとえば、これらの列のwidth属性を50%に設定した場合、各列は、他のすべての列がレンダリングされた後の残り領域の1/3を占めます。
ヒント:
列の幅は実行時に変更できますが、アプリケーションが変更の永続性を使用するように構成されていないかぎり、ユーザーがページを終了するとそれらの幅値は保持されません。変更の永続性の有効化および使用方法の詳細は、「JSFページでのユーザー・カスタマイズの許可」を参照してください。
HorizontalGridVisible: 水平のグリッド線を描画するかどうかを指定します。
VerticalGridVisible: 垂直のグリッド線を描画するかどうかを指定します。
RowBandingInterval: 色のバンディングの目的で、連続する何行で行グループを形成するかを指定します。デフォルトでは、これは0に設定されており、すべての行が同じ背景色で表示されます。別の色を使用する場合は、これを1に設定します。
ColumnBandingInterval: 列のバンディングが行われる間隔を指定します。この値により、表の列バンディングの表示が制御されます。たとえば、columnBandingInterval
が1の場合、表内にバンディングされた列が交互に表示されます。
FilterVisible: 入力されたフィルタ基準に一致する行のみが表示されるように、表にフィルタを追加できます。フィルタ処理を許可するように表を構成する場合、大文字と小文字を区別する、または大文字と小文字を区別しないようにフィルタを設定できます。詳細は、「表でのフィルタ処理の有効化」を参照してください。
ScrollPolicy: デスクトップ・デバイスでは、デフォルトで表にスクロールバーがレンダリングされ、ユーザーはすべての行をスクロールできます。タブレット・デバイスでは、スクロール・バーのかわりに表をページ区切りで表示するように表がレンダリングされます。
このデフォルトの動作を維持するには、値をauto
に設定します。表で行が必ず一連のページとして表示され、各ページに移動するナビゲーションがフッターに表示されるようにするには、値をpage
に設定します。表にスクロール・バーを常にレンダリングし、暗黙的なハイウォータマーク・スクロールを使用してスクロールされるようにするには、タブレット・デバイスに対してこの値をscroll
に設定します。この設定を使用すると、タブレットでの表データの仮想化スクロールによるパフォーマンスの問題に対処できます。maxClientRows
属性の値を設定して、ユーザーがスクロール・バックするときのデータベース・ラウンドトリップが最小になるよう、キャッシュする行数を指定できます。
大きい表で、スクロールする行が一定以上残っている場合には、滑らかにスクロールするように、この値をscrollPrefetch
に設定します。ユーザーがスクロールすると、プリフェッチがパラレルで実行されます。scrollPolicy属性の値をscrollPrefetch
に設定すると、表で必ず次のようになります。
最初に表がレンダリングされるとき、表の構成に応じて表のビューポートを埋める十分な行より多くの行がフェッチされます。たとえば、fetchSize
が25で、ビューポートの高さが12行の場合、スクロールする行が13行残っています。これはfetchSize
の半分より多いので、最初のブロックを超える追加の行はフェッチされません。一方、fetchSize
が25で、ビューポートの高さが13行の場合、スクロールする行は12行しか残っていません。これはfetchSize
の半分より少ないので、追加の行がフェッチされます。
これ以降の表のスクロールでは、スクロールする分が残っているクライアント行の数が常に監視され、残っている行数がしきい値を下回ったときに新しいデータ・ブロックのフェッチがトリガーされます。ただし、行数がわかっている表で、仮想ツールバーがサポートされている場合、ユーザーがスクロール後にマウス・ボタンを離すまでフェッチは実行されません。
注意:
デスクトップ・デバイスの場合、表がページ区切り(タブレット・デバイスの場合は、デフォルトで構成されます)になるように明示的に設定するには、scrollPolicy
属性をpage
に、autoHeightRows
属性を0
に設定する必要があります。これらの条件が満たされない場合、表にはスクロールバーが表示されます(拡大されたまたは動くコンポーネントへの子のいずれでも)。コンテナ・コンポーネントおよび表の詳細は、「表、ツリーおよびツリー表コンポーネントのジオメトリ管理」を参照してください。
テキスト属性: アクセシビリティを目的とした表のサマリーや説明だけでなく、行を表示できない場合に表示されるテキストを決定するテキスト文字列を定義できます。
「動作」セクションを開きます。このセクションを使用し、次に示す表固有の属性を設定して、表の動作を構成します。
ColumnResizing: エンド・ユーザーが実行時に列の幅をサイズ変更できるようにするかどうかを指定します。disabled
に設定した場合、列の幅はページがレンダリングされた後で設定され、ユーザーはそれらの幅を変更できません。
ヒント:
columnResizing
がtrue
に設定されている場合、ユーザーは実行時に列幅の値を変更できますが、アプリケーションが変更の永続性を使用するように構成されていないかぎり、ユーザーがページを終了するとそれらの幅値は保持されません。変更の永続性の有効化および使用方法の詳細は、「JSFページでのユーザー・カスタマイズの許可」を参照してください。
DisableColumnReordering: デフォルトでは、panelCollection
コンポーネントにデフォルトで含まれるメニュー・オプションを使用して、実行時に列を並べ替えられます。これは、ユーザーが列の順序を変更できないように変更できます。(panelCollection
コンポーネントには、表、ツリーおよびツリー表のデフォルトのメニューとツールバー・ボタンが用意されています。詳細は、「表メニュー、ツールバーおよびステータス・バーの表示」を参照してください。)
注意:
ユーザーは列の順序を変更できますが、アプリケーションがユーザーのカスタマイズを許可するように構成されていないかぎり、ユーザーがページを終了するとそれらの値は保持されません。詳細は、「JSFページでのユーザー・カスタマイズの許可」を参照してください。
FetchSize: 各データ・フェッチで戻されるブロックのサイズを設定します。デフォルトは25です。
ヒント:
表に合せるには何行必要であるかを判断するには、表の高さを取得して各行の高さで割ることで、fetchSize
属性の値を決定する必要があります。fetchSize
属性の値が小さすぎると、表を埋めるためにサーバーと何度もやりとりすることになります。値が大きすぎると、サーバーでは、データ・ソースから必要以上に行がフェッチされ、時間とメモリー使用量が増加します。クライアント側では、それらの行の処理とコンポーネントへのアタッチに時間がかかります。詳細は、「コンテンツの配信」を参照してください。データベース・アクセス速度が遅い場合は、連続表示とデータのスクロールを実行するために、fetchSize
は大きく設定してください。
ContentDelivery: データを送信するタイミングを指定します。contentDelivery
属性がimmediate
に設定されている場合、コンポーネントのレンダリングと同時にデータがフェッチされます。contentDelivery
属性がlazy
に設定されている場合は、後続のリクエスト中にデータがフェッチされてクライアントに送信されます。属性がwhenAvailable
(デフォルト)に設定されている場合、レンダラはデータが使用可能かどうかをチェックします。使用可能な場合、コンテンツは即時に配信されます。使用可能でない場合は、遅延配信が使用されます。詳細は、「コンテンツの配信」を参照してください。
AutoHeightRows: 表に初期状態で表示する行の数を指定します。返された行の数がこの値を超えている場合は、スクロールバーが表示されます。表がfetchSize
と同じサイズになるようにするには、0
に設定します。表の親コンテナが子を拡大するように構成されている場合に親コンテナいっぱいに表が拡大されるようにするには、-1
を設定します(表の拡大の詳細は、「表、ツリーおよびツリー表コンポーネントのジオメトリ管理」を参照)。それ以外の場合は、fetchSize
の現在の設定より小さい特定の数に設定してください。
注意:
autoHeightRows
属性の設定について、次の点に注意してください。
inlineStyle
属性に高さを指定しても効果はなく、AutoHeightRows
の値でオーバーライドされます。
inlineStyle
属性にmin-height
またはmax-height
を指定することは推奨されず、autoHeightRows
属性と互換性がありません。
コンポーネントをpanelSplitter
のようなレイアウト管理コンテナに配置すると、このコンテナによりコンポーネントのサイズが指定されます(自動のサイズ指定は発生しません)。
注意:
autoHeightRows
属性のデフォルト値は、DEFAULT_DIMENSIONS
web.xmlパラメータによって決まります。親が拡大可能な場合は必ず表コンポーネントが拡大され、そうでない場合はfetchSize
属性のサイズになるようにするには、autoHeightRows
属性ではなく、DEFAULT_DIMENSIONSパラメータをauto
に設定してください。
DEFAULT_DIMENSIONSパラメータをauto
に設定し、子を拡大しない親の中に表を配置する場合、autoHeightRows
属性をオーバーライドする値がなければ、表の幅はAFStretchWidth
スタイル・クラスから取得されます。この場合、表の幅はデフォルトで子の列コンポーネントを収容できるように拡大されます。
autoHeightRows
属性は、グローバル設定をオーバーライドする場合に設定します。
デフォルトでは、DEFAULT_DIMENSIONSは、autoHeightRows
の値が-1
(表は拡大されない)になるように設定されます。詳細は、「レイアウトと表コンポーネントの形状管理」を参照してください。
DisplayRow: 最初に表示される際に表に表示する行を指定します。使用可能な値は、表の上部に最初の行を表示する場合はfirst
、表の下部に最後の行を表示する場合はlast
(ユーザーが先行する行を表示するには上にスクロールする必要があります)、表で最初に選択された行を表示する場合はselected
です。
注意:
この属性が正常に機能するには、表モデルの合計の行数が把握されている必要があります。
EditingMode: 編集可能なコンポーネントについて、すべての行を編集可能にするか(editAll
)、ユーザーが行をクリックした場合にその行を編集可能にするか(clickToEdit
)、あるいは表を読取り専用に設定するか(readOnly
)を指定します。詳細は、「表、ツリーおよびツリー表のデータの編集」を参照してください。
ヒント:
clickToEdit
を選択した場合は、アクティブな行のみ編集できます。この行はactiveRowKey
属性によって決定されます。デフォルトでは、表が最初にレンダリングされるときに、アクティブな行は最初に表示される行です。ユーザーが別の行をクリックすると、その行がアクティブな行になります。activeRowKey
属性に別の値を設定することで、この動作を変更できます。
ContextMenuSelect: ポップアップ・メニューを開くために右クリックする際に、行を選択するかどうかを指定します。true
に設定すると、行が選択されます。ポップアップ・メニューの詳細は、「ポップアップ・ダイアログ、メニューおよびウィンドウの使用方法」を参照してください。
FilterModel: filterVisible
とともに使用します。詳細は、「表でのフィルタ処理の有効化」を参照してください。
様々なリスナー: 表で対応するイベントが起動された場合に実行されるメソッドにリスナーをバインドします。詳細は、「イベントの処理」を参照してください。
「拡張」セクションを開き、次の表固有の属性を設定します。
activeRowKey: clickToEdit
を選択すると、アクティブな行のみを編集できます。この行はactiveRowKey
属性によって決定されます。デフォルトでは、表が最初にレンダリングされるときに、アクティブな行は最初に表示される行です。ユーザーが別の行をクリックすると、その行がアクティブな行になります。activeRowKey
属性に別の値を設定することで、この動作を変更できます。
DisplayRowKey: 最初に表示される際に表に表示する行キーを指定します。値が文字列ではない場合があるため、属性は宣言的にではなくプログラムで設定する必要があります。この属性を指定すると、displayRow
属性がオーバーライドされます。
注意:
この属性が正常に機能するには、表モデルの合計の行数が把握されている必要があります。
「その他」セクションを開き、次の設定を行います。
BlockRowNavigationOnError: 検証エラーが存在する行からユーザーが移動できるようにする場合に指定します。always
に設定すると、行の検証エラーが発生したときは常に、ユーザーが別の行に移動することは禁止されます。never
に設定すると、ユーザーが別の行への移動を禁止されることはなくなります。auto
(デフォルト)に設定すると、ユーザーが移動できるかどうかはフレームワークによって決定されます。
たとえば、表の値がそのページ上の別のコンポーネントとの間で共有されていることがあります。1つの表で、ユーザーが多数のレコードを表示できるようになっているとします。特定のレコードが選択されたときに、その情報がフォーム内に表示されます。ユーザーがそのフォームでデータを変更したことが原因でエラーが発生した場合に、ユーザーが表をスクロールしてそのレコードから移動することができないようにするとします。この例の場合は、BlockRowNavigationOnError
を「always」に設定します。
FreezeDirection: 列を固定可能にする場合は、列を表の先頭(LTRロケールの左側)と表の末尾(LTRロケールの右側)のどちらから固定するかを指定します。固定を開始する列を、該当の列のfrozen
属性を使用して構成する必要があります。
たとえば、最初の3列を固定する場合を考えます。表のfreezeDirection
をstart
に設定し、3番目の列のfrozen
をtrue
に設定します。
最後の4列を固定する場合は、freezeDirection
をend
に設定し、最後から4番目の列のfrozen
をtrue
に設定します。
SelectionEventDelay: ユーザーが上下の矢印キーを使用して表内を移動することが予想される場合は、true
に設定します。
ユーザーは、マウスとスクロールバーを使用するか、上下の矢印キーを使用して、表内を移動できます。デフォルトでは、ユーザーが行をクリックするとすぐに選択イベントが起動されます。つまり、ユーザーが矢印キーで行間を移動している場合は、ユーザーの移動に伴い、各行で選択イベントが起動されます。
ユーザーがキーを使用して表内を移動することが予想される場合は、selectionEventDelay
属性をtrue
に設定すると、選択イベントが300ミリ秒遅れて起動されるようになります。ユーザーが300ミリ秒以内に別の行に移動した場合、選択イベントは取り消されます。
構造ウィンドウで列を選択します。「プロパティ」ウィンドウの「共通」セクションを開いて、次の列固有の属性を設定します。
HeaderText: 列のヘッダーに表示するテキストを指定します。outputText
コンポーネントを含むheaderファセットを追加する場合と等しい出力内容が生成されるため便利です。outputText
以外のコンポーネントを使用する場合は、かわりに列のheader
ファセットを使用する必要があります(詳細は手順16を参照してください)。header
ファセットを追加すると、headerText
属性の値は列ヘッダーにレンダリングされません。
Align: この列の配置を指定します。start
、end
およびcenter
を使用して、左から右への文字表示でそれぞれ左揃え、右揃え、中央揃えにします。left
またはright
の値は、左から右と右から左のどちらの文字表示であるかにかかわらず、左揃えまたは右揃えのセルが必要な場合に使用できます。デフォルト値はnull
で、これはスキンに依存し、行のヘッダー列とデータ列の対比で異なることを示します。スキンの詳細は、「スタイルおよびスキンを使用した外観のカスタマイズ」を参照してください。
Sortable: 列をソート可能にするかどうかを指定します。ソート可能な列には、クリックするとその列のプロパティで表がソートされるヘッダーがあります。列をソート可能にするには、sortable
属性をtrue
に設定し、この列のプロパティによるソートが、基礎となるモデルでサポートされている必要があることに注意してください。詳細は、「プログラムを使用した表の列のソートの有効化に関する必知事項」を参照してください。
注意:
列選択が有効になっている場合、列ヘッダーをクリックすると、列をソートするかわりに列が選択されます。この場合、列は昇順/降順ソート・インジケータをクリックすることでソートできます。
SortStrength: ソート時に重要とみなされる差異のレベルを指定します。次の1つを選択します(これらの値は、Java Collator
オブジェクトでの値と同じです)。
Primary
: ソートでは文字自体が考慮されます。大文字と小文字の違いやアクセント記号は無視されます。abc
、ÁBC
、ábc
、ABC
をソートすると、abc
、ÁBC
、ábc
、ABC
(出現順)となります。これは、大文字と小文字を区別しない場合に指定します。
Secondary
: 文字を考慮してソートされ、その後でアクセント記号が考慮されます。大文字/小文字は無視されます。abc
、ÁBC
、ábc
およびABC
は、abc
、ABC
、ÁBC
、ábc
とソートされます。アクセントのないロケールでは、結果的に大文字と小文字を区別しない検索が行われます。
Tertiary
: 文字を考慮してソートされ、その後でアクセント記号、大文字と小文字の違いの順に考慮されます。abc
、ÁBC
、ábc
、ABC
をソートするとabc
、ABC
、ábc
、ÁBC
となります。アクセントのないロケールでは、結果的に大文字と小文字を区別する検索が行われます。
Identical
: 文字、アクセント、大文字/小文字、および他のあらゆる差異(句読点付きの単語など)が考慮されます。abc
、ab-c
、ÁBC
、ábc
およびABC
は、abc
、ABC
、ábc
、ÁBC
、ab-c
とソートされます。この結果は大文字と小文字を区別する検索となり、これがデフォルトです。
Filterable: 列をフィルタ処理可能にするかどうかを指定します。フィルタ処理可能な列には、列ヘッダーの上部にフィルタ・フィールドが配置されます。列をフィルタ処理可能にするには、この属性をtrue
に設定し、表にfilterModel
属性を設定する必要があることに注意してください。リーフ列のみがフィルタ処理可能で、フィルタ・コンポーネントは、列ヘッダーが存在する場合にのみ表示されます。この列のsortProperty
属性は、filterModel
クラスのfilterProperty
属性のキーとして使用する必要があります。
注意:
フィルタ処理が有効化されている(filterable
=true
)列には、フィルタ基準入力フィールドとして使用する入力コンポーネントを指定できます。これを実行するには、列にフィルタ・ファセットを追加し、入力コンポーネントを追加します。詳細は、「表でのフィルタ処理の有効化」を参照してください。
「外観」セクションを開きます。このセクションを使用し、次に示す列固有の属性を使用して、列の外観を設定します。
DisplayIndex: 列の表示順序索引を指定します。列を並べ替えることが可能で、displayIndex
属性に基づいて表に表示されます。displayIndex
属性値が設定されていない列は、データ・ソースでの順序に基づいて最後に表示されます。親列の外にある子の列を並べ替えることはできないため、displayIndex
属性はトップレベルの列にのみ適用されます。
Width: 列の幅を指定します。表で列の拡大を使用する場合は、幅の割合を入力する必要があります。
列の拡大では、列の幅の割合が重みとして扱われます。たとえば、すべての列が50%の幅で、3つを超える列がある場合、各列には領域が均等に割り当てられますが、依然としてminWidth
属性に設定された値が適用されます。
割合としての幅は領域の実際の割合ではなく重みであるため、表で列の拡大がオンになっていて、1列のみが割合の幅で拡大されるものとしてリストされている場合、その列は、残りの列のピクセル幅で指定されていない、表の残り領域をすべて使用します。
MinimumWidth: 列幅の最低ピクセル数を指定します。ユーザーが列のサイズ変更を試行すると、この最小幅が強制されます。また、列がフレキシブルな場合にも、この最小幅より小さいサイズには縮小されません。ピクセル幅が定義されていて最小幅の方が大きい場合、最小幅は2つのうち小さい方の値になります。デフォルトで、最小幅は10ピクセルです。
ShowRequired: 対応する属性にデータが必要な場合に、列ヘッダーにアスタリスクを表示するかどうかを指定します。
HeaderNoWrapおよびNoWrap: コンテンツをヘッダーおよび列内で折り返すかどうかを指定します。
RowHeader: 列を表の行ヘッダーにする場合は、true
に設定します。
パフォーマンスに関するヒント
行ヘッダーを使用すると表の複雑さが増し、パフォーマンスに悪影響が及ぶことがあります。
「動作」セクションを開きます。このセクションを使用し、次に示す列固有の属性を使用して、列の動作を構成します。
SortProperty: この列によって表示されるプロパティを指定します。これは、フレームワークによって列のデータのソートに使用されるプロパティです。
Frozen: 列を固定するかどうかを指定します。固定すると、スクロールしたときにページから消えることはなくなります。固定列までの表の列は、ヘッダーでロックされ、その他の列とともにスクロールされません。親を固定せずに子の列を単独で固定することはできないため、frozen属性はトップレベルの列にのみ適用されます。
注意:
デフォルトでは、この列とそれよりも左の列が固定されます。つまり、この列とそれよりも左にある列はスクロールされません。これを変更するには、表コンポーネントのfreezeDirection
属性をend
に設定します。デフォルトでは、start
に設定されています。
パフォーマンスに関するヒント
固定された列を使用すると表の複雑さが増し、パフォーマンスに悪影響が及ぶことがあります。
Selected: true
に設定すると、最初のレンダリング時に列が選択されます。
この列が後続の列にまたがるようにするには、「その他」セクションを開いてColSpanを設定します。これには、その列がまたがる列の数を設定するか、表の最後までまたがる場合はALLを設定できます。その列のすべてのセルをまたがらせるわけではない場合は、EL式を使用し、解決した結果が特定のセルとなるように式を作成します。
次の例に、ツリー表コンポーネントで親ノードのみがすべての列にまたがるようにcolSpanを設定する方法を示します。
<af:column id="c1" sortable="true" sortProperty="Dname"
colSpan="#{testBean.container ? 'ALL' : '1'}"
headerText="DepartmentName">
<af:outputText value="#{node.Dname}" id="ot2"/>
</af:column>
次の例に、対応するマネージドBeanコードを示します。
public class TestBean { public boolean isContainer() { return _treeTable.isContainer(); } }
既存の表に列を追加するには、「構造」ウィンドウで表を右クリックし、「表の中に挿入」→「列」を選択します。列グループを作成するには、列コンポーネントをドラッグし、ヘッダーになるコンポーネントに子としてドロップします。引き続き列を追加して、グループを作成します。親列にheaderText
属性を設定します。
表にファセットを追加するには、表を右クリックして「ファセット - 表」を選択し、追加するファセットのタイプを選択します。その後、ファセットに直接コンポーネントを追加できます。
ヒント:
JSPまたはJSPX上のファセットに配置できる子コンポーネントは1つのみであるため、複数の子コンポーネントを追加する場合は、これらの子コンポーネントを1つのコンテナ(たとえばpanelGroupLayoutコンポーネントやgroupコンポーネント)の中にラップする必要があります。Faceletページ上のファセットには、複数のコンポーネントを配置できます。
列にファセットを追加するには、列を右クリックして「ファセット - 列」を選択し、追加するファセットのタイプを選択します。その後、ファセットに直接コンポーネントを追加できます。
ヒント:
JSPまたはJSPX上のファセットに配置できる子コンポーネントは1つのみであるため、複数の子コンポーネントを追加する場合は、これらの子コンポーネントを1つのコンテナ(たとえばpanelGroupLayoutコンポーネントやgroupコンポーネント)の中にラップする必要があります。Faceletページ上のファセットには、複数のコンポーネントを配置できます。
列にコンポーネントを子として追加し、データを表示します。
コンポーネントの値は、表のvar
属性および表示する属性の変数値セットにバインドする必要があります。たとえば、File Explorerアプリケーションの表では、var
属性の値としてfile
が使用されており、1列目に各行のファイル名が表示されています。そのため、ディレクトリ名の表示に使用される出力コンポーネントの値は、#{file.name}
です。
ヒント:
列の直接の子が入力コンポーネントの場合は、その幅を列幅に適切な幅に設定してください。幅が親列にとって広すぎる大きさに設定されていると、ブラウザにより、テキスト入力カーソルが必要以上に大きく拡大され、隣接する列を隠してしまう可能性があります。たとえば、inputText
コンポーネントのサイズが80ピクセルで、その親列のサイズが20ピクセルに設定されている場合、その表の入力カーソルは、隣接する列のクリック可能領域を覆ってしまいます。
入力コンポーネントが列の直接の子ではない場合に、サイズが自動的に設定されるようにするには、contentStyle="width:auto"
を設定します。
JDeveloperを使用してページに表を追加すると、JDeveloperにより、各属性の列のある表が作成されます。表をモデルにバインドすると、列にはモデルの属性が反映されます。まだモデルにバインドしていない場合は、JDeveloperにより、デフォルト値を使用して列が作成されます。デフォルト値の変更(列の追加/削除、列ヘッダーの変更など)は、表作成ダイアログで行うことも、後で「プロパティ」ウィンドウを使用して行うこともできます。
次の例に、File Explorerアプリケーション内の表の省略形のページ・コードを示します。
<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" sortStrength="identical" 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" sortStrength="identical" 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:link text="#{explorerBundle['global.properties']}" partialSubmit="true" action="#{explorer.launchProperties}" returnListener="#{explorer.returnFromProperties}" windowWidth="300" windowHeight="300" useWindow="true"> </af:link> </af:column> </af:table>
表を含むページがリクエストされ、コンテンツ配信がlazy
に設定されている場合、ページでは最初は標準のライフサイクルが実行されます。ただし、そのリクエスト中にデータがフェッチされるのではなく、独立した特別なPPRリクエストが実行されます。ページのレンダリング直後であるため、レンダー・レスポンス・フェーズのみが実行され、対応するデータがフェッチおよび表示されます。ユーザーのアクションにより後続のデータ・フェッチが実行される場合(表のスクロールなど)、別のPPRリクエストが実行されます。図12-22に、2番目のPPRリクエスト中の表を含むページを示します。データがフェッチされていることをユーザーに通知するメッセージが表示されます。
図12-22 2番目のPPRリクエストでデータをフェッチする表
ユーザーがソート可能な列のヘッダーをクリックすると、table
コンポーネントによりSortEvent
イベントが生成されます。このイベントにはgetSortCriteria
プロパティがあり、これを使用して、ソートの強さとともに表のソートに使用する必要のある基準が返されます。表は、基礎となるCollectionModel
インスタンスにsetSortCriteria()
メソッドをコールしてこのイベントに対応し、登録済の任意のSortListener
インスタンスをコールします。
表の列のソートを有効にできるのは、基礎となるモデルでソートがサポートされている場合のみです。モデルがCollectionModel
インスタンスの場合は、次のメソッドを実装する必要があります。
public boolean isSortable(String
propertyName
)
public List getSortCriteria()
public void setSortCriteria(List
criteria
)
2番目と3番目のメソッドの基準はリストであり、このリストの各項目はorg.apache.myfaces.trinidad.model.SortCriterion
(ソートの強さをサポートしています)のインスタンスです。
詳細は、MyFaces TrinidadのWebサイト(http://myfaces.apache.org/trinidad/index.html
)を参照してください。
モデルがCollectionModel
インスタンスではない場合、表コンポーネントはそのモデルをorg.apache.myfaces.trinidad.model.SortableModel
インスタンスへとラップし、ソート可能なCollectionModel
インスタンスへと変換します(SortableModel
はCollectionModel
を拡張し、ソート機能を実装する具体クラスです)。この場合、表は実際のデータを調べ、どのプロパティがソート可能であるか判断します。java.lang.Comparable
を実装するデータを含む列は、すべてソート可能です。この表によるソートの自動サポートは、CollectionModel
インスタンスに直接ソートするほど効率的ではありませんが、小さなデータセットでは十分、有効です。変換されたモデルを含む表では、1つの列のみソートすることができるので、複数列の表のソート(通常、複数のソート条件を指定することで実行されます)は変換されたモデルではサポートされません。
注意:
基礎になる表モデルがCollectionModel
インスタンスではなく、複数列のソートが必要な場合、panelCollection
コンポーネント内の表を使用することを検討してください。パネルのユーザー・インタフェースでは、変換されたモデルを含む表により提供される自動ソートがサポートしていなくても、ユーザーは複数のソート条件を使用してソートできます。panelCollection
コンポーネントの詳細は、「表、ツリーまたはツリー表を含むpanelCollectionの追加方法」を参照してください。
コレクションベースのコンポーネントでは、ユーザーが1つ以上の行を選択し、その行に対してなんらかのアクションを実行できます(carouselコンポーネントでは複数選択はサポートされません)。
コンポーネントの選択状態が変更されると、選択イベントが起動されます。selectionEvent
イベントは、選択解除された行と選択された行をレポートします。
コンポーネントの選択イベントをリスニングするには、selectionListener
属性を使用するか、addselectionListener()
メソッドで表にリスナーを追加して、コンポーネントにリスナーを登録します。これにより、リスナーは選択された行にアクセスし、それらの行に対してアクションを実行できます。
RowKeySet
オブジェクトは、現在の選択内容、つまり選択されている1つ以上の行であり、コンポーネントのgetSelectedRowKeys()
メソッドをコールすることで取得できます。プログラムを使用して選択内容を変更するには、次のいずれかを実行します。
RowKeySet
オブジェクトでrowKey
オブジェクトを追加するか、rowKey
オブジェクトを削除します。
コンポーネントに対してsetRowIndex()
またはsetRowKey()
メソッドをコールして、特定の行を現在行にします。その後、RowKeySet
オブジェクトに対してadd()
またはremove()
メソッドをコールして、その行を選択内容に追加するか、選択内容から削除できます。
次の例に、ユーザーが行を選択してから「削除」ボタンをクリックしてこれらの行を削除できる表の部分を示します。アクション・リスナーは、mybean
マネージドBeanのperformDelete
メソッドにバインドされます。
<af:table binding="#{mybean.table}" rowselection="multiple" ...> ... </af:table> <af:button text="Delete" actionListener="#{mybean.performDelete}"/>
次の例に、選択されたすべての行を反復し、それぞれにmarkForDeletion
メソッドをコールするアクション・メソッドperformDelete
を示します。
public void performDelete(ActionEvent action) { UIXTable table = getTable(); Iterator selection = table.getSelectedRowKeys().iterator(); Object oldKey = table.getRowKey(); try { 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(); } } finally { // restore the old key: table.setRowKey(oldKey); } }
注意:
table/tree/treeTableにsetRowKey
およびsetRowIndex
を使用して操作のために現在のレコードを変更した場合は、その操作後に古い現在のレコードをリストアする必要があります。そうしないと、古い現在のレコードをリストアしないことによって、アプリケーション・エラーが発生することがあります。表にselectOne
コンポーネントを使用する場合がありますが、各行でコンポーネントに異なる選択内容が表示される必要があります。そのため、実行時に項目のリストを動的に決定する必要があります。
個々の項目にスタンプを設定するにはforEach
コンポーネントを使用する必要があると考える可能性がありますが、forEach
はCollectionModel
インスタンスと連携しないため機能しません。また、表で使用されるようなコンポーネント管理のEL変数を使用するEL式にはバインドできません。forEach
コンポーネントはJSFタグの実行ステップで関数を実行しますが、表では次に示すコンポーネントのエンコーディング・ステップで実行します。そのため、forEach
コンポーネントは表の準備ができる前に実行され、反復関数は実行されません。
selectOne
コンポーネントの場合、直接の子はitems
コンポーネントであることが必要です。items
コンポーネントは行変数(<f:items value="#{row.Items}"/>
など)に直接バインドできますが、こうすると、基礎となるモデルを変更できなくなります。
かわりに、次の例に示すように、項目のリストを作成するマネージド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; }
ページの1つのコンポーネントからリストにアクセスすることができます。
<af:table var="row"> <af:column> <af:selectOneChoice value="#{row.myValue}"> <f:Items value="#{page_backing.Items}"/> </af:selectOneChoice> </af:column> </af:table>
editingMode属性の値をreadOnlyに設定することで、表を読取り専用に設定できます。editingMode属性をclickToEditタイプに設定した場合、表は通常のclickToEdit動作になります。
editingMode
属性に適切な値を設定すると、編集可能または読取り専用として、あるいは行またはノード・タイプをクリックした場合に編集可能として表をレンダリングできます。editingMode
属性をreadOnly
値に設定すると、その表のコンポーネントは、入力コンポーネントも含めてすべて読取り専用としてレンダリングされます。editingMode
をclickToEdit
値に設定した場合、表は通常のclickToEdit
動作になります。
web.xml
のパラメータoracle.adf.view.rich.table.clickToEdit.initialRender.readOnly
を設定すると、アプリケーションにおけるclickToEdit
タイプの表はすべて、最初にロードされるときにのみ読取り専用としてレンダリングされます。その他のeditingMode
を使用する表は、いずれも影響を受けません。詳細は、「表を最初に読取り専用としてレンダリング」を参照してください。
表のvar
ステータスは、新しい変数readOnly
(varStatus.readOnly
)で更新されます。これによって、行の現在のステータスが読取り専用かどうか、情報が取得されます。アプリケーションで、他の条件演算子とともにこの変数を使用すると、レンダリングの必要なコンポーネントを判定できます。varStatus.readOnly
を使用して、編集可能な行の入力テキストと読取り専用の行の出力テキストをレンダリングするサンプル・コードを次に示します。
varStatus
属性は、次のように追加します。<af:table value="#{bindings.EmpView1.collectionModel}" var="row" rows="#{bindings.EmpView1.rangeSize}" emptyText="#{bindings.EmpView1.viewable ? 'No data to display.' : 'Access Denied.'}" fetchSize="#{bindings.EmpView1.rangeSize}" rowBandingInterval="0" id="t1" inlineStyle="width:1000px;" editingMode="clickToEdit" varStatus="vars" binding="#{backingBeanScope.Backing.t1}" partialTriggers="::cb4 ::cb5 ::cb6 ::cb7 deptno1Id" columnSelection="single">
varStatus
属性は、次のように使用できます。<af:column headerText="switch" id="c100" width="130px"> <af:inputText value="#{row.bindings.Hiredate.inputValue}" required="#{bindings.EmpView1.hints.Hiredate.mandatory}" columns="#{bindings.EmpView1.hints.Hiredate.displayWidth}" maximumLength="#{bindings.EmpView1.hints.Hiredate.precision}" shortDesc="#{bindings.EmpView1.hints.Hiredate.tooltip}" id="it2" rendered="#{!vars.readOnly}"> <af:validator binding="#{row.bindings.Hiredate.validator}"/> <af:convertDateTime pattern="#{bindings.EmpView1.hints.Hiredate.format}"/> </af:inputText> <af:outputText value="outputtext #{row.Hiredate}" id="ot2" rendered="#{vars.readOnly}"> <af:convertDateTime pattern="#{bindings.EmpView1.hints.Hiredate.format}"/> </af:outputText> </af:column>
ADFコレクションベースのコンポーネントを使用して作成した表でコンテンツを表示するとき、detailStamp
ファセットを使用すると、コンテンツの部分ごとに表示と非表示を切り替えることができます。コンテンツにはトグル・アイコンが表示され、ユーザーがそれをクリックすると非表示のテキストがポップアップ・ウィンドウで表示されます。
表にdetailStamp
ファセットを使用して、表示または非表示にできるデータを指定できます。このファセットにコンポーネントを追加すると、表に、切替えアイコンが付いた追加の列が表示されます。ユーザーがアイコンをクリックすると、ファセットに追加されたコンポーネントが表示されます。ユーザーが再度切替えアイコンをクリックすると、コンポーネントが非表示になります。図12-23に、コンテンツがdetailStamp
ファセットに追加された際に表示される追加の列を示します。
注意:
detailStamp
ファセットを使用する表がスクリーン・リーダー・モードでレンダリングされると、そのファセットのコンテンツがポップアップ・ウィンドウに表示されます。アクセシビリティの詳細は、「アクセス可能なADF Facesページの開発」を参照してください。
図12-23 detailStampファセットが表示されていない表
図12-24に、1行目のdetailStamp
ファセットが表示されている同じ表を示します。
図12-24 表示されているdetailStampファセット
ファセットのrendered
属性にEL式を使用して、切替えアイコンと詳細を表示するかどうかを決定できます。たとえば、ショッピング・カート・ページでdetailStamp
ファセットを使用して、ギフト・ラッピング情報を表示するとします。ただし、すべての注文アイテムにギフト・ラッピング情報があるわけではないため、注文アイテムに表示する情報がある場合にのみ切替えアイコンを表示します。表示する情報があるかどうかを決定するメソッドをマネージドBeanに作成し、rendered
属性をそのメソッドにバインドできます。図12-25に、表示する情報がある行に対してのみアイコンが表示されている同じ表を示します。
図12-25 条件付きdetailStampファセット
注意:
列を固定できるように表を設定している場合、detailStamp
ファセットを表示すると固定機能が働かなくなります。つまり、詳細が表示されている間、ユーザーは列を固定できません。
detailStamp
ファセットを使用するには、表示または非表示にするデータにバインドされているコンポーネントをファセットに挿入します。
始める前に:
属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、「表への非表示機能の追加」を参照してください。
他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、「コレクションベース・コンポーネントの追加機能」を参照してください。
detailStampファセットを使用する手順:
注意:
アプリケーションでFusionテクノロジ・スタックを使用する場合、データ・コントロールから属性をドラッグし、detailStamp
ファセットにドロップできます。コードを変更する必要はありません。
コレクションベースのコンポーネントを使用して作成したADF表では、表のfilterModel
属性オブジェクトがFilterableQueryDescriptor
クラスのインスタンスにバインドされている場合、表のデータをフィルタ処理できます。
値がフィルタに一致する行のみを表に表示するために使用できるフィルタを表に追加できます。有効化されて、表示に設定されている場合、検索可能な各列の上に検索条件入力フィールドが表示されます。
たとえば、図12-27の表は、Location
の値が1700である行のみを表示するようにフィルタ処理されています。
図12-27 フィルタ処理された表
フィルタ処理された表の検索はQuery-by-Exampleに基づいており、QBEテキストまたは日付入力フィールド書式を使用します。検索基準を変更するための>
や<
などの演算子の文字を入力できるようにするため、入力バリデータは無効になっています。たとえば、数値列の検索条件として>1500
を入力できます。ワイルドカード文字もサポートされます。検索は、大文字と小文字を区別する、または大文字と小文字を区別しないようにできます。列がQBEをサポートしていない場合、検索基準入力フィールドはその列に対してレンダリングを行いません。
フィルタ処理機能では、データを表にフィルタ処理するためのモデルが使用されます。表のfilterModel
属性オブジェクトは、FilterableQueryDescriptor
クラスのインスタンスにバインドする必要があります。
注意:
アプリケーションでFusionテクノロジ・スタックを使用する場合は、データ・コントロールを使用して表を作成すると、フィルタ処理が作成されます。詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』の「ADFによるデータバインドされた表の作成」の章を参照してください
次の例では、表のfilterVisible
属性は、フィルタ入力フィールドを有効にするために、true
に設定されています。フィルタする各列に対して、sortProperty
属性をfilterModel
インスタンスの関連する列に設定し、filterable
属性をtrue
に設定する必要があります。
<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>
表にフィルタ処理機能を追加するには、まずフィルタ処理機能を提供するクラスを作成します。次に表をそのクラスにバインドし、フィルタ処理機能を使用するよう表と列を構成します。フィルタ処理機能を使用する表では、headerText
属性に値が設定されているか、フィルタ処理される列のheader
ファセットにコンポーネントが含まれている必要があります。これにより、フィルタ・コンポーネントが表示されます。また、filterModel
クラスではsortProperty
属性が使用されるため、列もソート可能に構成されている必要があります。
始める前に:
属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、「表でのフィルタ処理の有効化」を参照してください。
他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、「コレクションベース・コンポーネントの追加機能」を参照してください。
表にフィルタ処理機能を追加する手順:
FilterableQueryDescriptor
クラスのサブクラスであるJavaクラスを作成します。
getFilterConjunctionCriterion
メソッドから返されるConjunctionCriterion
オブジェクトはnull
にしないでください。このクラスの詳細は、ADF Faces Javadoc
を参照してください。
「表へのデータの表示」で説明されているように、表を作成します。
「構造」ウィンドウで表を選択し、次の属性を「プロパティ」ウィンドウで設定します。
FilterVisible: 検索可能な列の上にフィルタ条件入力フィールドを表示する場合はtrue
に設定します。
FilterModel: 手順1
で作成したFilterableQueryDescriptorクラスのインスタンスにバインドします。
ヒント:
フィルタにinputText
コンポーネント以外のコンポーネント(inputDate
コンポーネントなど)を使用する場合は、filterVisible
をtrue
に設定するかわりに、filter
ファセットに必要なコンポーネントを追加できます。これを行うには、次の手順を実行します。
「構造」ウィンドウで、フィルタ処理する列を右クリックし、「af:columnの中に挿入」→「JSF Core」→フィルタ・ファセットを選択します。
「コンポーネント」ウィンドウから、コンポーネントをファセットにドラッグ・アンド・ドロップします。
コンポーネントの値を、手順1で作成したFilterableQueryDescriptor
クラス内の対応する属性に設定します。値では、次の例のように、行に使用される変数を考慮する必要があります。
#{af:inputDate label="Select Date" id="name" value="row.filterCriteria.date"}
「構造」ウィンドウで表の列を選択し、「プロパティ」ウィンドウで表の各列に対して次の設定を行います。
Filterable: true
に設定します。
FilterFeatures: caseSensitive
またはcaseInsensitive
に設定します。指定されない場合、大文字と小文字の区別はモデルによって決定されます。
ADF Facesのツリー・コンポーネントを使用すると、任意の階層データを表示できます。
ADF Facesツリー・コンポーネントには、組織図や階層ディレクトリ構造などの階層データが表示されます。これらのタイプのデータには一連の最上位レベル・ノードがある場合があり、構造内の各要素は他の要素を含むように拡張できます。たとえば、組織図では、階層の任意の数の従業員が任意の数の直属の部下を持つことができます。ツリー・コンポーネントを使用すると、従業員の直属の部下が子ノードとして表示される階層を表示できます。
ツリー・コンポーネントでは、複数のルート要素がサポートされます。データは構造を表す形式で表示され、各要素が適切なレベルにインデントされて階層内での適切なレベルを示し、その親に接続されます。ユーザーは、階層の一部を展開および縮小できます。図12-28に、File Explorerアプリケーションのディレクトリの表示に使用されたツリーを示します。
図12-28 File Explorerアプリケーションのツリー・コンポーネント
ADF Facesのツリー・コンポーネントでは、基礎となる階層のデータにアクセスするためのモデルを使用します。特定のモデル・クラスはoracle.adf.view.rich.model.TreeModel
で、「表へのデータの表示」で説明されているように、CollectionModel
を拡張します。
ツリーをサポートする独自のツリー・モデルを作成する必要があります。ツリー・モデルは行のコレクションです。現在行に子の行が含まれている場合にtrue
を返すisContainer()
メソッドがあります。現在行の子にアクセスするには、enterContainer()
メソッドをコールします。このメソッドをコールすると、TreeModel
インスタンスが子の行のコレクションに変わります。親のコレクションに戻すには、exitContainer()
メソッドをコールします。
次の例に示すように、TreeModel
クラスの作成時には、org.apache.myfaces.trinidad.model.ChildPropertyTreeModel
クラスが便利です。
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 ADF FacesによるWebユーザー・インタフェースの開発』の「マスター/ディテール・データの表示」の章を参照してください
ツリーは、表の操作と同じような方法で操作できます。次の作業が実行できます。
ノードを現在のノードにするには、リストへの適切な索引を使用してツリーでsetRowIndex()
メソッドをコールします。または、適切なrowKey
オブジェクトを使用してsetRowKey()
メソッドをコールします。
特定のノードにアクセスするには、まずそのノードを現在のノードにしてから、ツリーでgetRowData()
メソッドをコールします。
展開または縮小されているノードの行にアクセスするには、RowDisclosureEvent
でgetAddedSet
メソッドおよびgetRemovedSet
メソッドをコールします。詳細は、「プログラムを使用したノードの開閉について」を参照してください。
ノードの子コレクションを操作するには、setRowIndex()
およびsetRowKey()
メソッドをコールする前にenterContainer()
メソッドをコールします。その後、exitContainer()
メソッドをコールして親ノードに戻します。
ツリー(任意のレベル)内のノードのrowKey
を指すには、focusRowKey
属性を使用します。focusRowKey
属性が設定されるのは、ユーザーがノードを右クリックして「先頭として表示」(またはpanelCollection
コンポーネントの「先頭として表示」ツールバー・ボタン)を選択したときです。
focusRowKey
属性が設定されていると、focusRowKey
で指定されたノードがツリーのルート・ノードとしてツリーにレンダリングされ、ルート・ノードの横に「階層セレクタ」アイコンが表示されます。「階層セレクタ」アイコンをクリックすると、ツリーのルート・ノードからfocusRowKey
オブジェクトへのパスを示す「階層セレクタ」ダイアログが表示されます。この表示の方法は、pathStamp
ファセットに配置されているコンポーネントによって決まります。
注意:
JavaScriptを使用して、ツリーを動的にサイズ変更することはできません。ツリーの高さは初めてレンダリングされるときに設定され、JavaScript APIを使用して変更することはできません。
表と同様、ツリーでも、個々のノードのコンテンツを表示するためにスタンプ設定機能が使用されます。ツリーには、各ノードのデータの表示に使用されるコンポーネントのホルダーであるnodeStamp
ファセットが含まれます。各ノードが一度ずつ、すべてのノードで繰り返しレンダリング(スタンプ設定)されます。各ノードにスタンプが設定されると、現在のノードのデータが、EL式を使用して特定可能なプロパティにコピーされます。このプロパティに使用する名前を、ツリーのvar
プロパティを使用して指定します。ツリーのレンダリングが完了したら、このプロパティは削除されるか前の値に戻ります。
このスタンプ設定動作のため、ADF Facesツリーで子としてサポートされるのは、特定タイプのコンポーネントのみです。動作が設定されていないすべてのコンポーネントは、大部分がValueHolder
またはActionSource
インタフェースを実装するコンポーネントとしてサポートされています。
次の例では、ツリーに表示されるデータを識別する変数node
を使用して各要素のデータを参照しています。nodeStamp
ファセットは、node
変数からさらにプロパティを取得して、各要素のデータを表示します。
<af:tree var="node"> <f:facet name="nodeStamp"> <af:outputText value="#{node.firstname}"/> </f:facet> </af:tree>
ツリーにもpathStamp
ファセットが含まれます。このファセットは、nodeStamp
ファセットがツリーのコンテンツのレンダリング方法を決定するのと同じように、「階層セレクタ」ダイアログのコンテンツのレンダリング方法を決定します。「階層セレクタ」ポップアップではユーザー入力が許可されないため、pathStamp
ファセットの内部のコンポーネントは、単純なoutputText
、image
およびoutputFormatted
タグの組合せにすることができ、入力コンポーネント(EditableValueHolder
コンポーネント)にすることはできません。このファセットが提供されていない場合、「階層セレクタ」アイコンはレンダリングされません。
たとえば、pathStamp
ファセットにイメージおよびoutputText
コンポーネントを含めると、ツリーにより、「階層セレクタ」ダイアログの各ノード・レベルにイメージとoutputText
コンポーネントがレンダリングされます。値へのアクセスには同じEL式を使用します。たとえば、outputText
コンポーネントのパスの各ノードに名前を表示する場合、EL式は<af:outputText value="#{node.firstname}"/>
になります。
ヒント:
panelCollection
コンポーネントにより作成されたデフォルトのツールバー・ボタンの動作方法の決定には、pathStamp
ファセットも使用されます。ボタンを使用する場合は、ノード値にバインドされたコンポーネントを追加します。panelCollection
コンポーネントの使用方法の詳細は、「表メニュー、ツールバーおよびステータス・バーの表示」を参照してください。
ツリーを作成するには、ページにツリー・コンポーネントを追加し、表示および動作プロパティを構成します。
始める前に:
属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、「ツリーへのデータの表示」を参照してください。
他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、「コレクションベース・コンポーネントの追加機能」を参照してください。
ページにツリーを追加する手順:
ページにツリーを追加すると、JDeveloperによりnodeStamp
ファセットが追加され、ツリーのノードにスタンプが設定されます。次の例に、File Explorerアプリケーション内のディレクトリ構造を表示するツリーの省略形のコードを示します。
<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>
ツリーは、階層でのレベルを示すためにノードがインデントされている形式で表示されます。ユーザーはクリックしてノードを開き、子ノードを表示できます。ユーザーは開いた状態のノードをクリックして閉じることもできます。ユーザーがこれらのアイコンのいずれかをクリックすると、コンポーネントによりRowDisclosureEvent
イベントが生成されます。このイベントに対応する処理を実行するには、カスタムのrowDisclosureListener
メソッドを登録します。詳細は、「プログラムを使用したノードの開閉について」を参照してください。
ユーザーがノードを選択または選択解除すると、ツリー・コンポーネントによりselectionEvent
イベントが起動されます。選択されたノードに基づいてツリー・コンポーネントで後処理を実行する、カスタムのselectionListener
インスタンスを登録できます。詳細は、「プログラムを使用したノードの選択について」を参照してください。
RowDisclosureEvent
イベントには、閉じた状態のすべてのノード用のRemovedSet
オブジェクトと、開いた状態のすべてのノード用のAddedSet
オブジェクトの2つのRowKeySet
オブジェクトがあります。コンポーネントは、追加されたセットの全ノードの下位のサブツリーを開き、削除されたセットの全ノードの下位のサブツリーを閉じます。
次の例に示すように、カスタムの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}">
ツリー・ノードの縮小については、ツリー・ノードの展開について示す次の例のように、行の公開イベントを処理するバッキングBeanメソッドのgetRemovedSet
を使用します。
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
属性として格納されます。次の例に示すように、このインスタンスを使用して、階層内のノードの開いた状態または閉じた状態をプログラムで制御できます。RowKeySet
インスタンスに含まれるノードは開かれ、その他すべてのノードは閉じられます。addAll()
メソッドによりすべての要素がセットに追加され、removeAll()
メソッドによりすべてのノードがセットから削除されます。
<af:tree var="node" inlineStyle="width:90%; height:300px" id="displayRowTable" varStatus="vs" rowselection="single" disclosedRowKeys="#{treeTableTestData.disclosedRowKeys}" value="#{treeTableTestData.treeModel}">
次の例に、公開された行キーを処理するバッキング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; }
ツリーおよびツリー表コンポーネントを使用すると、単一のノードのみまたは複数のノードを選択できるようになります。コンポーネントで複数の選択が許可されている場合、ユーザーは[Ctrl]を押しながらクリックする操作、および[Shift]を押しながらクリックする操作で複数のノードを選択できます。
ユーザーがノードを選択または選択解除すると、ツリー・コンポーネントによりselectionEvent
イベントが起動されます。このイベントには、選択解除されたすべてのノード用のRemovedSet
オブジェクトと、選択されたすべてのノード用のAddedSet
の2つのRowKeySet
オブジェクトがあります。
ツリーおよびツリー表コンポーネントは、クラスoracle.adf.view.rich.model.RowKeySet
のインスタンスを使用して選択されたノードを追跡します。このインスタンスは、コンポーネントのselectedRowKeys
属性として格納されます。このインスタンスを使用して、階層内のノードの選択状態をプログラムで制御できます。RowKeySet
インスタンスに含まれるノードは選択されているとみなされ、その他すべてのノードは選択解除されているとみなされます。addAll()
メソッドによりすべてのノードがセットに追加され、removeAll()
メソッドによりすべてのノードがセットから削除されます。ツリーおよびツリー表ノードの選択は、表の行の選択と同じように機能します。表の行選択のサンプル・コードは、「表の選択された行でのアクションの実行について」を参照してください。
ADF Tree Table
コンポーネントでは、階層構造でコンテンツを表示できます。このコンポーネントを使用すると、ツリー・コンポーネントを使用するより精巧にコンテンツを表示できます。
ADF Facesのツリー表コンポーネントでは、表形式で階層データが表示されます。ツリー表コンポーネントでは、階層の各ツリー・ノードのデータの列を表示できるため、ツリー表コンポーネントの表示はツリー・コンポーネントの表示より複雑です。コンポーネントには、階層のノードの開閉だけでなく、メイン・ツリー内のサブツリーにフォーカスするメカニズムもあります。図12-30に、File Explorerアプリケーションで使用されるツリー表を示します。ツリー・コンポーネント同様、ツリー表でも、コレクションのファイル間の階層関係を表示できます。また、表コンポーネントと同じように、各ファイルの属性値も表示できます。
図12-30 File Explorerアプリケーションのツリー表
ツリー表コンポーネントの直下の子は、表コンポーネントと同じように、列コンポーネントであることが必要です。表とは異なり、ツリー表コンポーネントには、階層のノードの1次識別子を含む列が配置されるnodeStamp
ファセットがあります。treeTable
コンポーネントでは、Tree
コンポーネントと同じスタンプ設定動作がサポートされています(詳細は、「ツリーへのデータの表示」を参照してください)。
注意:
nodeStamp
ファセットは、1列のみ含むことができます(これがツリーのノードになります)。
たとえば、(図12-30に示す)File Explorerアプリケーションの1次識別子はファイル名です。これは、nodeStamp
ファセットに含まれる列です。タイプや「サイズ」などのその他の列は、1次識別子の属性値を表示し、ツリー表コンポーネントの直接の子です。このツリー表では、nodeStamp
ファセット列の各ノードのデータ、および子の列の各コンポーネントのデータにスタンプを設定するために使用される変数の値としてnode
が使用されています。次の例に、File Explorerアプリケーション内のツリー表の省略形のコードを示します。
<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>
ツリー表コンポーネントでは、表とツリーの両方と同じ多くの属性がサポートされています。これらの属性の詳細は、「表へのデータの表示」および「ツリーへのデータの表示」を参照してください。
ツリー表を作成するには、「ツリー表の挿入」ウィザードを使用します。ウィザードが完了したら、「プロパティ」ウィンドウを使用してツリー表の追加プロパティを構成できます。
始める前に:
属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、「ツリー表へのデータの表示」を参照してください。
他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、「コレクションベース・コンポーネントの追加機能」を参照してください。
ページにツリー表を追加する手順:
ADF Facesフレームワークでは、表の行全体のデータまたは他のページにあるツリーを渡すことができます。これは、ボタンをクリックするだけで表のデータを取得したいときに便利です。
コレクションから行全体を値として渡すことが必要な場合があります。そのためには、表で行を表すために使用される変数、またはツリーでノードを表すために使用される変数を、pageFlow
スコープのプロパティに値として渡します。別のページは、スコープからその値にアクセスできます。setPropertyListener
タグでこれを行うことができます(使用手順を含むsetPropertyListener
タグの詳細は、「ページ間の値の受渡し」を参照してください)。
たとえば、次の例に示すように、マスター・ページにある単一選択の表に従業員を一覧表示し、ユーザーが行の1つを選択してボタンをクリックすると、その行のデータを編集するための新しいページに移動できるようにするとします。EL変数名emp
は、表の1行(従業員)を表すために使用されます。button
コンポーネントのaction
属性値は、静的な文字列結果showEmpDetail
です。これで、ユーザーが従業員詳細ページに移動できるようになります。setPropertyListener
タグにはfrom
値(変数emp
)が使用され、to
の値に格納されます。
<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:button text="Show more details" action="showEmpDetail"> <af:setPropertyListener from="#{emp}" to="#{pageFlowScope.empDetail}" type="action"/> </af:button> </af:column> </af:table>
ユーザーが特定の従業員の行のボタンをクリックすると、リスナーが実行され、表の現在行(従業員)に対応する#{emp}
の値が取得されます。取得された行オブジェクトは、#{pageFlowScope.empDetail}
EL式を使用してpageFlowScope
のempDetail
プロパティとして格納されます。アクション・イベントの実行は静的結果になり、ユーザーは詳細ページにナビゲートされます。詳細ページでは、次の例に示すように、outputText
コンポーネントは、pageFlowScope.empDetail
オブジェクトから値を取得します。
<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>
ADF panelCollection
コンポーネントを使用すると、メニュー、ツールバーおよびステータス・バーを表に追加できます。コンテンツを展開または縮小する、ツリーまたはツリー表からツールバーをデタッチするなどのアクションを追加することもできます。
panelCollection
コンポーネントを使用して、表、ツリーおよびツリー表にメニュー、ツールバーおよびステータス・バーを追加できます。panelCollection
コンポーネントを使用するには、表、ツリーまたはツリー表コンポーネントをpanelCollection
コンポーネントの直接の子として追加します。panelCollection
コンポーネントには、デフォルトのメニューとツールバー・ボタンが用意されています。
図12-31に、ツリー表コンポーネントを含む、File ExplorerアプリケーションのpanelCollection
コンポーネントを示します。ツールバーには、ツリー表で実行可能なアクション(ノードの開閉など)を提供するメニュー、ユーザーがツリー表を連結解除できるボタン、およびユーザーがツリー表に表示された行を変更できるボタンが含まれます。特定のツールバー項目を表示しないようにツールバーを構成できます。たとえば、ユーザーがツリーまたは表をデタッチできるボタンをオフにすることができます。メニュー、ツールバー、ツールバー・ボタンの詳細は、 「メニュー、ツールバーおよびツールボックスの使用方法」を参照してください。
図12-31 メニューおよびツールバーのあるツリー表のパネル・コレクション
panelCollection
コンポーネントには、メニュー・コンポーネントを保持するmenu
ファセット、ツールバー・コンポーネント用のtoolbar
ファセット、別のツールバー・コンポーネント・セット用のsecondaryToolbar
ファセット、およびステータス項目用のstatusbar
ファセットが含まれています。
デフォルトのトップレベルのメニューおよびツールバー項目は、panelCollection
コンポーネントの子として使用されているコンポーネントにより異なります。
表およびツリー: デフォルトのトップレベルのメニューは「表示」です。
選択可能な列が含まれる表およびツリー表: デフォルトのトップレベルのメニュー項目は「表示」および「書式設定」です。
表およびツリー表: デフォルトのツールバー・メニューは「連結解除」です。
選択可能な列が含まれる表およびツリー表: デフォルトのトップレベルのツールバー項目は「固定」、「連結解除」および「折返し」です。
ツリーおよびツリー表(pathStamp
ファセットが使用されている場合): ツールバー・ボタン「上に移動」、「先頭に移動」および「先頭として表示」も表示されます。
次の例に、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:button shortDesc="Create" icon="/new_ena.png"> </af:button> <af:button shortDesc="Update" icon="/update_ena.png"> </af:button> <af:button shortDesc="Delete" icon="/delete_ena.png"> </af:button> </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
コンポーネント内で、メニューを連結解除可能にできます。詳細は、「メニュー・バーでのメニューの使用方法」を参照してください。ユーザーが次の操作をする可能性がある場合は、連結解除メニューの使用を検討してください。
ページで類似のコマンドを繰り返し実行する場合。
大規模な表、ツリー表またはツリーにおいて、異なる行のデータで類似のコマンドを実行する場合。
長くて幅の広い表やツリー表、およびツリーでデータを表示する場合。ユーザーは一度クリックすることで、表示または非表示にする列やブランチを選択できます。
長くて幅の広い表、ツリー表またはツリーでデータを書式設定する場合。
panelCollection
コンポーネントを追加してから、panelCollection
コンポーネントに表、ツリーまたはツリー表を追加します。その後、メニューおよびツールバーを追加および変更できます。
始める前に:
属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、「表メニュー、ツールバーおよびステータス・バーの表示」を参照してください。
他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、「コレクションベース・コンポーネントの追加機能」を参照してください。
集約表示のコンポーネントを含むpanelCollectionコンポーネントを作成する手順:
ADF FacesのlistView
およびlistItem
コンポーネントを使用すると、単一列の表構造でコンテンツを表示できます。TreeModel
にlistView
をバインドして、2レベル階層を実現することもできます。
複数の列を持つ表を使用するかわりに、listView
およびlistItem
コンポーネントを使用すると、1つの列のみを持つ表のような単純な形式で構造化データを表示できます。図12-32に、1つのlistItem
コンポーネントを持ち、それを使用して各行にエラー・アイコン、タスク情報およびアクション・ボタンを表示するlistView
コンポーネントを示します。
図12-32 1つのlistItemコンポーネントを持つlistViewコンポーネント
図12-33に示すように、表示するデータを列を使用してグループ化するかわりに、1つのlistItem
コンポーネントに保持された複数のレイアウト・コンポーネントおよびその他のコンポーネントの組合せによって実際のデータが表示されます。この例では、listItem
コンポーネントに1つの大きなpanelGroupLayout
コンポーネントが含まれ、子を水平に表示するように設定されています。子として別のpanelGroupLayout
コンポーネントが3つあり、これらを使用して表における列のように子をグループ化しています。これらのpanelGroupLayout
コンポーネントも、それぞれの子を水平に表示するように設定されています。これらのレイアウト・コンポーネントの2番目には、1つのpanelGroupLayout
コンポーネントが含まれ、子コンポーネント(この場合は3つのoutputText
コンポーネント)を垂直に表示するように設定されています。
図12-33 データを表示する複数のコンポーネントを含むlistItemコンポーネント
対応するコードについては、次の例12-1を参照してください。
listView
コンポーネントをコレクションにバインドします。その後、コンポーネントは各アイテムに値をスタンプ設定し、1つのlistItem
コンポーネントを繰り返しレンダリングします。各アイテムにスタンプが設定されると、現在の行のデータが、listView
コンポーネントのvar
属性を使用するEL式を使用して特定可能なプロパティにコピーされます。リストのレンダリングが完了したら、このプロパティは削除されるか前の値に戻ります。
この例では、listView
の値はdemolistView.taskModel
オブジェクトにバインドされています。このオブジェクトのプロパティには、var
プロパティ(item
に設定されている)を使用してアクセスできます。たとえば、タスク名を表示する場合は、outputText
コンポーネントの値はitem.taskName
に設定されます。
また、listView
コンポーネントには、制限付きの2レベルの階層を表示することもできます。階層を表示するには、listView
をCollectionModel
ではなくTreeModel
にバインドする必要があります。TreeModelは、1つのルート・レベルと1つの子レベルを持つことができます(TreeModelクラスの詳細は、「ツリーへのデータ表示」を参照)。
ツリーの場合と同様に、listView
も、スタンプ設定を使用して個々のノードの値を表示し、ノードの親グループの表示に使用されるコンポーネントのホルダーとなるファセット(groupHeaderStamp
という名前のファセット)を使用します。ただし、listView
で許可されるのは2レベルのみであるため、groupHeaderStampファセットには、ルート・レベルのみの表示に使用されるコンポーネントが含まれます。
図12-34に、ルートがアルファベット文字、リーフ・ノードが従業員オブジェクトという単純な階層を表示するlistView
コンポーネントを示します。
図12-34 listViewコンポーネントの単純な階層
次の例に示すように、従業員オブジェクトの表示に使用されるコンポーネントはlistItem
コンポーネント内に配置され、アルファベット文字の表示に使用されるコンポーネントはgroupHeaderStamp
ファセットのlistItem
コンポーネント内に配置されています。
<af:listView id="listView" binding="#{editor.component}" var="item" varStatus="vs" groupDisclosurePolicy="noDisclosure" value="#{demolistView.ABTreeModel}"> <af:listItem id="listItem1"> <af:panelGroupLayout id="pgl3" layout="vertical"> <af:outputText id="ot2" value="#{item.ename}" styleClass="ABName"/> <af:outputText id="ot3" value="#{item.job}" styleClass="ABJob"/> </af:panelGroupLayout> </af:listItem> <f:facet name="groupHeaderStamp"> <af:listItem id="listItem2" styleClass="ABHeader"> <af:outputText id="ot1" value="#{item.alphabetHeading}"/> </af:listItem> </f:facet> </af:listView>
listView
コンポーネントに階層を表示する場合は、図12-35に示すように、ヘッダーで子コンポーネントを表示または非表示にできるように構成できます。
図12-35 閉じるヘッダーを表示するように構成されたlistViewコンポーネント
デフォルトでは、listView
コンポーネントはすべての子を表示するように構成されます。groupDisclosurePolicy
属性を使用すると、これを変更できます。
ユーザーがグループの開閉を行うと、RowDisclosureEvent
が起動されます。groupDisclosureListener
を使用すると、プログラムからノードを開閉できます。詳細は、「プログラムを使用したノードの開閉について」を参照してください。
ユーザーが行またはノードを選択または選択解除すると、SelectionEvent
が起動されます。selectionListener
を使用すると、プログラムでイベントに応答できます。詳細は、「表の選択された行でのアクションの実行に関する必知事項」を参照してください。
例12-1 listViewコンポーネント
<af:listView id="listView" binding="#{editor.component}" var="item" varStatus="vs" partialTriggers="::pprLV" value="#{demolistView.taskModel}" selection="multiple"> <af:listItem id="lvi"> <af:showPopupBehavior popupId="::ctxtMenu" triggerType="contextMenu"/> <af:panelGroupLayout id="panelGroupLayout1" layout="horizontal" styleClass="AFStretchWidth"> <af:panelGroupLayout id="panelGroupLayout2" layout="horizontal" inlineStyle="margin-left:20px; width:45px" halign="center" valign="middle"> <af:image rendered="#{vs.index %6 ==1}" source="/images/error.png" id="i1" shortDesc="Error at Line #{vs.index + 1}"/> </af:panelGroupLayout> <af:panelGroupLayout id="panelGroupLayout3" layout="horizontal" inlineStyle="width:100%"> <af:panelGroupLayout id="panelGroupLayout5" layout="vertical" inlineStyle="min-width:300px"> <af:outputText id="outputText1" value="#{item.taskName}" styleClass="taskName"/> <af:outputText id="outputText2" value="#{item.projectDesc}" styleClass="taskProjectDesc"/> <af:outputText id="outputText3" value="#{item.created}" styleClass="taskCreated"/> </af:panelGroupLayout> </af:panelGroupLayout> <af:panelGroupLayout id="panelGroupLayout4" layout="horizontal" halign="end" valign="middle" inlineStyle="margin-right:20px"> <af:button id="cb1" text="Action" shortDesc="Click To Invoke Action for Item #{vs.index + 1}"> <af:showPopupBehavior popupId="::popupDialog" alignId="cb1" align="afterStart"/> </af:button> </af:panelGroupLayout> </af:panelGroupLayout> </af:listItem> </af:listView>
リストを作成するには、CollectionModel
インスタンスにバインドされたlistView
コンポーネントと、1つのlistItem
コンポーネントを使用します。単純な親子のヘッダーを表示する場合は、groupHeaderStamp
ファセット内に2つ目のlistItemコンポーネントを配置します。次に、レイアウト・コンポーネントとその他のテキスト・コンポーネントを追加して、実際のデータを表示します。
リストにコレクションを表示するには:
表と同様に、スクロールバーを使用するようにlistView
コンポーネントを構成できます。iOSオペレーティング・システムで、listView
コンポーネントでスクロールを使用するように構成すると、デフォルトではコンテンツの上にマウスを置いたときのみスクロールバーが表示されます。それ以外の場合は、非表示のままです。この同じ動作が他のオペレーティング・システムでも行われるようにアプリケーションを構成するには、-tr-overflow-style: autohiding-scrollbar
スキニング・プロパティをaf|listView
セレクタに追加します。
af|listView { -tr-overflow-style: autohiding-scrollbar }
注意:
iOS以外のオペレーティング・システムでは、listViewルート要素のスタイル属性にoverflow:hidden
を初期設定します。mouseHover
イベントの場合は、スタイル属性にoverflow:auto
を設定し、mouseOut
イベントの場合は、スタイル属性にoverflow:hidden
を設定します。
ADF carouselItem
コンポーネントを使用すると、回転カルーセル構造でイメージを表示できます。カルーセル構造の表示に構成することもできます。
図12-37に示すように、イメージを回転カルーセルに表示できます。ユーザーは、下部にあるスライダを使用するか、補助イメージの1つをクリックしてそのイメージを前面に移動することにより、前面のイメージを変更できます。
図12-37 ADF Facesカルーセル
デフォルトでは、カルーセルは水平に表示されます。カルーセルの水平方向のオブジェクトは中央に垂直に整列され、カルーセル自体はそのコンテナの中央に水平に整列されます。
参照ローロデックス(回転式カード・ファイル)が必要な場合は、垂直に表示されるようにカルーセルを構成できます。デフォルトでは、垂直方向のカルーセルの中のオブジェクトは水平方向の中央がそろうように整列され、カルーセル自体は垂直方向の中央に整列されます(図12-38を参照)。カルーセルの位置合せ属性を使用して、位置合せを変更できます。
図12-38 垂直カルーセル・コンポーネント
ベスト・プラクティス
一般に、カルーセルは子を拡大する親コンポーネントに配置する必要があります(panelSplitter
やpanelStretchLayout
など)。子を拡大するコンポーネントにカルーセルを配置しない場合、カルーセルは幅500px、高さ300pxのデフォルト・サイズで表示されます。これらのサイズは変更できます。
前後のイメージを部分的に表示するかわりに、映写フィルム風デザインで(図12-39を参照)、またはルーミー・サーキュラー・デザインで(図12-40を参照)イメージを表示するようにカルーセルを構成することができます。
図12-39 カルーセルの映写フィルム風表示
図12-40 カルーセルのルーミー・サーキュラー表示
デフォルトでは、カルーセルが循環モードで表示するように構成されている場合、補助アイテム(現在、中央に表示されていないアイテム)にポインタを置くと、そのアイテムが枠で囲まれ選択可能であることが示されます(この枠は、アプリケーションがSkyrosおよび以降のスキンを使用している場合にのみ、表示されることに注意してください)。図12-41に示すように、アイテムが移動し、最大サイズで表示されるように、カルーセルを構成できます。
図12-41 マウスを置いた場所に移動する補助アイテム
カルーセルに現在のイメージのみを表示するように構成することもできます(図12-42を参照)。
図12-42 カルーセルにイメージを1つだけ表示できる
イメージの一覧表示に使用されるコントロールを構成できます。前後への矢印付きの、複数のイメージにまたがるスライダを表示することも、前後へのボタンのみを表示することも(図12-42を参照)、前後へのボタンとスライド・カウンタを表示することもできます(図12-43を参照)。
図12-43 スライダのない次および前ボタン
子carouselItem
コンポーネントは、カルーセルにオブジェクトとそのオブジェクトのタイトルを表示します。表示するオブジェクトごとにcarouselItem
コンポーネントを作成し、これらのコンポーネントを個々のオブジェクトにバインドするかわりに、carousel
コンポーネントを完全なコレクションにバインドします。ツリーが各データ行をスタンプ・アウトするのと同様の方法で、コンポーネントは、各項目の値をスタンプ処理することで1つのcarouselItem
コンポーネントを繰り返しレンダリングします。各項目にスタンプが設定されると、現在の項目のデータが、carousel
コンポーネントvar
属性を使用するEL式を使用して特定可能なプロパティにコピーされます。カルーセルのレンダリングが完了したら、このプロパティは削除されるか前の値に戻ります。カルーセルには、テキストの表示に使用されるcarouselItem
コンポーネントのホルダーと各項目の短い説明の両方であり、各項目について表示されるイメージの親コンポーネントでもあるnodeStamp
ファセットが含まれます。
たとえば、図12-37に示すADF Facesコンポーネント・デモのcarouselItem
JSFページには、各ADF Facesコンポーネントのイメージを表示するcarousel
コンポーネントが含まれます。demoCarouselItem
(CarouselBean.java
)マネージドBeanには、これらの各コンポーネントのリストが含まれます。carousel
コンポーネントのvalue属性は、そのリストを表すそのBeanのitems
プロパティにバインドされます。カルーセル・コンポーネントのvar
属性は、表示する各項目の値の保持に使用され、各項目の適切な値を取得するためにcarouselItem
コンポーネントとimage
コンポーネントの両方で使用されます。次の例に、カルーセルのJSFページ・コードを示します。カルーセルのスタンプ動作の詳細は、「ツリーへのデータの表示」を参照してください。
<af:carousel id="carousel" binding="#{editor.component}" var="item" value="#{demoCarousel.items}" carouselSpinListener="#{demoCarousel.handleCarouselSpin}"> <f:facet name="nodeStamp"> <af:carouselItem id="crslItem" text="#{item.title}" shortDesc="#{item.title}"> <af:image id="img" source="#{item.url}" shortDesc="#{item.title}"/> </af:carouselItem> </f:facet> </af:carousel>
carouselItem
コンポーネントは、子コンポーネントのみ拡大します。単一のimage
コンポーネントをcarouselItem
の内部に配置した場合、イメージはその項目に割り当てられた正方形に合せて拡大されます(ユーザーがカルーセルをスピンすると、これらのサイズが縮小または拡大されます)。
ベスト・プラクティス
image
コンポーネントは、拡大されたときの動作を変更するジオメトリ管理コントロールを提供しません。拡大されたときにイメージが適切な縦横比を保つためには、同じ幅と高さのイメージを使用する必要があります。
carousel
コンポーネントでは、Collection
Model
クラスを使用して基礎となるコレクションのデータにアクセスします。このクラスは、JSF DataModel
クラスを拡張し、行キーのサポートを追加します。DataModel
クラスでは、行は索引によって完全に識別されます。ただし、基になるデータが変更された場合に問題を回避するために、CollectionModel
クラスが索引ではなく行キーに基づいています。
java.util.List
、array
およびjavax.faces.model.DataModel
など、別のモデル・クラスも使用できます。他のいずれかのクラスを使用する場合は、carousel
コンポーネントにより、インスタンスがCollectionModel
クラスに自動的に変換されますが、機能は追加されません。CollectionModel
クラスの詳細は、http://myfaces.apache.org/trinidad/trinidad-1_2/trinidad-api/apidocs/index.html
にあるMyFaces TrinidadのJavadocを参照してください。
注意:
アプリケーションでFusionテクノロジ・スタックを使用する場合は、項目を表すデータ・ソースに対するADFビジネス・コンポーネントを作成でき、作成するとモデルが作成されます。その後、カルーセルを宣言的に作成でき、そのカルーセルは自動的にそのモデルにバインドされます。詳細は、『Oracle Application Development FrameworkによるFusion Webアプリケーションの開発』の「ADF Facesカルーセル・コンポーネントの使用」の章を参照してください。
カルーセル・コンポーネントは仮想化されています。つまり、サーバーのコンポーネントに存在する一部の項目のみがクライアントに配信され、表示されます。データ・ソースから一度に一定数の行をフェッチするようにカルーセルを構成します。レンダリング時にすぐにデータをコンポーネントに配信することも、コンポーネントのシェルがレンダリングされた後に遅延フェッチすることもできます。デフォルトでは、カルーセルは最初のリクエストに対してデータの遅延フェッチを行います。ページにこれらのコンポーネントが1つ以上含まれる場合、ページでは最初は標準のライフサイクルが実行されます。ただし、最初のリクエスト中にデータをフェッチするカルーセルのかわりに、特定の個別の部分ページ・レンダリング(PPR)リクエストがコンポーネントで実行され、カルーセルのフェッチ・サイズの値として設定されたアイテム数が返されます。ページのレンダリング直後であるため、レスポンスのレンダリング・フェーズのみがカルーセルに対して実行され、対応するデータのフェッチおよび表示が可能になります。ユーザーが後続のデータ・フェッチの原因となる操作(たとえば、カルーセルを別のイメージ・セットに回転)を実行すると、別のPPRリクエストが実行されます。
パフォーマンスに関するヒント
ページにカルーセルより多くのコンポーネントが含まれる場合は、遅延配信を使用する必要があります。遅延配信を使用すると、データが使用可能になる前に、初期ページのレイアウト・コンポーネントおよびその他のコンポーネントが最初にレンダリングされます。
即時配信は、カルーセルがページの唯一のコンテキストである場合、またはカルーセルが大きな項目セットを返さないと予想される場合に使用します。この場合、ユーザー・レスポンス時間がより高速で、サーバーCPU利用率がより高ければ、2番目のリクエストはサーバーに移動しないため、レスポンス時間は遅延配信を使用する場合よりも高速になります(または、場合によっては高速に感じます)。ただし、フェッチ・ブロックとして構成された項目数のみが最初に返されます。遅延配信と同様に、ユーザーのアクションが後続のデータ・フェッチの原因となる場合は、次の項目セットが配信されます。
スライダ・コントロールでは、ユーザーはコレクションをナビゲートできます。通常、スライダ上のサムにはオブジェクトの総数のうちの現在のオブジェクト番号(6/20など)が表示されます。オブジェクトの総数が大きすぎて計算できない場合、スライダ上のサムには現在のオブジェクト番号のみ表示されます。たとえば、会社の従業員電話帳にカルーセルが使用されているとします。デフォルトでは、電話帳には全従業員の顔写真が表示されますが、コストの高いデータベース・コールを行わないと、その日システムに厳密に94,409人の従業員がいることがわからない場合があります。
カルーセルとともに他のコンポーネントを使用できます。たとえば、ツールバーまたはメニュー・バーを追加し、ユーザーが現在のオブジェクトに対するアクションを実行できるボタンまたはメニュー項目をそれらに追加できます。
カルーセルを作成するには、まず、表示するイメージを含むデータ・モデルを作成する必要があります。次に、carousel
コンポーネントをそのモデルにバインドし、carouselItem
コンポーネントをカルーセルのnodeStamp
ファセットに挿入します。最後に、image
コンポーネント(またはimage
コンポーネントを含むその他のコンポーネント)をcarouselItem
コンポーネントに子として挿入します。
始める前に:
属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、「カルーセルでのイメージの表示」を参照してください。
他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、「コレクションベース・コンポーネントの追加機能」を参照してください。
表示するイメージのコレクションを提供するデータ・モデルを作成します。データ・モデルは、List
、Array
、DataModel
またはCollectionModel
にすることができます。コレクションがCollectionModel
以外の場合、フレームワークはそれをCollectionModel
に自動的に変換します。CollectionModel
クラスの詳細は、http://myfaces.apache.org/trinidad/trinidad-1_2/trinidad-api/apidocs/index.html
にあるMyFaces TrinidadのJavadocを参照してください。
データ・モデルは、カルーセルに表示する各イメージについて次の情報を提供する必要があります。
イメージのURL
カルーセルのイメージの下に表示されるタイトル
ユーザーがイメージ上にカーソルを置いたときに表示するテキストに使用される短い説明
たとえば、ADF Facesコンポーネント・デモ・アプリケーションのCarouselBean.java
およびCarouselMediaBean.java
クラスを参照してください。
カルーセルを作成する手順:
ADF Facesのガント・チャートからExcelスプレッドシートに、またはカンマ区切り形式ファイルにデータをエクスポートできます。書式設定情報も、データとともにエクスポートされます。
表、ツリーまたはツリー表から、あるいはデータ視覚化プロジェクトのガント・チャートの表領域から、データをMicrosoft Excelスプレッドシートまたはカンマ区切り形式(CSV)ファイルにエクスポートできます。ユーザーが表をエクスポートできるようにするには、エクスポートの起動に使用するアクション・ソース(ボタンやリンクなど)を作成し、exportCollectionActionListener
コンポーネントを追加して、エクスポートするデータに関連付けます。書式情報はエクスポートされるExcelワークシートに含まれているので、データ・タイプを正しく識別でき、様々な列でMS Excelの組込み機能を使用できます。ただし、セルの書式が有効でない場合、テキストはデフォルトのText
形式でエクスポートされます。exportCollectionActionListener
を構成するときに、表またはツリーのすべての行をエクスポートするか、ユーザーが選択した行のみをエクスポートするかを指定します。
ヒント:
DVTピボット表からデータをエクスポートすることもできます。詳細は、「ピボット・テーブルからのエクスポート」を参照してください。
たとえば、図12-47に示すADF Facesコンポーネント・デモ・アプリケーションの表には、ユーザーがデータをExcelのスプレッドシートに、またはCSVファイルとしてエクスポートするためのボタンがあります。
図12-47 データをエクスポートするためのボタンがある表
ユーザーがボタンの1つをクリックすると、すべての行をスプレッドシートまたはCSVにエクスポートする処理がリスナーによって実行されます。図12-47に示すように、ユーザーが選択する行のみがエクスポートされるように、exportCollectionActionListener
コンポーネントを構成することも可能です。
次の値のみエクスポートできます
値ホルダー・コンポーネント(input
コンポーネントやoutput
コンポーネントなど)の値。
selelctOneChoice
およびselectOneListbox
コンポーネントで使用されるselectItem
コンポーネントの値(他の選択コンポーネントのselectItem
コンポーネントの値はエクスポートされません)。
コマンド・コンポーネントのtext
属性の値。
image
およびicon
コンポーネントのshortDesc
属性の値。
image
コンポーネントおよびicon
コンポーネントのshortDesc
属性の値がエクスポートされないようにするには(たとえば、セル内にイメージがある場合)、事前定義済のskipObjectComponent
フィルタ・メソッドを使用します。このメソッドはexportCollectionActionListener
の前に実行され、実行するとObject
コンポーネントはエクスポートされなくなります。独自のフィルタ・メソッドを作成して任意の必要なロジックをexportCollectionActionListener
の実行前に適用することもできます。
ブラウザ、およびリスナーの構成に応じて、図12-48に示すようにブラウザのダイアログが開くか(このダイアログで、ユーザーはファイルを開くか保存するかを選択できます)、ファイルがブラウザに表示されます。たとえば、ユーザーがMicrosoft Internet Explorerでページを表示していて、exportCollectionActionListener
コンポーネントにファイル名が指定されていない場合、ファイルはブラウザに表示されます。Mozilla Firefoxでは、ダイアログが開かれます。
図12-48 Excelへのエクスポート・ダイアログ
ユーザーがファイルの保存を選択した場合は、後でそのファイルをスプレッドシート・アプリケーションで開くことができます(図12-49を参照)。ユーザーがファイルを開くことを選択した場合、その後の動作はブラウザにより異なります。たとえば、ユーザーがページをMicrosoft Internet Explorerで見ているときにスプレッドシートをエクスポートした場合は、スプレッドシートはブラウザ・ウィンドウに表示されます。ユーザーがMozilla Firefoxでページを表示している場合は、スプレッドシートがExcelで開かれます。
図12-49 Excelにエクスポートされたデータファイル
注意:
スプレッドシートの場合は、ファイルのフォーマットがファイル拡張子で指定されたものとは異なるというExcelの警告が表示されることがあります。この警告は無視して問題ありません。
ボタン、リンク、メニュー項目などのコマンド・コンポーネントを作成し、そのコンポーネントの内部にexportCollectionActionListener
を追加します。その後、exportCollectionActionListener
コンポーネントのexportedId
属性を、データをエクスポートするコレクション・コンポーネントIDに設定して、エクスポートするデータ・コレクションを関連付けます。
始める前に:
属性が機能に与える影響に関する知識が役立つ場合があります。詳細は、「表、ツリーまたはツリー表からのデータのエクスポート」を参照してください。
他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、「コレクションベース・コンポーネントの追加機能」を参照してください。
ページに表、ツリーまたはツリー表が存在している必要があります。ない場合は、この章の指示に従って表、ツリーまたはツリー表を作成します。たとえば、表を追加するには、「表へのデータの表示」を参照してください。
ヒント:
ユーザーがエクスポートする行を選択できるようにするには、選択が許可されるよう表を構成します。詳細は、「表の書式設定」を参照してください。
外部形式にコレクション・データをエクスポートする手順:
次の例に、表およびそのexportCollectionActionListener
コンポーネントのコードを示します。exportedId
値が、表のid
値に設定されていることに注意してください。
<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:button text="Export To Excel" immediate="true"> <af:exportCollectionActionListener type="excelHTML" exportedId="table" filename="export.xls" title="ADF Faces Export"/>
ADF Facesフレームワークでは、ELのクライアント・サポートはありません。クライアントで行固有のデータにアクセスするには、コレクションベース・コンポーネントを使用する必要があります。
ADF Facesフレームワークでは、クライアント側でのELのサポートが存在せず、コレクション・モデル全体をクライアントに送信することもサポートされていないため、クライアント上でJavaScriptを使用して値にアクセスする必要がある場合に、クライアント側のコードがコンポーネント・スタンピングに依存して値にアクセスすることはできません。各行で同じコンポーネント・インスタンスを再利用するかわりに、完全に解決されるEL式を使用して、各行に新しいJavaScriptコンポーネントが作成されます(どの行にもコンポーネントが1つ作成される必要があると仮定しています)。
したがって、クライアント上で行固有のデータにアクセスするには、コレクションベース・コンポーネントそのものを使用して値にアクセスする必要があります。クライアント側のデータ・モデルを使用せずにこれを実現するには、クライアント側の選択変更リスナーを使用します。
コレクションベースのコンポーネントからクライアント上の値にアクセスするには、まずコンポーネントにクライアント表現があることを確認する必要があります。その後で、選択変更リスナーをクライアント上で登録する必要があります。そのリスナーは、選択された行を特定し、その行に対応するスタンプされたコンポーネントを見つけ、このコレクション・コンポーネントを使用して行固有の名前を特定し、選択されたデータに対して必要な操作を行うように設定する必要があります。
始める前に:
他のADF Faces機能を使用して追加できる機能について理解することが役立つ場合もあります。詳細は、「コレクションベース・コンポーネントの追加機能」を参照してください。
コレクションベース・コンポーネントから選択された値にアクセスする手順:
次の例にJavaScriptの全コードを示します。
function showSelectedName(event) { var firstRowKey; var addedRowKeys = event.getAddedSet(); for (var rowKey in addedRowKeys) { firstRowKey = rowKey; break; } // The table needs to find the 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); } }
行キーはサーバー上のtokenizedで、これはクライアント上の行キーとサーバー上の行キーに類似点がない可能性があることを意味します。そのため、クライアント側APIによって処理される行キー(AdfSelectionEvent.getAddedSet()
など)のみ有効です。
また、対応する行がスクロールされて画面から見えなくなっていて、クライアントで使用できない場合には、AdfUITable.findComponent(id, rowKey)
メソッドによりnull
が戻される可能性があることに注意してください。AdfUITable.findComponent()
メソッドの戻り値にnull
がないか必ず確認してください。