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

前
 
次
 

18 ナビゲーション・コンポーネントの使用

この章では、commandButtonnavigationPaneおよびtrainなど、ADF Facesのナビゲーション・コンポーネントを使用して、Webユーザー・インタフェースでのナビゲーションを実現する方法を説明します。

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

18.1 ナビゲーション・コンポーネントの概要

JSFアプリケーション同様、ADF Facesコンポーネントを使用するアプリケーションには、ボタンやリンク(またはその他のナビゲーション・コンポーネント)がクリックされた場合に、次に表示するページを選択する一連のルールがあります。ルールは、アプリケーションの構成リソース・ファイル(faces-config.xml)にJSFナビゲーション・ルールおよびケースを追加することで定義します。

JSFでは、結果の文字列は、ページ・ナビゲーションの実行に使用するナビゲーション・ルールの選択に使用されます。javax.faces.component.ActionSourceインタフェースを実装するADF Facesのナビゲーション・コンポーネントでは、ユーザーがコンポーネントをアクティブ化するとActionEventイベントが生成されます。JSF NavigationHandlerおよびデフォルトのActionListenerメカニズムでは、アクティブ化されたコンポーネントの結果文字列を使用して、一連のナビゲーション・ルールで一致するものが検出されます。JSFで一致が検出されると、対応するページが選択され、レスポンスのレンダリング・フェーズで選択したページがレンダリングされます。JSFライフサイクルの詳細は、第4章「ADF FacesでのJSFライフサイクルの使用」を参照してください。また、ADF Facesアプリケーションのナビゲーションでは、部分ページ・レンダリングが使用される場合があります。詳細は、7.4項「部分ページ・ナビゲーションの使用について」を参照してください。

次に、ADF Facesのコマンド・コンポーネントに含まれるものを示します。

ナビゲーションにコマンド・コンポーネントを使用するのに加え、ADF Facesには、アクション・イベントの起動時に特定の機能を実行するためにコマンド・コンポーネントとともに使用できるリスナー・タグも含まれています。詳細は、18.4項「ボタンまたはリンクの機能の呼出し目的での使用」を参照してください。

18.2 ボタンおよびリンクのナビゲーション目的での使用

ADF Facesのボタンおよびリンクには、コマンド・コンポーネントcommandButtoncommandLinkおよびcommandImageLinkと、実行コンポーネントgoButtongoImageLinkおよびgoLinkが含まれます。コマンド・コンポーネントと実行コンポーネントの主な違いは、コマンド・コンポーネントはリクエストを送信してActionEventイベントを起動するのに対し、実行コンポーネントはアクションを配信せずに直接別の場所に移動する点です。図18-11に示すように、レンダリングされたコマンド・コンポーネントと実行コンポーネントの外観は同じように見えます。

図18-1 コマンド・コンポーネントおよび実行コンポーネント

コマンド・コンポーネントと実行コンポーネント

ヒント:

ADF Facesには、メニューやツールバー内で使用できる特殊なコマンド・コンポーネントも用意されています。詳細は、第14章「メニュー、ツールバーおよびツールボックスの使用方法」を参照してください。


commandImageLinkおよびgoImageLinkコンポーネントは、図18-2に示すように、オプションのテキストとともに、イメージをリンクとしてレンダリングします。iconPosition属性に値を設定することで、オプションのテキストに対するイメージの位置を決定できます。また、ユーザーがアイコンにカーソルを置いた場合、またはアイコンが押された場合や無効化された場合のために、別々のアイコンを設定できます。

図18-2 commandImageLinkおよびgoImageLink

コマンド・イメージ・リンクと実行イメージ・リンク

ADF Facesには、ツールバー・ボタンからポップアップ・メニューを開くことができるpopupファセットなど、その他の機能を提供するツールバー・ボタンもあります。詳細は、14.3項「ツールバーの使用方法」を参照してください。

リンクをレンダリングするコマンド・コンポーネントをエンド・ユーザーが右クリックしたときに、ブラウザのポップアップ・メニューを起動できるように、アプリケーションを構成できます。コマンド・コンポーネントによりレンダリングされたリンクを右クリックしたエンド・ユーザーは、ブラウザのコンテキスト・メニューを使用して、起動する必要のないアクション(新しいウィンドウのリンクを開くなど)を起動できてしまいます。詳細は、18.3項「コマンド・リンクへのブラウザ・コンテキスト・メニューの構成」を参照してください。

ナビゲート元のページにコミットされていないデータが含まれる場合には、ユーザーに警告メッセージを表示できます。immediate属性がtrueに設定されているコマンド・コンポーネントに、checkUncommittedDataBehaviorコンポーネントを子として追加します。ユーザーがナビゲートしないことを選択すると、子イベントは取り消されます。次のコンポーネントにcheckUncommittedDataBehaviorコンポーネントを子として追加できます。

エンド・ユーザーに警告メッセージを表示するには、8.2.5項「documentタグの構成方法」で説明されているように、ページにコミットされていないデータが含まれていて、documentタグのuncommittedDataWarning属性がonに設定されている必要があります。


注意:

documentタグのuncommittedDataWarningタグがonに設定されている場合には、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の暗黙的セーブポイントの有効化方法に関する項で説明されているように、コミットされていないデータに対して警告メッセージが表示され、ページには、criticalとして構成されている、ADF Controllerにバインド・タスク・フローもレンダリングされます。


18.2.1 コマンド・ボタンおよびコマンド・リンクの使用方法

通常、commandButtoncommandLinkおよびcommandImageLinkコンポーネントは、ページ・ナビゲーションおよびサーバー側の処理を実行するために使用します。

コマンド・コンポーネントを作成および使用する手順:

  1. コンポーネント・パレットからJSFページに「Button」をドラッグ・アンド・ドロップして、commandButtonコンポーネントを作成します。「リンク」をドラッグ・アンド・ドロップして、commandLinkコンポーネントを作成します。「イメージ・リンク」をドラッグ・アンド・ドロップして、commandImageLinkコンポーネントを作成します。

  2. プロパティ・インスペクタで、「共通」セクションを開き、text属性を設定します。


    ヒント:

    かわりに、textAndAccessKey属性を使用して、ボタンまたはリンクに使用するラベルおよびアクセス・キーを定義する単一の値を指定できます。アクセス・キーの定義方法の詳細は、22.3.4項「ADF Facesコンポーネントのアクセス・キーの定義方法」を参照してください。


  3. icon属性を、commandButtonまたはcommandImageLinkコンポーネント内に使用するイメージ・ファイルのURIに設定します(commandLinkではサポートされていません)。commandImageLinkコンポーネントの場合は、hoverIcondisabledIconおよびdepressedIcon属性を設定することも可能です。


    ヒント:

    text属性(またはtextAndAccessKey属性)かicon属性、あるいはその両方を使用できます。


  4. action属性を、結果の文字列、または論理結果のStringを返すバッキングBeanのアクション・メソッドを参照するメソッド式に設定します。ページ間のナビゲーションを構成する方法の詳細は、2.3項「ページ・フローの定義」を参照してください。

    デフォルトのJSF ActionListenerメカニズムでは、結果の文字列を使用して適切なJSFナビゲーション・ルールが選択され、レスポンスのレンダリング・フェーズに使用するページがJSF NavigationHandlerに通知されます。マネージドBeanメソッドを使用してダイアログを開く方法の詳細は、第13章「ポップアップ・ダイアログ、メニューおよびウィンドウの使用方法」を参照してください。JSFアプリケーションでの結果の文字列およびナビゲーションの詳細は、http://download.oracle.com/javaee/index.htmlでJava EE 6チュートリアルを参照してください。


    ヒント:

    結果を返すハンドラにバインドされている場合は、ナビゲーションにactionListener属性を使用することもできます。通常、この属性はナビゲーションではなく、ユーザー・インタフェース・ロジックの処理にのみ使用する必要があります。

    たとえば、File Explorerアプリケーションの「検索」パネルの「検索」ボタンにはナビゲート先はありません。かわりに、検索の実行に使用されます。actionListener属性には、次の値が指定されています。

    actionListener="#{explorer.navigatorManager.searchNavigator.
                                               searchForFileItem}"
    

    この式は、実際に検索を実行するメソッドに評価されます。


  5. コンポーネントを対話型ではないボタンまたはリンクとして表示する場合は、「動作」セクションを開いて、disabled属性をtrueに設定します。

  6. コンポーネントがアクティブ化されるたびに部分ページ・リクエストが起動されるように、partialSubmit属性をtrueに設定します。詳細は、7.2項「部分ページ・レンダリングの宣言的有効化」を参照してください。

  7. 検証の処理およびモデルの更新フェーズをスキップする場合は、immediate属性をtrueに設定します。コンポーネントのアクション・リスナー(存在する場合)およびデフォルトのJSF ActionListenerハンドラは、JSFライフサイクルのリクエスト値の適用フェーズの最後に実行されます。詳細は、4.2項「immediate属性の使用」を参照してください。

  8. 手順7で説明されているように、immediate属性をtrueに設定した場合は、オプションで、コマンド・コンポーネントにaf:checkUncommittedDataBehaviorコンポーネントを子として追加し、コミットされていないデータがページに含まれている際に、ユーザーに警告メッセージを表示できます。コンポーネント・パレットの「操作」パネルの「動作」セクションから「未コミット・データの確認動作」をドラッグして、手順1で追加したコマンド・コンポーネントの子として、これをドロップします。


    注意:

    8.2.5項「documentタグの構成方法」で説明されているように、documentタグのuncommittedDataWarning属性をonに設定しておく必要もあります。


コマンド・ボタンおよびリンクも、useWindowwindowHeightwindowWidthlaunchListenerおよびreturnListenerの属性を使用して、2次ウィンドウを開くために使用できます。2次ウィンドウを開く方法の詳細は、第18章「ナビゲーション・コンポーネントの使用」を参照してください。

18.2.2 実行ボタンおよび実行リンクの使用方法

goButtongoImageLinkおよびgoLinkコンポーネントは、ActionEventイベントを配信せずに、ページ・ナビゲーションを直接実行するために使用します。

実行ボタンおよび実行リンクを作成および使用する手順:

  1. コンポーネント・パレットからJSFページに実行ボタンをドラッグ・アンド・ドロップして、goButtonコンポーネントを作成します。移動リンクをドラッグ・アンド・ドロップして、goLinkコンポーネントを作成します。「実行イメージ・リンク」をドラッグ・アンド・ドロップして、goImageLinkコンポーネントを作成します。

  2. goButtonまたはgoLinkコンポーネントを作成した場合、プロパティ・インスペクタで「共通」セクションを開き、text属性を設定します。goImageLinkコンポーネントを作成した場合、「その他」セクションでtext属性を設定します。


    ヒント:

    かわりに、textAndAccessKey属性を使用して、ボタンまたはリンクに使用するラベルおよびアクセス・キーを定義する単一の値を指定できます。アクセス・キーの定義方法の詳細は、22.3.4項「ADF Facesコンポーネントのアクセス・キーの定義方法」を参照してください。


  3. icon属性を、goButtonまたはgoImageLinkコンポーネント内に使用するイメージ・ファイルのURIに設定します(goLinkではサポートされていません)。goImageLinkコンポーネントの場合は、hoverIcondisabledIcondepressedIconおよびiconPosition属性を設定することも可能です。

    iconPosition属性では、leading (デフォルト)およびtrailingの2つの値がサポートされています。アイコンをテキストの前にレンダリングする場合はleadingに設定します。アイコンをテキストの後ろにレンダリングする場合はtrailingに設定します。


    ヒント:

    text属性(またはtextAndAccessKey属性)かicon属性、あるいはその両方を使用できます。


  4. destination属性を、リンクのナビゲート先のページのURIに設定します。

    たとえば、File Explorerアプリケーションのpopups.jspxファイルのgoLinkコンポーネントには、destination属性に次のEL式が設定されています。

    destination="http://www.oracle.com"
    
  5. targetFrame属性を設定して、新しいページの表示場所を指定します。使用できる値は次のとおりです。

    • _blank: リンクにより、ドキュメントは新しいウィンドウに開かれます。

    • _parent: リンクにより、ドキュメントは親ウィンドウに開かれます。たとえば、リンクがダイアログに表示された場合、結果のページは親ウィンドウにレンダリングされます。

    • _self: リンクにより、ドキュメントは同じページまたはリージョンに開かれます。

    • _top: リンクにより、ページ全体が置き換えられて、ドキュメントはウィンドウ全体に開かれます。

  6. コンポーネントを対話型ではないボタンまたはリンクとして表示する場合は、「動作」セクションを開いて、disabled属性をtrueに設定します。「その他」セクションで、goImageLinkコンポーネントのdisabled属性を設定します。

18.3 コマンド・リンクへのブラウザ・コンテキスト・メニューの構成

実行時にリンクをレンダリングするコマンド・コンポーネントを使用すると、エンド・ユーザーがアクションを起動できるようになります。また、ADF Facesフレームワークにより、エンド・ユーザーのブラウザにそれらのコマンド・コンポーネントのコンテキスト・メニューがレンダリングされるよう、アプリケーションを構成することも可能です。コンテキスト・メニューにより、コマンド・コンポーネントに指定されている別のアクション(新しいウィンドウにリンクを開くなど)を起動するメニュー・オプションが提供されます。この動作を構成できるコンポーネントは次のとおりです。

移動先を指定し、アクションを起動しないコンポーネントには、この動作を構成できません。次に、これらのコンポーネントの例を示します。

18.3.1 コマンド・リンクへのブラウザ・コンテキスト・メニューの構成方法

アプリケーションのweb.xmlファイルにあるoracle.adf.view.rich.ACTION_LINK_BROWSER_CONTEXT_SUPPRESSIONコンテキスト・パラメータの値をnoに設定します。

始める前に:

この機能を構成できるコマンド・コンポーネントを把握しておくと役に立ちます。詳細は、18.3項「コマンド・リンクへのブラウザ・コンテキスト・メニューの構成」を参照してください。

コマンド・リンクにブラウザ・コンテキスト・メニューを構成する手順:

  1. アプリケーション・ナビゲータで、「web.xml」をダブルクリックし、ファイルを開きます。

    JDeveloperではデフォルトで、web.xmlファイルは概要エディタで開かれます。

  2. 「コンテキスト初期化パラメータ」表で、oracle.adf.view.rich.ACTION_LINK_BROWSER_CONTEXT_SUPPRESSIONパラメータのエントリを追加し、noに設定します。

  3. 変更を保存して、web.xmlファイルを閉じます。

18.3.2 コマンド・リンクにブラウザのコンテキスト・メニューを構成する場合の処理

コマンド・リンクに対するブラウザのポップアップ・メニューの構成に関する項で説明された手順を実行すると、例18-1に示すように、JDeveloperではweb.xmlファイルに値が書き込まれます。

例18-1 ブラウザのコンテキスト・メニューを構成するためのコンテキスト・パラメータ

<context-param>
    <param-name>oracle.adf.view.rich.ACTION_LINK_BROWSER_CONTEXT_SUPPRESSION</param-name>
    <param-value>no</param-value>
</context-param>

アプリケーションのweb.xmlファイルにおけるADF Facesの構成オプションの詳細は、A.2項「web.xmlでの構成」を参照してください。

18.3項「コマンド・リンクへのブラウザのコンテキスト・メニューの構成」で説明されているように、特定のコンポーネントによってレンダリングされたリンクを右クリックすると、実行時にエンド・ユーザーがブラウザのコンテキスト・メニューを起動できます。

18.4 ボタンまたはリンクの機能の呼出し目的での使用

ナビゲーションにコマンド・コンポーネントを使用するのに加え、ADF Facesには、アクション・イベントの起動時に特定の機能を実行するためにコマンド・コンポーネントとともに使用できるリスナー・タグも含まれています。次に、ADF Facesに含まれるリスナー・タグを示します。

18.4.1 ファイルをダウンロードするためのコマンド・コンポーネントの使用方法

コマンド・ボタンなどのアクション・コンポーネントを作成し、fileDownloadActionListenerタグに関連付けることで、ユーザーがファイルをダウンロードする機能を作成できます。ユーザーがアクション・コンポーネントを選択またはクリックすると、図18-3に示すように、ユーザーが異なるダウンロード・オプションを選択できるポップアップ・ダイアログが表示されます。

図18-3 ファイルのダウンロード・ダイアログ

ファイルのダウンロード・ダイアログ

コマンド・ボタン、コマンド・リンクまたはメニュー項目などのアクション・コンポーネントにより、プログラムを使用してファイルのコンテンツがユーザーに送信されるよう、fileDownloadActionListenerタグは宣言的に使用します。特定のコンテンツ・タイプまたはファイル名を宣言することもできます。ファイルのダウンロードは、XMLHttp AJAXリクエストではなく通常のリクエストで処理する必要があるため、サポートされている場合は、親コンポーネントのpartialSubmit属性をfalseに設定する必要があります。


ヒント:

サーバーへのファイルのアップロードの詳細は、9.9項「ファイルのアップロード機能の使用方法」を参照してください。


コンテンツがブラウザに送信された後、そのコンテンツが表示または保存される方法は、ダイアログで選択したオプションにより異なります。プログラムで開くオプションを選択した場合、そのファイル・タイプに関連付けられているアプリケーションが起動されてコンテンツが表示されます。たとえば、テキスト・ファイルの場合はメモ帳アプリケーションが起動されます。ディスクに保存オプションを選択した場合は、ブラウザによっては、ファイル名およびコンテンツを格納する場所を選択するためのポップアップ・ダイアログが表示されます。

例18-2に、ユーザーにファイル・コンテンツ「Hi there!」をダウンロードするためにfileDownloadActionListenerタグを使用するコマンド・ボタンのタグを示します。

例18-2 コマンド・ボタンおよびfileDownloadActionListenerタグを使用したファイルのダウンロード

<af:commandButton value="Say Hello">
  <af:fileDownloadActionListener filename="hello.txt"
      contentType="text/plain; charset=utf-8"
      method="#{bean.sayHello}"/>
</af:commandButton>

例18-3に、ファイルのダウンロード処理に使用されるマネージドBeanメソッドを示します。

例18-3 ファイルのダウンロード処理に使用されるマネージドBeanメソッド

public void sayHello(FacesContext context, OutputStream out) throws IOException{
  OutputStreamWriter w = new OutputStreamWriter(out, "UTF-8");
  w.write("Hi there!");
   . . .
}

ファイルのダウンロード・メカニズムを作成する手順:

  1. コンポーネント・パレットからページにアクション・コンポーネントをドラッグ・アンド・ドロップします(アクション・コンポーネントの詳細は、18.2項「ボタンおよびリンクのナビゲーション目的での使用」を参照してください)。

  2. コンポーネント・パレットの「操作」セクションを開き、ファイルのダウンロード・アクション・リスナー・タグをアクション・コンポーネントの子としてドラッグ・アンド・ドロップします。

  3. プロパティ・インスペクタで次の属性を設定します。

    • contentType: text/plaintext/csvapplication/pdfなど、ファイルのMIMEタイプを指定します。

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

    • method: ファイル・コンテンツのダウンロードに使用されるメソッドを指定します。methodには、FacesContextオブジェクトおよびOutputStreamオブジェクトの2つの引数を指定できます。OutputStreamオブジェクトは自動的に閉じられるため、このmethodの唯一の目的は、すべてのバイトをOutputStreamオブジェクトに書き込むことです。

    たとえば、コマンド・ボタンのコードは次のようになります。

    <af:commandButton text="Load File">
      <af:fileDownloadActionListener contentType="text/plain"
          filename="MyFile.txt"
          method="#(mybean.LoadMyFile"/>
    </af:commandButton>
    

18.4.2 入力フィールドをリセットするためのコマンド・コンポーネントの使用方法

resetActionListenerタグとコマンド・コンポーネントを組み合せて使用すると、入力値をリセットできます。すべての値は、nullまたは空に戻されます。入力コンポーネントを以前の状態、つまりサーバーへの部分的または完全な送信が成功している状態にリセットする場合は、「リセット」ボタンを使用する必要があります。詳細は、9.2.3項「formへの「リセット」ボタンの追加方法」を参照してください。

リセット・タグを使用する手順:

  1. 18.2項「ボタンおよびリンクのナビゲーション目的での使用」の説明に従い、コマンド・コンポーネントを作成します。

  2. コンポーネント・パレットからリセット・アクション・リスナーをコマンド・コンポーネントの子としてドラッグ・アンド・ドロップします。

18.5 ページ階層用のナビゲーション・アイテムの使用


注意:

アプリケーションにADFコントローラを含むFusionテクノロジ・スタックが使用されている場合は、ADFタスク・フローおよびXMLMenuModel実装を使用して、アプリケーションのページ階層にナビゲーション・システムを作成します。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の「ページ階層の作成」を参照してください。


アプリケーションはツリー式階層に関連付けて編成されたページで構成されます。ユーザーは、リンクのパスをドリルダウンして、ページ上の特定の情報にアクセスします。たとえば、図18-4は、トップレベル・ノードであるHomeの下に3つのレベルのノードがある単純なページ階層を示しています。トップレベル・ノードは、ルートの親ページを表しています。第1レベルのノードであるBenefitsおよびEmployee Dataは、より詳細な情報を含む第2レベルの子ノード(InsuranceやView Employeeなど)に関する汎用情報が含まれる親ページを表しています。Insuranceノードも親ノードで、第3レベルの子ノードであるHealthとDentalに関する汎用情報が含まれています。ページ階層の各ノード(ルートのHomeノードを除く)は、同時に親ノードにも子ノードにもなることができ、ページ階層の各ノードは1つのページに対応しています。

図18-4 BenefitsおよびEmployeeページ階層

階層ページ・ツリー。2レベル、1ノードでグローバル・ノードが1つ。

ページ階層のナビゲーションは、親子のリンクに従います。たとえば、Healthの情報を表示するには、ユーザーはBenefitsページからドリルダウンを開始し、2つの選択肢(一方がHealth)が用意されているInsuranceページに移動します。Homeから始まり、Healthで終わる選択したリンクのパスは、ツリーのフォーカス・パスと呼ばれます。

直接の親子のナビゲーションのみでなく、レベル間または親間のナビゲーションも可能です。たとえば、Dentalページから、ユーザーは第2レベルのPaid Time Offページに移動することも、第1レベルのBenefitsページまたはEmployee Dataページに移動することもできます。

図18-4に示すように、階層内のどのノードにもリンクされていないが、トップレベルのHomeノードと同じレベルにあるHelpノードは、グローバル・ノードです。グローバル・ノードは、階層内のどのページからもアクセスできるグローバル・ページ(「ヘルプ」ページなど)を表します。

ページ階層のWebユーザー・インタフェースで使用される一般的なウィジェットは、タブ、バー、グローバル・リンクで、すべてnavigationPaneコンポーネントを使用して作成できます。図18-5に、navigationPaneおよびその他のコンポーネントを使用してレンダリングされた図18-4の階層を示します。

図18-5 レンダリングされたBenefitsおよびEmployeeページ

ページの階層メニュー・コンポーネント

図18-5に示すように、通常、タブは第1レベルのノードとして使用されます。ここでは、BenefitsおよびEmployee Detailページのタブがあります。InsuranceおよびPaid Time Offなどの第2レベルのノードはバーとして、HealthおよびDentalなどの第3レベルのノードはリストとしてレンダリングされます。ただし、タブは、第1および第2レベルのノードの両方に使用できます。(グローバル・ノードを表す)グローバル・リンクは、テキスト・リンクとしてレンダリングされます。図18-5で、Homeおよび「ヘルプ」グローバル・リンクはテキスト・リンクとしてレンダリングされています。

第1、第2、第3レベルのノードまたはグローバル・ノードのいずれであるかにかかわらず、1つのnavigationPaneコンポーネントは、1レベルのノードに対応します。ナビゲーション・アイテムのタイプに関係なく、navigationPaneコンポーネントはレベルに対してレンダリングするよう構成されており、navigationPaneコンポーネント内の各項目を表すには、必ずcommandNavigationItemコンポーネントを使用します。

navigationPaneコンポーネントは、ナビゲーション用のタブ、バー、リストおよびグローバル・リンクをレンダリングするだけです。図18-10図18-11に示されているような、位置指定やページ背景のビジュアルなスタイル設定を行うには、decorativeBoxコンポーネントを第1レベルのnavigationPaneコンポーネントの親として使用します。decorativeBoxコンポーネントは、テーマおよびスキニング・キーを使用して、その様々なファセットの枠および色を制御します。たとえば、デフォルトのテーマを使用する場合、decorativeBoxコンポーネント本体は白、枠は青で、左上隅は丸くなります。ミディアム・テーマを使用する場合、本体は中間色の青になります。テーマおよびスキンの使用の詳細は、第20章「スタイルおよびスキンを使用した外観のカスタマイズ」を参照してください。


ヒント:

ページ階層を作成するには、階層内の各ページで同じレイアウトおよびルック・アンド・フィールを使用する必要があるため、ナビゲーション・コンポーネントの配置場所やスタイルを決定するためにテンプレートの使用を検討してください。詳細は、19.3項「ページ・テンプレートの使用」を参照してください。


より単純な階層の各ページのために一連のnavigationPaneコンポーネントを使用し、階層の各レベルを表します。次に、各レベルの各リンクに、commandNavigationItemコンポーネントをnavigationPaneコンポーネントの直接の子として追加します。たとえば、図18-5に示すように、Health insuranceページを作成するには、まず、ページに表示された各レベルに対してnavigationPaneコンポーネントを使用します。この場合、使用するのは、グローバル・リンク、第1レベルのノード、第2レベルのノード、第3レベルのノードの4つのレベルです。個々のリンクを表示するには、各navigationPaneコンポーネントにcommandNavigationItemコンポーネントを子として追加する必要があります。図18-6に示すように、Benefitsページを作成していた場合、3つのnavigationPaneコンポーネント(グローバル、第1、第2レベルの3つのレベル)のみを作成します。次に、このページから表示されるリンク用にcommandNavigationItemコンポーネントを作成します。

図18-6 第1レベルのページ

第1レベルのページ

大規模な階層では、このプロセスは非常に時間がかかり、ミスも発生しやすくなります。大規模な階層の場合は、各ページに別々のcommandNavigationItemコンポーネントをそれぞれ作成するのではなく、XMLMenuModel実装およびマネージドBeanを使用して、ページのナビゲーション・アイテムを動的に生成することをお薦めします。メタデータ・ファイルとともに使用するXMLMenuModelクラスには、各ページに適切な数の階層レベルを生成するためのすべての情報と、各レベルに属するナビゲーション・アイテムが含まれます。navigationPaneコンポーネント内に複数のcommandNavigationItemコンポーネントを使用し、各ページで現在の項目を選択済としてマーキングするかわりに、各navigationPaneコンポーネントを宣言的に同じXMLMenuModel実装にバインドし、nodeStampファセットにcommandNavigationItemコンポーネントを1つ使用してナビゲーション・アイテムを指定します。commandNavigationItemコンポーネントは、navigationPaneコンポーネントのスタンプとして機能し、XMLMenuModelオブジェクトに保持されている(各レベルの)ノードのナビゲーション・アイテムにスタンプを設定します。デフォルトのActionListenerメカニズムを使用したJSFナビゲーション・モデルを使用して、ユーザーがナビゲーション・アイテムを選択した時のナビゲート先のページが選択されます。メニュー・モデルの詳細は、18.6項「メニュー・モデルを使用したページ階層の作成」を参照してください。

どのページでも、ユーザーの現在の位置をページ階層全体との関連で表示するには、一連のcommandNavigationItemコンポーネントまたは1つのcommandNavigationItemコンポーネントを含むbreadCrumbsコンポーネントをnodeStampとして使用し、現在のページ(フォーカス・パスの現在のノード)からルート・ページへ戻るリンクのパスを指定します。

XMLMenuModelを使用したナビゲーション階層の作成の詳細は、18.6項「メニュー・モデルを使用したページ階層の作成」を参照してください。ナビゲーション階層の手動による作成の詳細は、18.7項「単純なナビゲーション階層の作成」を参照してください。


注意:

アプリケーションの変更の反映に使用できるメニュー(「Open」および「Delete」コマンドが含まれる「File」メニューなど)を作成する場合は、第14章「メニュー、ツールバーおよびツールボックスの使用方法」を参照してください。


18.6 メニュー・モデルを使用したページ階層の作成


注意:

アプリケーションにFusionテクノロジ・スタックまたはADFコントローラが使用されている場合は、ADFタスク・フローおよびXMLMenuModel実装を使用して、アプリケーションのページ階層にナビゲーション・システムを作成します。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の「ページ階層の作成」を参照してください。


18.5項「ページ階層用のナビゲーション・アイテムの使用」に、複数のcommandNavigationItem子コンポーネントを含むnavigationPaneコンポーネントを使用して、非常に単純なページ階層用のナビゲーション・メニューを作成する方法が説明されています。より複雑なページ階層で同じ方法を使用すると時間がかかり、ミスが起こりやすくなります。ナビゲーションを可能にするすべての項目を作成するために、複数のJSFページのnavigationPaneおよびbreadCrumbsコンポーネントに個々のcommandNavigationItemコンポーネントを手動で挿入し構成するのは、非効率的で単調な作業です。各項目について正確なselectedステータスを管理したり、現在のページからルート・ページに戻るブレッドクラム・リンクをたどって追跡するのも困難です。

より複雑なページ階層の場合(および単純なページ階層の場合でも)、ナビゲーション・メニューを作成するより効率的な方法は、メニュー・モデルを使用することです。メニュー・モデルは、特別なツリー・モデルです。ツリー・モデルは、行キーで索引付けされた行のコレクションです。ツリーでは、現在行に子の行を含めることができます(ツリー・モデルの詳細は、10.5項「ツリーへのデータの表示」を参照してください)。メニュー・モデルは、現在フォーカス(フォーカス・ノード)があるノードのrowKeyを取得できるツリー・モデルです。メニュー・モデルにはページ・ナビゲーションの特別な情報はなく、ツリーにアクセスするノードに対する要件もありません。

XMLMenuModelクラスは、ナビゲーション・ツリー・モデルからメニュー・モデルを作成します。ただし、XMLMenuModelクラスには、XMLメタデータにナビゲーションの階層ツリーを定義できる追加のメソッドがあります。(他のADF Facesのメニュー・モデル・クラスの1つを使用している場合のように)Javaクラスを作成し多数のマネージドBeanを構成してメニュー・モデルを定義および作成するかわりに、XMLMenuModelクラスでメニュー・モデルを作成する際に必要なすべてのノード情報を含む1つ以上のXMLMenuModelメタデータ・ファイルを作成します。


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

メニュー・モデルを含むnavigationPaneコンポーネントを使用すると、ユーザーがタブを切り替えるたびにフル・ページ・リフレッシュが実行されます。かわりに、panelTabbedコンポーネントを使用できます(8.10項「アコーディオン・パネルおよびタブ付きのパネルにおけるコンテンツの表示または非表示」を参照)。このコンポーネントでは、タブ付きコンテンツの部分ページ・レンダリングがサポートされています。ただし、ナビゲーション・モデルにはバインドできず、ページ内からすべてのコンテンツにアクセスできる必要があるため、適用性は制限されています。


メニュー・モデルを使用してページ階層を作成する手順:

18.6.1 メニュー・モデル・メタデータの作成方法

XMLMenuModelメタデータ・ファイルは、XML形式によるページ階層用のナビゲーション・メニューの表現です。XMLMenuModelメタデータ・ファイルでは、ページ階層全体が、ファイルのルート要素であるmenu要素内に説明されています。各XMLMenuModelメタデータ・ファイルにはmenu要素が必要で、使用できるmenu要素は1つのみです。

階層の残りのノードは、項目ノード、グループ・ノードおよび共有ノードで構成されています。項目ノードは、階層のナビゲート可能なノード(またはページ)を表します。たとえば、図18-7に示すような階層を作成するとします。

図18-7 サンプルのページ階層

ナビゲーション・メニューの階層

階層の各ノードにユーザーがナビゲートできる独自のページを作成する場合は、各ページのメタデータに項目ノードを作成します。親ノードに子ノードをネストさせて階層を作成します。ただし、Employee Dataノードにはページが必要ないが、ユーザーが直接View Employeeページにナビゲートできるようにするとします。グループ・ノードを使用して「Employee Data」ページを表し、グループ・ノードのidref属性を使用して、エンド・ユーザーが「Employee Data」タブをクリックすると開かれるページ(「View Employee」ページ)を参照します。グループ・ノードを使用すると、単に子ノードの集約であるノード用にページを作成せずに階層を維持できます。

共有ノードを使用して、メニュー・モデルをネストすることもできます。ページ階層を維持しやすくなるため、この方法は、階層にサブ・ツリー(Benefitsツリーなど)がある場合にお薦めです。たとえば、アプリケーション全体で再利用できるように、Benefitsツリー全体を独自のモデルとして作成するとします。それぞれに使用するためにノードを作成するかわりに、別のメニューとして一度ノードを作成し、異なる階層内で、共有ノードを使用すると、Benefitsメニュー・モデルを参照できます。

例18-4に、図18-7に示されているページ階層を定義するための、XMLMenuModelメタデータ・ファイルを示します。

例18-4 XMLMenuModelメタデータ・ファイルのサンプル

<?xml version="1.0" encoding="windows-1252" ?>
<menu xmlns="http://myfaces.apache.org/trinidad/menu">
  <itemNode id="Home" focusViewId="/home.jspx" label="Home" action="goHome">
    <itemNode id="benefits" focusViewId="/benefits.jspx" action="goBene"
              label="Benefits">
      <itemNode id="insurance" focusViewId="/insurance.jspx" action="goIns"
                label="Insurance">
        <itemNode id="health" focusViewId="/health.jspx" action="goHealth"
                  label="Health"/>
        <itemNode id="dental" focusViewId="/dental.jspx" action="goDental"
                  label="Dental"/>
      </itemNode>
      <itemNode id="pto" focusViewId="/pto.jspx" action="goPto"
                label="Paid Time Off">
        <itemNode id="vacation" focusViewId="/vacation.jspx"
                  action="goVacation" label="Vacation"/>
        <itemNode id="sick" focusViewId="/sick.jspx" action="goSick"
                  label="Sick Pay"/>
      </itemNode>
    </itemNode>
    <groupNode id="empData" idref="newEmp" label="Employee Data">
      <itemNode id="newEmp" focusViewId="/createemp.jspx" action="goCreate"
                label="Create New Employee"/>
      <itemNode id="viewdata" focusViewId="/viewdata.jspx" action="goView"
                label="View Data"/>
    </groupNode>
  </itemNode>
  <itemNode id="Help" focusViewId="/globalhelp.jspx" action="goHelp"
            label="Help"/>
  <itemNode id="Preferences" focusViewId="/preferences.jspx" action="goPref"
            label="Preferences"/>
</menu>

ルートのmenu要素内において、グローバル・ノードは、menu要素の直接の子である任意のタイプのノードです。つまり、menu要素の下の第1レベルの要素はグローバル・ノードです。たとえば、例18-4のコードには、Home、Help、Preferencesの3つのグローバル・ノードが示されています。第1レベルの子ノード内に、ノードをネストさせて、さらに多くのレベルのナビゲーションを提供できます。たとえば、例18-4のコードでは、Homeの下にBenefitsとEmployee Dataの2つの第2レベルのノードが示されています。Benefits内では、InsuranceおよびPaid Time Offの2つの第3レベルのノードとその他のノードがあります。

JDeveloperでは、「ADFメニュー・モデルの作成」ウィザードを提供することで、XMLMenuModelクラス用のメタデータの作成が簡略化されています。

XMLMenuModelメタデータを作成する手順:

  1. ページ階層のすべてのノードのナビゲーション・ケースが含まれるグローバルなJSFナビゲーション・ルールを1つ作成します。

    たとえば、図18-4に示されているページ階層には、グローバルのHelpノードを含む10のノードがあります。この場合、例18-5に示すように、faces-config.xmlファイルの1つのグローバル・ナビゲーション・ルール内に10のナビゲーション・ケースを作成します。

    各ナビゲーション・ケースに、一意の結果文字列と、指定された文字列に一致する結果値がナビゲーション・システムによって返された場合に表示するJSFページへのパスを指定します。

    例18-5 faces-config.xml内のページ階層のグローバル・ナビゲーション・ルール

    <navigation-rule>
      <navigation-case>
        <from-outcome>goHome</from-outcome>
        <to-view-id>/home.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goHelp</from-outcome>
        <to-view-id>/globalhelp.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goEmp</from-outcome>
        <to-view-id>/empdata.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goBene</from-outcome>
        <to-view-id>/benefits.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goIns</from-outcome>
        <to-view-id>/insurance.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goPto</from-outcome>
        <to-view-id>/pto.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goView</from-outcome>
        <to-view-id>/viewdata.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goCreate</from-outcome>
        <to-view-id>/createemp.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goHealth</from-outcome>
        <to-view-id>/health.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goDental</from-outcome>
        <to-view-id>/dental.jspx</to-view-id>
      </navigation-case>
    ...
    </navigation-rule>
    

    JDeveloperにおけるナビゲーション・ケースの作成方法の詳細は、2.3項「ページ・フローの定義」を参照してください。

  2. アプリケーション・ナビゲータで、XMLMenuModelメタデータ・ファイルを作成するプロジェクトを探します。プロジェクトの「Webコンテンツ - WEB-INF」フォルダで、faces-config.xmlファイルを右クリックし、ポップアップ・メニューから「ADFメニューの作成」を選択します。


    注意:

    アプリケーションでADFコントローラが使用されている場合は、このメニュー・オプションを使用できません。かわりに、バインド・タスク・フローを使用して階層を作成できます。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の「ページ階層の作成」を参照してください。


  3. 「ADFメニュー・モデルの作成」ダイアログで、XMLMenuModelメタデータ・ファイルのファイル名(root_menuなど)を入力します。

  4. メタデータ・ファイルのディレクトリを入力します。JDeveloperにより、デフォルトで、アプリケーションのWEB-INFディレクトリにXMLMenuModelメタデータ・ファイルが保存されます。

    「OK」をクリックすると、JDeveloperにより自動的に次の操作が行われます。

    • 手順3で指定した名前がマネージドBean名として使用され、faces-config.xmlファイルにモデルのマネージドBeanが作成されます。

    • マネージドBeanのsourceマネージド・プロパティの値が、手順3で指定した/WEB-INF/root_menu.xmlなどのXMLMenuModelメタデータ・ファイルに設定されます。

    • 例18-6に示すように、ソース・ファイル(/WEB-INF/root_menu.xml)が、空のXMLMenuModelメタデータ・ファイルとしてソース・エディタに表示されます。

    例18-6 空のXMLMenuModelメタデータ・ファイル

    <?xml version="1.0" encoding="windows-1252" ?>
    <menu xmlns="http://myfaces.apache.org/trinidad/menu"></menu>
    

    JDeveloperにより自動的に追加されるマネージドBean構成の詳細は、18.6.2項「ADFメニュー・モデルの作成ウィザードを使用する場合の処理」を参照してください。

  5. 構造ウィンドウでmenuノードを選択し、プロパティ・インスペクタに適切な情報を入力します。

    表18-1に、menu要素に指定できる属性を示します。

    表18-1 menu要素の属性

    属性 説明

    resourceBundle

    オプション。実行時にナビゲーション・アイテムのラベル(表示可能なテキスト)に使用するリソース・バンドルです。org.apache.myfaces.demo.xmlmenuDemo.resource.MenuBundleなどです。

    var

    リソース・バンドルを使用している場合は、ナビゲーション・アイテム・ラベルのEL式のバンドルの参照に使用するIDを指定します。#{bundle.somelabel}などです。リソース・バンドルを使用するXMLMenuModelメタデータ・ファイルのサンプルは、例18-7を参照してください。

    xmlns

    必須。http://myfaces.apache.org/trinidad/menuに設定します。


    例18-7に、ナビゲーション・アイテムのラベルのリソース・バンドルにアクセスするためにEL式を使用する、サンプルのXMLMenuModelメタデータ・コードを示します。

    例18-7 リソース・バンドルを使用したXMLMenuModel

    <?xml version="1.0" encoding="windows-1252" ?>
    <menu xmlns="http://myfaces.apache.org/trinidad/menu"
          resourceBundle="org.apache.myfaces.demo.xmlmenuDemo.resource.MenuBundle"
          var="bundle">
      <itemNode id="in1" label="#{bundle.somelabel1}" ../>
      <itemNode id="in2" label="#{bundle.somelabel2}" ../>
    </menu>
    

    注意:

    sharedNode要素を使用してサブメニューを作成し、ナビゲーション・アイテムのラベルにリソース・バンドルを使用する場合は、共有メニュー・モデルでルートのmenu要素のvar属性に同じ値が使用される可能性があります。XMLMenuModelクラスでは、解析中に各リソース・バンドルに一意のハッシュ・キーが割り当てられていることを確認することにより、この可能性に対応します。


    リソース・バンドルの使用方法の詳細は、第21章「ページの国際化およびローカライズ」を参照してください。

  6. 構造ウィンドウで、必要に応じてitemNodegroupNodeまたはsharedNodeを使用して、階層のノードに必要な要素を追加します。まず、menuを右クリックして「menuの中に挿入」を選択し、図18-8に示されているように、ポップアップ・メニューから必要な要素を選択します。

    図18-8 menuに要素を挿入するためのポップアップ・メニュー

    menuに要素を挿入するためのポップアップ・メニュー

    要素は次のいずれかです。

    • itemNode: ユーザーによる選択時にナビゲーションを実行するノードを指定します。

    • groupNode: グループの子コンポーネントで、groupNode自体はナビゲーションを行いません。子ノードは、itemNodeまたは別のgroupNodeにすることができます。

      たとえば、Employee Dataノードにはページが必要ないが、ユーザーが直接View Employeeページにナビゲートできるようにするとします。必要な子ノードのid属性をグループ・ノードのidref属性の値として指定することで、グループ・ノードを使用して「Employee Data」ページを表します。グループ・ノードを使用すると、単に子ノードの集約であるノード用にページを作成せずに階層を維持できます。

    • sharedNode: 別のXMLMenuModelインスタンスを参照します。sharedNode要素は真のノードではなく、ナビゲーションの実行もノード自体へのレンダリングも行われません。

      sharedNode要素は、階層内の任意の場所に挿入できます。たとえば、例18-8に示されているコードでは、sharedNode要素によりグローバル・ノードと同じレベルにサブメニューが追加されています。

      例18-8 sharedNodeのサンプル・コード

      <?xml version="1.0" encoding="windows-1252" ?>
      <menu xmlns="http://myfaces.apache.org/trinidad/menu"
        <itemNode id="in1" label="Home" ../>
        <sharedNode ref="#{shared_menu}"/>
        <itemNode id="in6" label="Help" ../>
      </menu>
      

    XMLMenuModelメタデータ・ファイルを作成すると、図18-9に示すように、メニュー・メタデータのインデント・レベルが構造ウィンドウに表示されるツリー構造に正確に反映されます。

    図18-9 構造ウィンドウのXMLMenuModelメタデータのツリー構造

    構造ウィンドウのツリー構造
  7. ノードの作成に使用されている各要素に、プロパティ・インスペクタでプロパティを設定します。itemNode要素は表18-2に、groupNode要素は表18-3に、sharedNode要素は表18-4に説明されています。

    表18-2 itemNode要素の属性

    属性 説明

    action

    結果文字列、または結果文字列を返すELメソッド・バインディング式を指定します。どちらの場合も、結果文字列は、faces-config.xmlファイルに構成されているように、そのノードのナビゲーション・ケースに対するfrom-outcome値に一致する必要があります。

    destination

    ノードが選択されたときにナビゲートするページのURIを指定します(例: http://www.oracle.com)。ナビゲート先がJSFページの場合、URIは/facesで開始する必要があります。

    または、そのURIに評価されるELメソッド式を指定します。

    actionおよびdestinationの両方が指定されている場合は、actionよりdestinationが優先されます。

    focusViewId

    必須。ノードのナビゲーション結果に一致するページのURI。つまり、faces-config.xmlファイルに指定されているそのノードのナビゲーション・ケースのto-view-id値。

    たとえば、ノードのアクション結果が(faces-config.xmlファイルに構成されているように)/page_one.jspxにナビゲートする場合は、focusViewId/page_one.jspxであることが必要です。

    focusViewIdは、ナビゲーションは実行しません。ページ・ナビゲーションは、actionまたはdestination属性によって行われます。ただし、XMLMenuModelが現在のフォーカス・パスを確認するためにfocusViewIdが必要です。

    id

    必須。ノードの一意の識別子を指定します。

    例18-4に示されているように、各itemNodeのIDにinXを使用することをお薦めします。ここで、inXはin1、in11、in111、in2、in21、in 211などです。

    label

    ノードに表示するラベル・テキストを指定します。#{bundle.somelabel}など、リソース・バンドルの文字列に対するEL式も使用できます。このbundleは、ルートmenu要素のvar属性の値に一致する必要があります。


    groupNode要素には、直接ナビゲーションを実行するactionまたはdestination属性はありませんが、(actionまたはdestination属性のある)子のitemNodeを直接示すか、itemNode要素に到達するまで、子ノードのいずれかを示す子のgroupNodeを間接的に示すことにより、アクション結果または宛先のURIを含む子ノードを示します。ナビゲーションは、その後、アクション結果またはそのitemNode要素の宛先のURIから決定されます。

    例18-9に示されているgroupNodeのコードを例にとります。実行時、ユーザーがgroupNode id="gn1"groupNode id="gn11"またはitemNode id="in1"をクリックすると、到達した最初のitemNode (つまり、itemNode id="id1")に指定されているように、ナビゲーション結果はgoToSubTabOneになります。表18-3に、groupNode要素を使用する際に指定する必要のある属性を示します。

    例18-9 groupNode要素

    <?xml version="1.0" encoding="windows-1252" ?>
    <menu xmlns:"http://myfaces.apache.org/trinidad/menu">
      <groupNode id="gn1" idref="gn11" label="GLOBAL_TAB_0">
        <groupNode id="gn11" idref="in1" label="PRIMARY_TAB_0">
          <itemNode id="in1" label="LEVEL2_TAB_0" action="goToSubTabOne"
                    focusViewId="/menuDemo/subtab1.jspx"/>
          <itemNode id="in2" label="LEVEL2_TAB_1" action="goToSubTabTwo"
                    focusViewId="/menuDemo/subtab2.jspx"/>
        </groupNode>
        <itemNode id="in3" label="PRIMARY_TAB_1" focusViewId="/menuDemo/tab2.jspx"
                  destination="/faces/menuDemo/tab2.jspx"/>
      </groupNode>
      <itemNode id="gin1" label="GLOBAL_TAB_1" action="goToGlobalOne" 
                focusViewId="/menuDemo/global1.jspx"/>
      <itemNode id="gin2" label="GLOBAL_TAB_2" 
                destination="/faces/menuDemo/global2.jspx"
                focusViewId="/menuDemo/global2.jspx"/>
    </menu>
    

    表18-3 groupNode要素の属性

    属性 説明

    id

    グループ・ノードの一意の識別子。

    例18-4に示されているように、各groupNodeのIDにgnXを使用することをお薦めします。ここで、gnXgn1gn2などです。

    idref

    子ノードのID (itemNodeまたは別のgroupNode)を指定します。子ノードとしてgroupNodeを追加する場合、その子は別のgroupNodeなどを参照できますが、最終的には、子のitemNodeは最後の子として参照する必要があります。

    idref属性には、空白で区切って複数の子IDを指定でき、IDはリストされた順序で処理されます。

    label

    グループ・ノードに表示するラベル・テキストを指定します。リソース・バンドルの文字列へのEL式(#{bundle.somelabel}など)にすることもできます。


    表18-4 sharedNode要素の属性

    属性 説明

    ref

    faces-config.xmlファイルに構成されているように、別のXMLMenuModelクラスのマネージドBean名(#{shared_menu}など)を指定します。

    実行時に、参照ナビゲーション・メニューが作成され、メイン(ルート)のメニューにサブメニューとして挿入されてレンダリングされます。


18.6.2 「ADFメニュー・モデルの作成」ウィザードを使用する場合の処理

「ADFメニュー・モデルの作成」ウィザードを使用してXMLMenuModelメタデータ・ファイルを作成する場合、マネージドBean名として指定したメタデータ・ファイル名を使用して、JDeveloperによりfaces-config.xmlファイルのメタデータ・ファイルにマネージドBeanが自動的に構成されます。

例18-10に、XMLMenuModelメタデータ・ファイルの構成が1つ含まれるfaces-config.xmlファイルの一部を示します。JDeveloperでは、デフォルトで、oracle.adf.view.rich.model.MDSMenuModelクラスがマネージドBeanクラスとして使用され、必須で変更できないrequestはマネージドBeanスコープとして使用されます。

例18-10 faces-config.xml内のXMLMenuModelのマネージドBean構成

<managed-bean>
    <managed-bean-name>root_menu</managed-bean-name>
    <managed-bean-class>oracle.adf.view.rich.model.
                       MDSMenuModel</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
      <property-name>createHiddenNodes</property-name>
      <value>false</value>
    </managed-property>
    <managed-property>
      <property-name>source</property-name>
      <property-class>java.lang.String</property-class>
      <value>/WEB-INF/root_menu.xml</value>
    </managed-property>
</managed-bean>

また、各XMLMenuModelのマネージドBeanに、次のマネージド・プロパティが追加されます。

  • createHiddenNodes: trueの場合、コンポーネントのrendered属性がfalseの場合でも、階層ノードを作成する必要があることを指定します。createHiddenNodes値は、取得されて、ソース・メニュー・メタデータ・ファイルが開かれて解析されると使用可能になります。これにより、実際のコンポーネントをレンダリングする必要がない場合でも、階層全体を作成できます。

    createHiddenNodesプロパティは、sourceプロパティの前に配置する必要があります。JDeveloperによってマネージドBeanが自動的に設定される際は、このように配置されます。sourceマネージド・プロパティからメニューのXMLメタデータを適切に解析および作成するには、この値がXMLMenuModelマネージドBeanに事前に設定されている必要があります。

  • source: 使用するソース・メタデータ・ファイルを指定します。

ウィザードを使用してプロジェクトに作成する各XMLMenuModelメタデータ・ファイルに対し、JDeveloperにより、faces-config.xmlファイルにマネージドBeanが構成されます。たとえば、(例18-8に示すように)別のXMLMenuModelメタデータ・ファイルを参照するために、XMLMenuModelsharedNode要素を使用すると、2つのメタデータ・ファイルが作成されます。また、例18-11に示すように、JDeveloperにより、faces-config.xmlファイルに2つのマネージドBean構成(1つ目はメイン(ルート)メニュー・モデル用、2つ目のマネージドBeanは共有(参照)メニュー・モデル用)が追加されています。

例18-11 faces-config.xml内の共有メニュー・モデルのマネージドBean

<!-- managed bean for referenced, shared menu model -->
<managed-bean>
  <managed-bean-name>shared_menu</managed-bean-name>
  <managed-bean-class>
  <managed-bean-class>oracle.adf.view.
                      rich.model.MDSMenuModel</managed-bean-class>
  </managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
  <managed-property>
    <property-name>createHiddenNodes</property-name>
    <value>true</value>
  </managed-property>
  <managed-property>
    <property-name>source</property-name>
    <property-class>java.lang.String</property-class>
    <value>/WEB-INF/shared_menu.xml</value>
  </managed-property>
</managed-bean>

つまり、XMLMenuModelメタデータ・ファイルに共有ノードを使用すると、faces-config.xmlファイルには、ルート・メニュー・モデルのマネージドBeanと、共有ノードを介して参照される任意のメニュー・モデル用のメニュー・モデルのマネージドBeanが含まれます。

18.6.3 JSFページでのXMLMenuModelへのバインド方法

ページ階層の各ノードは1つのJSFページに対応します。各ページで、XMLMenuModelメタデータ・ファイルに定義したナビゲーション・アイテム(グローバル・アイテムも含む)の各レベルにnavigationPaneコンポーネントを1つ使用します。レベルはゼロベースの索引の番号によって定義されます。メタデータ・ファイルのグローバル・ノード(すなわち、例18-4で示されているように、menu要素の下の直接の子ノード)から始まり、level属性値は0(ゼロ)で、次のレベル(通常はタブ)は1、その次のレベル(通常はバー)は2、などのように続きます。たとえば、図18-7および例18-4に示すようなページ階層がある場合、(Homeノードの下の3つのレベルのナビゲーションに)Homeなどのページで3つのnavigationPaneコンポーネントを使用し、グローバル・ノードにnavigationPaneコンポーネントをもう1つ使用します。


ヒント:

メニュー・モデルにより、動的に階層(各navigationPaneコンポーネントに表示されるリンク)が決定され、フォーカス・パスの現在のノードが選択済として設定されるため、事実上、各ページに同じコードを再利用できます。実行する必要があるのは、ページのドキュメント・タイトルの変更と、そのページに表示する特定のページ・コンテンツの追加のみです。

コードが似ているため、navigationPaneコンポーネントを含むファセットのみが存在する単一のページ・フラグメントを作成し、ページのドキュメント・タイトルの変更やページ・コンテンツの追加を行う各ページにそのフラグメントを追加できます。


18.7.1項「単純なページ階層の作成方法」で説明されているように、各階層レベルに使用するナビゲーション・アイテムのタイプ(buttonstabsまたはbarなど)を指定するにはhint属性を使用します。ただし、複数のcommandNavigationItemコンポーネントを手動で追加してナビゲーション・アイテムを指定するのではなく、例18-12に示すように、各navigationPaneコンポーネントをXMLMenuModelマネージドBeanにバインドし、各navigationPaneコンポーネントのnodeStampファセットにcommandNavigationItemコンポーネントを1つのみ挿入します。

例18-12 XMLMenuModelマネージドBeanにバインドされたnavigationPaneコンポーネント

<af:navigationPane var="menuNode" value="#{root_menu}" level="1"
                   hint="tabs">
  <f:facet name="nodeStamp">
    <af:commandNavigationItem text="#{menuNode.label}"
                              action="#{menuNode.doAction}"
                              icon="#{menuNode.icon}"
                              destination="#{menuNode.destination}"
                              visible="#{menuNode.visible}"
                              rendered="#{menuNode.rendered}"/>
  </f:facet>
</af:navigationPane>

XMLMenuModelマネージドBeanとともに使用するnodeStampファセットと単一のcommandNavigationItemコンポーネントにより、次の操作が実行されます。

  • レベル内のナビゲーション・アイテムの適切な数がスタンプ設定されます。

  • 正しいラベル・テキストとその他のプロパティが、メタデータに定義されているとおりに表示されます。たとえば、EL式#{menuNode.label}によりナビゲーション・アイテムに使用する適切なラベル・テキストが取得され、#{menuNode.doAction}は同じ項目に定義されているアクション結果に評価されます。

  • フォーカス・パスの現在の項目が選択済とマークされます。commandNavigationItemコンポーネントにはselected属性は指定できません。


注意:

特定の階層レベル(第3レベルのリストなど)のXMLMenuModelオブジェクトにノード情報がない場合、ページにはそのレベルのnavigationPaneコードが含まれていても、ADF Facesではページにそれらの項目は表示されません。


XMLMenuModelマネージドBeanにバインドする手順:

  1. メニュー・タブのスタイルを設定する場合は、コンポーネント・パレットのレイアウト・セクションから装飾ボックスをJSFページにドラッグ・アンド・ドロップして、decorativeBoxコンポーネントを作成します。テーマを設定して、タブの表示方法を決定します。有効な値は次のとおりです。

    • default: 本体は白で、枠は青です。左上隅は丸くなります。

    • light: 本体は薄い青です。左上隅は丸くなります。

    • medium: 本体は中間色の青です。左上隅は丸くなります。

    • dark: 本体は濃い青です。左上隅は丸くなります。

    テーマの表示方法は変更できます。詳細は、第20章「スタイルおよびスキンを使用した外観のカスタマイズ」を参照してください。

  2. コンポーネント・パレットからJSFページにナビゲーション・ペインをドラッグ・アンド・ドロップして、navigationPaneコンポーネントを作成します。階層の各レベルにnavigationPaneコンポーネントを追加します。


    ヒント:

    ナビゲーション・ペイン・コンポーネントは、コンポーネント・パレットのレイアウト・ペインにあります。


    たとえば、図18-5の階層のようなページを作成するには、navigationPaneコンポーネントを4つドラッグ・アンド・ドロップします。

  3. プロパティ・インスペクタで「共通」セクションを開き、各navigationPaneコンポーネントのhint属性を次に示すナビゲーション・アイテムのいずれかのタイプに設定して、navigationPaneで次のものをどのように表示するかを決定します。

    • bar: バーで分割されたナビゲーション・アイテムを表示します。図18-11InsuranceおよびPaid Time Offリンクなどがこれに当たります。

    • buttons: グローバル領域のバーで分割されたナビゲーション・アイテムを表示します。図18-11Homeおよび「ヘルプ」リンクなどがこれに当たります。

    • choice: 関連付けられたドロップダウン・アイコンがクリックされたときに、ポップアップ・リストにナビゲーション・アイテムを表示します。navigationPaneコンポーネントのicon属性に値を含める必要があり、title属性を使用してドロップダウン・リストにラベルを関連付けることができます。

    • list: ナビゲーション・アイテムを箇条書きリストで表示します。図18-11HealthおよびDentalリンクなどがこれに当たります。

    • tabs: ナビゲーション・アイテムをタブで表示します。図18-11BenefitsおよびEmployee Dataタブなどがこれに当たります。

  4. XMLMenuModelメタデータ・ファイルのメタデータの適切なレベルを指すように、level属性を設定します。level属性はゼロベースの索引の番号によって定義されます。メタデータ・ファイルのグローバル・ノード(すなわち、例18-4で示されているように、menu要素の下の直接の子ノード)から始まり、level属性値は0(ゼロ)で、次のレベル(通常はタブ)は1、その次のレベル(通常はバー)は2、などのように続きます。

    commandNavigationItemコンポーネントは、親のnavigationPaneコンポーネントのlevel属性を介して、メタデータ・ファイルからメタデータを取得することができます。level属性の値を指定しない場合は、デフォルトで0 (ゼロ)が使用され、これは、navigationPaneコンポーネントが、commandNavigationItemコンポーネントによるレンダリング用に、menu要素の下にある第1レベルからメタデータを取得することを意味します。

  5. プロパティ・インスペクタで、「データ」セクションを開きます。value属性を、faces-config.xmlファイルのルートXMLMenuModelクラスに構成されているメニュー・モデルのマネージドBeanに設定します。


    注意:

    value属性が参照できるのは、ルート・メニュー・モデルと共有ノードによって参照されるメニュー・モデルです。値属性で共有ノードを参照する場合、faces-config.xmlファイルは、メニュー・モデル・メタデータ・ファイルのルート・メニュー・モデル定義で使用されるものではなく、異なるマネージドBeanの名前の新しいマネージドBeanエントリを含む必要があります。これにより、value属性で参照可能なルート・メニュー・モデルに共有ノードのメニュー・モデルがプロモートされます。


  6. var属性を、メニュー・モデルから必要なデータを取得するためにcommandNavigationItemコンポーネントで使用するテキストに設定します。

    実行時に階層が作成されて各ノードにスタンプが設定されると、EL式を使用して特定可能なvar属性に現在のノードのデータがコピーされます。varプロパティを使用して、このプロパティに使用する名前をEL式に指定します。


    ヒント:

    ページまたはアプリケーションのすべてのnavigationPaneコンポーネントのvar属性に同じ値を使用します。


  7. navigationPaneコンポーネントのnodeStampファセットに、コンポーネント・パレットから「ナビゲーション・アイテム」をドラッグ・アンド・ドロップします。

  8. (必要な情報が含まれるメタデータを持つ)メニュー・モデルを参照するEL式を使用して、対応する値がメタデータに保持される残りの属性に値を設定します。手順6で、値がメタデータで保持されている対応するitemNode要素の名前とともに、親のnavigationPaneコンポーネントに設定したvar属性の値を使用してこれらの値にアクセスします。表18-5に、対応する値がメタデータにあるナビゲーション・アイテムの属性を示します。

    表18-5 ナビゲーション・アイテムの属性および関連付けられたメニュー・モデルの属性

    ナビゲーション・アイテムの属性 関連付けられたメニュー・モデル要素の属性

    text

    label

    action

    doAction

    icon

    icon

    destination

    destination

    visible

    visible

    rendered

    rendered


    たとえば、親のnavigationPaneコンポーネントのvar属性をmenuNodeに設定した場合、action属性の値のEL式として#{menuNode.doAction}を使用します。これは、各ノードのメタデータに設定されているactionプロパティに解決されます。例18-13に、HRの例のメニュー・モデルにバインドするためのJSFコードを示します。

    例18-13 XMLモデルへのバインド

    <af:form>
      <af:navigationPane hint="buttons" level="0" value="#{root_menu}"
                         var="menuNode">
        <f:facet name="nodeStamp">
          <af:commandNavigationItem text="#{menuNode.label}"
                                    action="#{menuNode.doAction}"
                                    icon="#{menuNode.icon}"
                                    destination="#{menuNode.destination}"/>
        </f:facet>
      </af:navigationPane>
      <af:navigationPane hint="tabs" level="1" value="#{root_menu}"
                         var="menuNode">
        <f:facet name="nodeStamp">
          <af:commandNavigationItem text="#{menuNode.label}"
                                    action="#{menuNode.doAction}"
                                    icon="#{menuNode.icon}"
                                    destination="#{menuNode.destination}"/>
        </f:facet>
      </af:navigationPane>
      <af:navigationPane hint="bar" level="2" value="#{root_menu}"
                         var="menuNode">
        <f:facet name="nodeStamp">
          <af:commandNavigationItem text="#{menuNode.label}"
                                    action="#{menuNode.doAction}"
                                    icon="#{menuNode.icon}"
                                    destination="#{menuNode.destination}"/>
        </f:facet>
      </af:navigationPane>
      <af:navigationPane hint="list" level="3" value="#{root_menu}"
                         var="menuNode">
        <f:facet name="nodeStamp">
          <af:commandNavigationItem text="#{menuNode.label}"
                                    action="#{menuNode.doAction}"
                                    icon="#{menuNode.icon}"
                                    destination="#{menuNode.destination}"/>
        </f:facet>
      </af:navigationPane>
    </af:form>
    

18.6.4 breadCrumbsコンポーネントの使用方法

メニュー・モデルを使用したブレッドクラムの作成は、ページ階層の作成に似ています。commandNavigationItemコンポーネントにスタンプを設定するnodeStampファセットを含むbreadCrumbsコンポーネントは、モデルのデータとともに使用します。

ブレッドクラムを作成する手順:

  1. コンポーネント・パレットからJSFページにブレッド・クラム・コンポーネントをドラッグ・アンド・ドロップして、breadCrumbsコンポーネントを作成します。

  2. デフォルトでは、ブレッドクラム・リンクは水平に表示されます。レイアウトが垂直になるように変更するには、プロパティ・インスペクタで、「共通」セクションを開き、orientation属性をverticalに設定します。

  3. プロパティ・インスペクタで、「データ」セクションを開きます。faces-config.xmlファイルに構成されているように、value属性をルート・メニュー・モデルのマネージドBeanに設定します。これが、navigationPaneコンポーネントがバインドされるのと同じBeanです。


    注意:

    value属性が参照できるのは、共有ノードを介して参照されるメニュー・モデルではなく、ルート・メニュー・モデルのみです。たとえば、(例18-8に示されているように)メインのXMLMenuModel要素に共有ノードを使用している場合は、JDeveloperにより、その共有ノードにマネージドBean構成が作成され、共有モデルを使用するルートXMLMenuModel Beanも作成されます。共有モデルのマネージドBeanは、起動時にメニュー・ツリーが解析されると、ルート・メニュー・モデルのマネージドBeanに自動的に組み込まれます。


  4. var属性を、メニュー・モデルから必要なデータを取得するためにcommandNavigationItemコンポーネントで使用するテキストに設定します。

    実行時に階層が作成されて各ノードにスタンプが設定されると、EL式を使用して特定可能なvar属性に現在のノードのデータがコピーされます。varプロパティを使用して、このプロパティに使用する名前をEL式に指定します。


    ヒント:

    ページまたはアプリケーションのnavigationPaneコンポーネントで実行したように、breadCrumbsコンポーネントのvar属性に同じ値を使用できます。


  5. コンポーネント・パレットから「ナビゲーション・アイテム」をドラッグ・アンド・ドロップし、breadCrumbsコンポーネントのnodeStampファセットに、子としてcommandNavigationItemコンポーネントを1つ追加します。


    注意:

    breadCrumbsコンポーネントのnodeStampファセットは、breadCrumbsコンポーネントのvalue属性に指定されたメニュー・モデルに応じて、表示するリンクを決定します。breadCrumbsコンポーネントのvalue属性に、レンダリングするメニュー・モデルを指定しない場合は、実行時にリンクが表示されません。スタンプ設定が不要なためメニュー・モデルを使用しない場合は、breadCrumbsコンポーネントにnodeStampファセットを使用しないでください。


  6. (必要な情報が含まれるメタデータを持つ)メニュー・モデルを参照するEL式を使用して、対応する値がメタデータに保持される残りの属性に値を設定します。手順4で、値がメタデータで保持されている対応するitemNode要素の名前とともに、親のbreadCrumbsコンポーネントに設定したvar属性の値を使用してこれらの値にアクセスします。表18-5に、対応する値がメタデータにあるナビゲーション・アイテムの属性を示します。

    たとえば、breadCrumbsコンポーネントのvar属性をmenuNodeに設定した場合、action属性の値のEL式として#{menuNode.doAction}コンポーネントを使用します。これは、各ノードのメタデータに設定されているactionプロパティに解決されます。

    例18-14 MenuModelにバインドされたbreadCrumbsコンポーネント

    <af:breadCrumbs var="menuNode" value="#{root_menu}">
      <f:facet name="nodeStamp">
        <af:commandNavigationItem text="#{menuNode.label}"
                                  action="#{menuNode.doAction}"/>
      </f:facet>
    </af:breadCrumbs>
    

18.6.5 実行時に行われる処理

navigationPaneコンポーネントのvalue属性は、XMLMenuModel要素のマネージドBeanを参照します。そのマネージドBeanがリクエストされると、次の処理が実行されます。

  • faces-config.xmlファイルのmanaged-property要素に指定されているように、XMLMenuModelクラスのsetSource()メソッドが、モデルのメタデータの場所を使用してコールされます。

  • パーサー(SAXParser)が、メタデータへのInputStreamオブジェクトを使用できるようになります。ナビゲーション・アイテムのメタデータが解析され、MenuContentHandlerメソッドへのコールが実行されます。

  • MenuContentHandlerにより、次のようにして、ナビゲーション・メニューのツリー構造がListオブジェクトとして作成されます。

    • メタデータ内のノードの処理が開始される際に、startElement()メソッドがコールされます。

    • ノードの処理の終了時に、endElement()メソッドがコールされます。

    • 各ノードが処理されると、メニュー・モデルのページ階層を構成するナビゲーション・メニュー・ノードのListが作成されます。

  • ナビゲーション・メニュー・ノードのリストから、TreeModelオブジェクトが作成されます。

  • TreeModelオブジェクトからXMLMenuModelオブジェクトが作成されます。

groupNode要素のidref属性に複数の子IDがある場合は、次の処理が実行されます。

  • IDはリストされている順序で処理されます。現在のIDで子ノードが検出されない場合は次のIDが使用され、これが繰り返されます。

  • idrefリストの現在のIDに一致する子ノードが検出されると、そのノードでは、rendered属性がtrueに設定されていること、disabled属性がfalseに設定されていること、readOnly属性がfalseに設定されていること、およびvisible属性がtrueに設定されていることが確認されます。条件のいずれかが一致しない場合は、idrefリストの次のIDが使用され、これが繰り返されます。

  • 条件に一致する最初の子ノードは、アクション結果または宛先のURIの取得に使用されます。条件に一致する子ノードが検出されない場合は、エラーが記録されます。ただし、UIにはエラーは表示されません。

  • 条件に一致する最初の子ノードが別のgroupNode要素の場合、処理はその子に続行されます。処理は、actionまたはdestination属性を含むitemNode要素が出現すると止まります。

  • itemNode要素にaction属性がある場合は、ユーザーの選択によりPOSTアクションが開始され、アクション結果を介してナビゲーションが実行されます。itemNode要素にdestination属性がある場合は、ユーザーの選択によりGETアクションが開始され、destination値を使用して直接ナビゲーションが実行されます。

XMLMenuModelクラスには、ナビゲーション・メニュー・システムを使用してナビゲートすると、ナビゲーション・メニューの項目(タブやバーなど)が適切に強調表示および有効にされるモデルがあります。モデルはlabeldoAction、およびナビゲーション・アイテムの動的な生成に使用されるその他のプロパティの値でもインスタンス化されます。

XMLMenuModelクラスではレンダリングは行われません。navigationPaneコンポーネントでは、コールからgetFocusRowKey()メソッドへの戻り値を使用して、レベルのナビゲーション・メニュー・アイテムがページにレンダリングされます。

navigationPaneコンポーネントのnodeStampファセットの中のcommandNavigationItemコンポーネントは、各ナビゲーション・アイテムのラベル・テキストおよびアクション結果を提供します。nodeStampファセットがスタンプ設定されるたびに、現在のナビゲーション・アイテムのデータが到達可能なELプロパティにコピーされます。その名前は、nodeStampファセットを格納するnavigationPaneコンポーネントのvar属性によって定義されます。nodeStampは、到達可能なELプロパティからさらにプロパティを取得して、各アイテムのデータを表示します。ナビゲーション・メニューがレンダリングを完了すると、このプロパティは削除されます(または元の値に戻されます)。ユーザーがナビゲーション・アイテムを選択すると、デフォルトのJSF actionListenerメカニズムでは、アクション結果文字列または宛先URIを使用してページ・ナビゲーションを処理します。

nodeStampファセットとともに、XMLMenuModelクラスも、ナビゲーション・アイテムを選択されたものとしてレンダリングするかどうかを制御します。前述のように、XMLMenuModelオブジェクトは、各ノードのviewId属性情報を含むツリー・モデルから作成されます。XMLMenuModelクラスには、どのページにフォーカスを置くかを決定するメソッドgetFocusRowKey()があり、ノードにフォーカス・パスがある場合は、選択されたものとして自動的にノードをレンダリングします。最も単純なgetFocusRowKey()メソッドでは、次の内容が実行されます。

  • 現在のviewId属性が取得されます。

  • 重複するviewId値の解決に使用される内部マップのID、およびメニュー・モデルの作成時にツリーをトラバースすることにより作成されたviewIdFocusPathMapオブジェクトのIDと、viewId属性の値が比較されます。

  • 現在のviewId属性があるノードへのフォーカス・パスが返されるか、現在のviewId属性値が検出されない場合にはnullが返されます。

ノードのviewId属性は、フォーカスrowKeyオブジェクトの特定に使用されます。モデルの各項目には、現在のrowKeyオブジェクトに基づいてスタンプが設定されます。ユーザーがナビゲートして現在のviewId属性が変更されると、モデルのフォーカス・パスも変更されて、新しいナビゲーション・アイテムのセットがアクセスされます。

18.6.6 カスタム属性の使用に関する必知事項

作成したカスタム属性を表示できるのはitemNode要素のみです。itemNode要素を追加してカスタム属性の値にアクセスできるようにするには、次のようにしてメニュー・モデルからツリーを取得する必要があります。

  • メニュー・モデルのgetWrappedData()メソッドをコールします。

  • getFocusRowKey()メソッドをコールして、現在のフォーカス・パスを取得します。

  • このフォーカス・パスを使用してツリーをトラバースし、フォーカス・パスのノードのリストを返します。

  • getCustomProperty() APIをコールし、カスタム属性に関してこれらのノードを1つ以上テストします。

例18-15に、必要なコードの例を示します。

例18-15 XMLMenuModelからのカスタム属性へのアクセス

  /**
    * Returns the nodes corresponding to a focus path
    * 
    * @param tree
    * @param focusPath
    */
    public List getNodesFromFocusPath(TreeModel tree, ArrayList focusPath)
    {
      if (focusPath == null || focusPath.size() == 0)
        return null;
 
      // Clone the focusPath cause we remove elements
      ArrayList fp = (ArrayList) focusPath.clone();
  
      // List of nodes to return
      List nodeList = new ArrayList<Object>(fp.size());
  
      // Convert String rowkey to int and point to the
      // node (row) corresponding to this index
      int targetNodeIdx = Integer.parseInt((String)fp.get(0));
      tree.setRowIndex(targetNodeIdx);
 
      // Get the node
      Object node = tree.getRowData()
 
      // put the Node in the List
      nodeList.add(node);
 
      // Remove the 0th rowkey from the focus path
      // leaving the remaining focus path
      fp.remove(0);
  
      // traverse into children 
      if (   fp.size() > 0
          && tree.isContainer() 
          && !tree.isContainerEmpty()
         )
      {
        tree.enterContainer();
  
        // get list of nodes in remaining focusPath
        List childList = getNodesFromFocusPath(tree, fp);
  
        // Add this list to the nodeList
        nodeList.addAll(childList);
  
        tree.exitContainer();
      }
  
      return nodeList;
    } 
 
  public String getElementLabel(XMLMenuModel model, Object myVal, String myProp)
  {
     TreeModel tree = model.getWrappedData();
     
     Object node = findNodeByPropertyValue(tree, myVal, myProp);
 
     FacesContext context = FacesContext.getCurrentInstance();
     PropertyResolver resolver = context.getApplication().getPropertyResolver();
     
     String label = (String) resolver.getValue(node, _LABEL_ATTR);
     
     return label;
  }
 
  public Object findNodeByPropertyValue(TreeModel tree, Object myVal, String myProp)
  {
    FacesContext context = FacesContext.getCurrentInstance();
    PropertyResolver resolver = context.getApplication().getPropertyResolver();
    
    for ( int i = 0; i < tree.getRowCount(); i++)
    {
      tree.setRowIndex(i);
 
      // Get a node
      Object node = tree.getRowData();
      
      // Get the value of the attribute of the node
      Obect propVal = resolver.getValue(node, myProp);
      
      if (propVal == myVal)
      { 
        return node;
      }        
      
      if (tree.isContainer() && !tree.isContainerEmpty())
      {
        tree.enterContainer();
        node = findNodeByPropertyValue(tree, myVal, myProp);
 
        if (node != null)
          return node;
 
        tree.exitContainer();
      }guap
    }
    return null;
  }  

18.7 単純なナビゲーション階層の作成

図18-10および図18-11に、navigationPaneコンポーネントおよび個々のcommandNavigationItemコンポーネントを使用して、図18-4に示すページ階層のビューを作成した場合に、ユーザー・インタフェースがどのように表示されるかの例を示します。

図18-10 View Employeeページから使用可能なナビゲーション・アイテム

navigationPaneを使用したナビゲーション・アイテム

手動で階層を作成する場合には、各ページのフォーカス・パス(ページが存在する階層内の正確な場所)を確認し、各ページに必要なnavigationPanescommandNavigationItemコンポーネントの正確な数、ならびにユーザーがページを表示した際に各コンポーネントを選択済として構成する必要があるかどうかを決定する必要があります。たとえば、Employee Dataページが表示されている図18-10では、必要なものはEmployee Dataの子のバーのみで、Employee Dataタブは選択済としてレンダリングされています。

Healthページを表示している図18-11でも同様に、Benefitsでは子のバーのみが必要であり、Benefitsタブを選択済として構成する必要があります。このページではさらに、Insuranceの下に子ノードを作成します。これは、ページの横に垂直のリストとして表示されます。ページのコンテンツが中央に(垂直のリストの右側)に表示されます。

図18-11 「Health」ページから使用可能なナビゲーション・アイテム

navigationPaneを使用したナビゲーション・アイテム

使用するナビゲーション・アイテムのタイプ(タブやバーなど)に関係なく、各navigationPaneコンポーネント内の一連のcommandNavigationItem子コンポーネントにより、実際のナビゲーション・アイテムが提供されます。たとえば、図18-11では、Employee Dataタブへの実際のリンク、InsuranceとPaid Time Offバー、およびリストのHealthとDentalリンクは、それぞれcommandNavigationItemコンポーネントによって表されています。

18.7.1 単純なページ階層の作成方法

ナビゲーション階層に含まれるページ数が少なく、階層があまり深くない場合は、手動で作成することを選択できます。これには、ナビゲーション・メタデータの作成、navigationPaneコンポーネントを使用した階層の作成、およびcommandNavigationItemコンポーネントを使用したリンクの作成が含まれます。

手動でナビゲーション階層を作成する手順:

  1. ページ階層のすべてのノード(ページ)のナビゲーション・ケースが含まれるグローバルなJSFナビゲーション・ルールを1つ作成します。

    たとえば、図18-4に示されているページ階層には、グローバルのHelpノードを含む10のノードがあります。この場合、例18-16に示すように、faces-config.xmlファイルの1つのグローバル・ナビゲーション・ルール内に10のナビゲーション・ケースを作成します。

    各ナビゲーション・ケースに、一意の結果文字列と、指定された文字列に一致する結果値がナビゲーション・システムによって返された場合に表示するJSFページへのパスを指定します。

    例18-16 faces-config.xml内のページ階層のグローバル・ナビゲーション・ルール

    <navigation-rule>
      <navigation-case>
        <from-outcome>goHome</from-outcome>
        <to-view-id>/home.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goHelp</from-outcome>
        <to-view-id>/globalhelp.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goEmp</from-outcome>
        <to-view-id>/empdata.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goBene</from-outcome>
        <to-view-id>/benefits.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goIns</from-outcome>
        <to-view-id>/insurance.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goPto</from-outcome>
        <to-view-id>/pto.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goView</from-outcome>
        <to-view-id>/viewdata.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goCreate</from-outcome>
        <to-view-id>/createemp.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goHealth</from-outcome>
        <to-view-id>/health.jspx</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>goDental</from-outcome>
        <to-view-id>/dental.jspx</to-view-id>
      </navigation-case>
    </navigation-rule>
    

    JDeveloperにおけるナビゲーション・ケースの作成方法の詳細は、2.3項「ページ・フローの定義」を参照してください。

  2. メニュー・タブのスタイルを設定する場合は、コンポーネント・パレットのレイアウト・セクションから装飾ボックスをJSFページにドラッグ・アンド・ドロップして、decorativeBoxコンポーネントを作成します。テーマを設定して、タブの表示方法を決定します。有効な値は次のとおりです。

    • default: 本体は白で、枠は青です。左上隅は丸くなります。

    • light: 本体は薄い青です。左上隅は丸くなります。

    • medium: 本体は中間色の青です。左上隅は丸くなります。

    • dark: 本体は濃い青です。左上隅は丸くなります。

    テーマの表示方法は変更できます。詳細は、第20章「スタイルおよびスキンを使用した外観のカスタマイズ」を参照してください。

  3. コンポーネント・パレットのレイアウト・セクションからナビゲーション・ペインdecorativeBoxコンポーネントの子としてドラッグ・アンド・ドロップして、navigationPaneコンポーネントを作成します。階層の各レベルにnavigationPaneコンポーネントを追加します。

    たとえば、図18-11のような「Health」ページを作成するには、navigationPaneコンポーネントを4つドラッグ・アンド・ドロップします。Healthページでは、すでにページのルック・アンド・フィールを作成するためのレイアウト・コンポーネントが含まれているテンプレートの特定の領域に、コンポーネントをドロップします。

  4. プロパティ・インスペクタで「共通」セクションを開き、各navigationPaneコンポーネントのhint属性を次に示すナビゲーション・アイテムのいずれかのタイプに設定して、navigationPaneコンポーネントをどのように表示するかを決定します。

    • bar: バーで分割されたナビゲーション・アイテムを表示します。図18-11InsuranceおよびPaid Time Offリンクなどがこれに当たります。

    • buttons: グローバル領域のバーで分割されたナビゲーション・アイテムを表示します。図18-11Homeおよび「ヘルプ」リンクなどがこれに当たります。

    • choice: 関連付けられたドロップダウン・アイコンがクリックされたときに、ポップアップ・リストにナビゲーション・アイテムを表示します。navigationPaneコンポーネントのicon属性に値を含める必要があり、title属性を使用してドロップダウン・リストにラベルを関連付けることができます。

    • list: ナビゲーション・アイテムを箇条書きリストで表示します。図18-11HealthおよびDentalリンクなどがこれに当たります。

    • tabs: ナビゲーション・アイテムをタブで表示します。図18-11BenefitsおよびEmployee Dataタブなどがこれに当たります。

  5. コンポーネント・パレットの「共通コンポーネント」セクションから「ナビゲーション・アイテム」をドラッグ・アンド・ドロップし、異なるリンクを表示するために必要なcommandNavigationItemコンポーネントを、各navigationPaneコンポーネントに追加します。必要な各リンクのnavigationPaneコンポーネントの子として、「ナビゲーション・アイテム」をドロップします。

    たとえば、図18-11のようなHealthページを作成するには、各navigationPaneコンポーネントに2つずつ、合計6つのcommandNavigationItemコンポーネントを使用します。


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

    実行時、使用可能なブラウザの領域が、ナビゲーション・ペインのタブやバーのコンテンツ、またはブレッドクラムのコンテンツの表示に必要な領域より少ない場合、表示されていない項目をユーザーが選択して表示できるオーバーフロー・アイコンがADF Facesにより自動的に表示されます。navigationPaneまたはbreadCrumbsコンポーネント内の子コンポーネントの数、および子の複雑さが、オーバーフローの項目のパフォーマンスに影響します。可能な場合は、オーバーフローしないように、navigationPaneまたはbreadCrumbsコンポーネントのサイズを設定する必要があります。


  6. commandNavigationItemコンポーネントで、ナビゲーションを必要なページに設定します。プロパティ・インスペクタで、「共通」セクションを開き、アクションの静的な結果文字列を指定するか、EL式を使用し、actionプロパティを介してアクション・メソッドを参照します。文字列を使用する場合は、手順1で作成したページのナビゲーション・ルールに設定されたナビゲーション・メタデータに一致する必要があります。メソッドを参照する場合は、必要な文字列がそのメソッドにより返される必要があります。

  7. プロパティ・インスペクタで、「動作」セクションを開き、selected属性を設定します。ページの最初のレンダリング時に、commandNavigationItemコンポーネントを選択済として表示する必要がある場合はこの属性をtrueにし、その必要がない場合はfalseにします。

    実行時に、ユーザーがナビゲーション・アイテムを選択すると、コンポーネントのselected属性が選択済に変更され、ユーザーに、アイテムが選択済であることを示すために、表示が変更されます。たとえば、図18-11では、「Benefits」タブ、「Insurance」バー、および「Health」リスト・アイテムが、背景色またはフォント・スタイルの変更によって選択済として表示されます。選択済のステータスを表示するためにコードを記述する必要はありません。属性値がtrueの場合は、アイテムのcommandNavigationItemコンポーネントのselected属性により、選択済のステータスの有効化が処理されます。

図18-17に、現在のページがHealthの場合に使用可能なナビゲーション・アイテムの生成に使用されるコードを示します。HealthページはBenefitsページを経由してInsuranceページからアクセスされているため、これらの3つのリンクのcommandNavigationItemコンポーネントではselected="true"です。

例18-17 1つのページに個々のナビゲーション・アイテムを使用したサンプル・コード

<af:navigationPane hint="buttons">
  <af:commandNavigationItem text="Home" action="goHome"/>
  <af:commandNavigationItem text="Help" action="goHelp"/>
</af:navigationPane>
.
.
.
<af:navigationPane hint="tabs">
  <af:commandNavigationItem text="Benefits" action="goBene"
                            selected="true"/>
  <af:commandNavigationItem text="Employee Data" action="goEmp"/>
</af:navigationPane>
.
.
.
<af:navigationPane hint="bar">
  <af:commandNavigationItem text="Insurance" action="goIns"
                            selected="true"/>
  <af:commandNavigationItem text="Paid Time Off" action="goPto"/>
</af:navigationPane>
.
.
.
<af:navigationPane hint="list">
  <af:commandNavigationItem text="Health" action="goHealth"
                            selected="true"/>
  <af:commandNavigationItem text="Dental" action="goDental"/>
</af:navigationPane>

18.7.2 breadCrumbsコンポーネントの使用方法

図18-10および図18-11の両方で、ページ階層におけるユーザーの現在の位置は、現在のページからルート・ページに戻るリンクのパスで示されています。ブレッドクラムとも呼ばれるリンクのパスは、2番目のバーの下、垂直のリスト(存在する場合)の上に表示されます。そのようなリンクのパスを作成するには、一連のcommandNavigationItemコンポーネントを子として含むbreadCrumbsコンポーネントを使用します。

ブレッドクラムを作成する手順:

  1. コンポーネント・パレットからJSFページにブレッド・クラム・コンポーネントをドラッグ・アンド・ドロップして、breadCrumbsコンポーネントを作成します。

  2. デフォルトでは、ブレッドクラム・リンクは水平に表示されます。レイアウトが垂直になるように変更するには、プロパティ・インスペクタで、「共通」セクションを開き、orientation属性をverticalに設定します。

  3. ブレッドクラムの各リンクに、コンポーネント・パレットからbreadCrumbsコンポーネントの子として「ナビゲーション・アイテム」をドラッグ・アンド・ドロップし、commandNavigationItemコンポーネントを作成します。最後の項目が現在のページを表します。


    ヒント:

    レンダラまたはクライアントのデバイス・タイプによっては、ブレッドクラムの最後のリンクが表示されない場合がありますが、commandNavigationItemコンポーネントを追加する必要があります。最後のブレッドクラム・リンクを表示するクライアントでは、現在のページに対応しているため、リンクは常に自動的に無効にされます。


  4. commandNavigationItemコンポーネント(最後を除く)で、ナビゲーションを必要なページに設定します。プロパティ・インスペクタで、「共通」セクションを開き、アクションの静的な結果文字列を指定するか、EL式を使用し、actionプロパティを介してアクション・メソッドを参照します。文字列を使用する場合は、手順1で作成したページのナビゲーション・ルールに設定されたナビゲーション・メタデータに一致する必要があります。メソッドを参照する場合は、必要な文字列がそのメソッドにより返される必要があります。

たとえば、図18-11のHealthページのようにブレッドクラムを作成するには、例18-18に示すように、4つのnavigationPaneコンポーネントをドラッグ・アンド・ドロップします。

例18-18 個々の子commandNavigationItemのあるbreadCrumbsコンポーネント

<af:breadCrumbs>
  <af:commandNavigationItem text="Home" action="goHome"/>
  <af:commandNavigationItem text="Benefits" action="goBene"/>
  <af:commandNavigationItem text="Insurance" action="goIns"/>
  <af:commandNavigationItem text="Health"/>
</af:breadCrumbs>

注意:

同様に、個々のcommandNavigationItemコンポーネントを使用するかわりに、breadCrumbsコンポーネントのvalue属性をXMLMenuModel実装にバインドし、breadCrumbsコンポーネントのnodeStampファセットにcommandNavigationItemコンポーネントの1つ使用して、ページの項目にスタンプを設定することもできます。XMLMenuModelクラスの詳細は、18.6項「メニュー・モデルを使用したページ階層の作成」を参照してください。


18.7.3 ナビゲーション・タブの削除に関する必知事項

hint属性の値がtabsnavigationPaneコンポーネントは、個々のタブを閉じられるように構成できます。これは、すべてのタブを閉じる、最後のタブを除いてすべて閉じる、またはタブを閉じないように構成できます。ナビゲーション・タブを削除するように構成した場合、マウス・カーソルがタブの上に置かれると、各タブの端に閉じるアイコン(Xなど)が表示されます。

hint="tabs"の場合にnavigationPaneコンポーネントでのタブの削除を有効化するには、次のようにします。

  • navigationPane hint="tabs"itemRemoval属性をallまたはallExceptLastに設定します。allExceptLastに設定されている場合は、1つを除くすべてのタブが閉じられます。これは、ユーザーがタブを閉じ、タブが1つのみ残ると、その最後の1つのタブは閉じられないことを意味します。

  • タブの削除を実行するにはハンドラを実装します。ユーザーがタブを閉じると、タイプがremoveItemEventが起動されます。このイベントと実際のタブの削除、およびその他の必要な機能(警告ダイアログの表示や子コンポーネントの処理方法など)には、コードで対応する必要があります。イベントの詳細は、第5章「イベントの処理」を参照してください。ポップアップ・ダイアログおよびウィンドウの使用方法の詳細は、第13章「ポップアップ・ダイアログ、メニューおよびウィンドウの使用方法」を参照してください。

  • 例18-19に示すように、commandNavigationItemコンポーネントのitemListener属性を、実際のタブの削除を処理するハンドラ・メソッドに解決されるEL式に設定します。

例18-19 タブ・アイテムを削除するためのitemListenerの使用

JSF Page Code ----->
<af:navigationPane hint="tabs" itemRemoval="all">
  <af:commandNavigationItem text="Benefits" partialSubmit="true"
                            itemListener="#{closebean.handleCloseTabItem}"/>
  .
  .
  .
</af:navigationPane>

Managed Bean Code ----->
import oracle.adf.view.rich.event.ItemEvent;
...
public void handleCloseTabItem(ItemEvent itemEvent)
{
  if (itemEvent.getType().equals(ItemEvent.Type.remove))
  {
    Object item = itemEvent.getSource();
    if (item instanceof RichCommandNavigationItem)
    {
      RichCommandNavigationItem tabItem = (RichCommandNavigationItem) item;
      tabItem.setVisible(false);
      // do other desired functionality here ...
    }
  }
}

18.7.4 圧縮レイアウトのナビゲーション・タブに関する必知事項

navigationPaneコンポーネントによってレンダリングされたナビゲーション・タブが圧縮レイアウトのアプリケーション・ウィンドウに表示される場合は、組込みのオーバーフロー・インジケータが表示されます。これは、アプリケーション・ウィンドウにすべてのナビゲーション・タブを表示するだけの十分な幅がないということです。図18-12に示すように、ユーザーは、このようなオーバーフロー・インジケータによってレンダリングされたドロップダウン・リストで、移動先のナビゲーション・アイテムを選択できます。

図18-12 圧縮レイアウトのnavigationPaneコンポーネントのオーバーフロー・インジケータ

navigationPaneコンポーネントのオーバーフロー・インジケータ

オーバーフロー・インジケータを表示(デフォルトの動作)するかわりに、図18-12に示すように、navigationPaneコンポーネントの-tr-layout-typeスキニング・キーを構成して、ユーザーが左右にスクロールして現在非表示になっているタブを表示できるコンベア・ベルトをコンポーネントでレンダリングするようにできます。また、-tr-layout-typeスキニング・キーを構成すると、図18-13に示すように、すべてのナビゲーション・タブが1つのドロップダウン・リストにレンダリングされます。この構成は、navigationPaneコンポーネントのhint属性がtabsに設定されている場合にのみ有効です。navigationPaneコンポーネントのhint属性が別の値に設定されている場合は、-tr-layout-typeスキニング・キーをデフォルト値(overflow)に設定してください。

例18-20に、アプリケーションのADFスキン・ファイルの-tr-layout-typeスキニング・キーを構成して、navigationPaneおよびpanelTabbedコンポーネントにコンベア・ベルトをレンダリングする方法を示します。スキニングの詳細は、第20章「スタイルおよびスキンを使用した外観のカスタマイズ」を参照してください。

例18-20 -tr-layout-typeスキニング・キーの構成によるコンベア・ベルトのレンダリング

af|panelTabbed,
af|navigationPane {
  -tr-layout-type: conveyor;
}  

図18-13に、圧縮レイアウトでコンベア・ベルトをレンダリングするnavigationPaneコンポーネントを示します。

図18-13 圧縮レイアウトのnavigationPaneコンポーネントのコンベア・ベルト

navigationPaneコンポーネントのコンベア・ベルト

18.8 trainコンポーネントを使用したマルチステップ・プロセス用のナビゲーション・アイテムの作成


注意:

アプリケーションにFusionテクノロジ・スタックまたはADFコントローラが使用されている場合は、ADFタスク・フローを使用して、アプリケーションのページ階層にナビゲーション・システムを作成します。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の「トレインの作成」を参照してください。


ユーザーが特定の順序で表示する必要のある一連のページがある場合は、各ページにtrainコンポーネントを使用して、マルチステップ・プロセスをガイドする一連のナビゲーション・アイテムを表示することを検討してください。図18-14に、レンダリングされたtrainコンポーネントがページでどのように表示されるかの例を示します。trainはマルチステップ・プロセスのステップ数を表示するだけでなく、プロセス全体との関連における現在のステップの位置も示します。

図18-14 trainコンポーネントによりレンダリングされたナビゲーション・アイテム

trainコンポーネントによりレンダリングされたナビゲーション・アイテム

trainコンポーネントは、トレイン・ストップとして表される構成済の各手順を、すべてのストップが線でつながった状態でレンダリングします。各トレイン・ストップにはイメージ(四角いブロックなど)があり、そのイメージの下にラベルがあります。

各トレイン・ストップは、マルチステップ・プロセスの1つの手順または1ページに対応します。ユーザーは、イメージやラベルをクリックして、トレイン・ストップをナビゲートします。これによって、新しいページが表示されます。通常、トレイン・ストップは順番に表示する必要があり、ユーザーは手順1から開始し、手順2、手順3というように移動する必要があります。ユーザーが手順2を表示していない場合は、手順3を表示することはできません。

図18-14に示すように、trainコンポーネントには、トレイン・ストップ用に少なくとも4つのスタイルが用意されています。ユーザーが表示している現在のストップは、トレイン・ストップのラベルが太字フォント・スタイルで示され、ストップには異なるイメージが使用されます。現在のストップより前の表示済のストップは、ラベルのフォントとイメージが異なる色で示されます。現在のストップの直後のストップは、有効化されて表示されます。表示されていないその他のストップは、グレー表示されます。

トレイン・ストップにはサブトレインを含めることができ、親ストップから子のマルチステップ・プロセスを開始し、サブプロセスの完了後に適切な親ストップに戻るよう、コマンド・コンポーネント(commandButtonコンポーネントなど)を構成できます。4番目のストップに3つのストップを含むサブプロセス・トレインがあるとします。ユーザーがサブプロセス・トレインの最初のストップに移動すると、図18-15に示すように、ADF Facesにより、サブプロセス・トレインの前後に親トレインを表すアイコンが表示されます。

図18-15 サブトレインの最初と最後の親トレインのアイコン

サブトレインのマルチステップ・プロセス

trainコンポーネントにtrainButtonBarコンポーネントを使用して、図18-16に示すように、「Back」および「Next」ボタンという形で、trainに追加のナビゲーション・アイテムを指定できます。これらの「Back」および「Next」ボタンを使用した場合、ユーザーは現在のストップから前後のトレイン・ストップにのみナビゲートできます。trainButtonBarコンポーネントは、trainコンポーネントなしでも使用できます。たとえば、表示されないストップがある場合、いくつかの条件付きロジックに基づいて、ストップを表示せずに「Back」および「Next」ボタンのみを表示することが必要な場合があります。

図18-16 trainButtonBarコンポーネントによりレンダリングされたナビゲーション・ボタン

trainButtonBarによりレンダリングされた「Back」および「Next」ボタン

どちらのtrainコンポーネントも、value属性をタイプorg.apache.myfaces.trinidad.model.MenuModelのトレイン・モデルにバインドすることで機能します。トレイン・メニュー・モデルには、次の処理に必要な情報が含まれています。


注意:

ADFモデル・レイヤーおよびADFコントローラを使用しているアプリケーションでは、このナビゲーションおよび表示は異なる方法で設定および処理されています。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の「トレインの作成」を参照してください。


つまり、トレインのメニュー・モデルは、続いてTreeModelクラスを拡張するMenuModel抽象クラスを拡張することで実装されます(詳細は、第10章「表、ツリー、およびその他のコレクションベースのコンポーネントの使用」を参照)。MenuModelオブジェクトは、ページやアプリケーションのメニュー構造を表すことも、ページの階層やフローに含まれるストップを表すこともあります。

MenuModelクラスのインスタンスは特殊なTreeModelオブジェクトであるため、TreeModelオブジェクト内のノードはトレイン・ストップを表すことができます。trainコンポーネント内のトレイン・ストップを表すノード・インスタンスは、タイプTrainStopModelにすることも、任意のオブジェクト(TrainStopModelオブジェクトと同じEL構造を提供する場合)にすることもできます。ただし、TrainStopModelクラスでは、ストップのラベルやimmediatedisabledおよびvisited属性の状態だけでなく、結果を取得するメソッドも公開されます。

MenuModelクラスは、ツリーのどの部分で現在のトレイン・ストップ(ページ)がフォーカスされているかを示すこともできます。MenuModelクラスのgetFocusRowKey()メソッドは、現在のviewIdのフォーカス・ページのrowKeyオブジェクトを返します。トレインのメニュー・モデル実装には、org.apache.myfaces.trinidad.model.ProcessMenuModelクラスを拡張することで作成できる固有のトレイン動作も必要です。トレイン動作は、現在のトレイン・ストップを表示している間に、ユーザーがトレインのどのストップを表示できるかを制御します。

トレイン・ストップ・モデルを作成するには、TrainStopModel抽象クラスを拡張して抽象メソッドを実装することも、同じメソッド・シグネチャを使用して独自のクラスを作成することもできます。作成するクラスではrowDataオブジェクトを返す必要があります。

トレイン・メニュー・モデルへのtrainコンポーネントのバインドは、XMLMenuModelクラスへのnavigationPaneコンポーネントのバインドに似ています(詳細は、18.6.3項「JSFページでのXMLMenuModelへのバインド方法」で説明されています)。ただし、TrainStopModelの実装でrowDataオブジェクトが戻される場合は、各ストップにcommandNavigationItemコンポーネントを提供する必要はありません。ADF Facesにより、実行時にnodeStampファセットおよびcommandNavigationItemコンポーネントが動的に作成され、トレイン・ストップ・モデルのメソッドがcommandNavigationItemコンポーネントの適切なプロパティに自動的にバインドされます。例18-21に、トレインの簡略化されたバインディングを示します。


ヒント:

様々な場所のトレイン・ストップの情報を照合する必要がある場合は、nodeStampファセットおよびそれらのトレイン・ストップを表す個々のcommandNavigationItemコンポーネントを手動で作成する必要があります。詳細は、18.8.3項「JSFページでのトレイン・モデルへのバインド方法」を参照してください。


例18-21 簡略化されたトレイン・モデル・バインディング

<af:train value="#{simpleTrainModel}"/>

トレイン・モデルのMenuModel実装には、特定のトレイン動作が必要です。トレイン動作は、現在表示されているページに基づいてユーザーがアクセスできるページをどのように制御するかを定義します。ADF Facesでは、Plus OneおよびMax Visitedという2つのトレイン動作がサポートされています。

トレインに5つのページまたは5つのストップがあり、ユーザーはページ1からページ4まで順番にナビゲート済であるとします。ページ4でユーザーはページ2に戻ります。ここでは、トレイン・モデルで使用されているトレイン動作に応じて、ユーザーは次に進むことができます。

Max Visitedでは、ユーザーは現在のページ2からページ1に戻ることも、ページ3に進むことも、ページ4に移動することもできます。つまり、Max Visitedを使用すると、ユーザーは前のページに戻ることも、すでに表示した最も先のページまで進むこともできます。ページ5はまだ表示されていないため、ユーザーはページ2からページ5に移動することはできません。

同じ状況で、Plus One動作の場合には、ユーザーはページ3に進むかページ1に戻ることしかできません。つまり、Plus Oneを使用すると、ユーザーは前のページに戻るか、現在のストップの1つ先のストップに進むことができます。ページ4がすでに表示されている場合でも、ユーザーはページ4に移動することはできません。

マルチステップ・プロセスのすべてのページにトレインを定義および使用する手順:

18.8.1 トレイン・モデルの作成方法

トレイン・メニュー・モデルを定義するには、次のものを作成します。

  • トレイン・ストップをレンダリングするためのデータを提供するトレイン・ストップ・モデル

  • 特に、現在のトレイン・ストップを表示している間にユーザーがトレインのどのストップを表示できるか、どのストップを無効にする必要があるか、またはトレインを順番にナビゲートする必要があるかを制御する特定のトレイン動作(Max VisitedまたはPlus One)が指定されたMenuModel実装

ADF Facesを使用すると、次のような追加のpublicクラスが用意されているため、トレイン・メニュー・モデルの定義がより簡単になります。

  • トレイン・ストップ・モデルを実装するための抽象クラスTrainStopModel

  • トレイン・モデルのトレイン動作を実装するためのクラスProcessMenuModelおよびProcessUtils

トレイン・モデル・クラスの例として、ADF Facesデモ・アプリケーションのoracle.adfdemo.view.nav.richパッケージを参照してください。

トレイン・モデルを作成する手順:

  1. トレイン・ストップ・モデル・クラスを作成します。トレイン・ストップ・モデル・オブジェクトには、各トレイン・ストップにスタンプを設定するための行データが保持されます。作成するトレイン・ストップ・モデル実装では、トレインの各ストップのプロパティを設定および取得し、トレイン・ストップのレンダリングに必要なメソッドを定義する必要があります。トレイン・ストップのプロパティは、commandNavigationItemコンポーネントのプロパティに対応します。このため、例18-21に示すように、簡略化されたバインディングを使用できます。

    または、抽象クラスTrainStopModelを拡張して、サブクラスの抽象メソッドを実装できます。

    ELにより自動的にバインドされるcommandNavigationItemコンポーネントのプロパティを次に示します。

    • action: 静的なアクション結果、またはアクション結果を返すアクション・メソッドへの参照。結果は、JSFのデフォルトのActionListenerメカニズムを介して、ページ・ナビゲーションに使用されます。

    • disabled: トレイン・ストップが非対話型である必要があるかどうかを示すブール値。使用するトレイン動作が、このプロパティ値に影響することに注意してください。詳細は、手順2を参照してください。

    • immediate: データ検証を実行する必要があるかどうかを決定するブール値。使用するトレイン動作が、このプロパティ値に影響することに注意してください。詳細は、手順2を参照してください。

    • messageType: トレイン・ストップ・イメージ上のメッセージ・アラート・アイコンを指定する値。使用可能な値は、noneerrorwarninginfoおよびcompleteです。メッセージの詳細は、第17章「ヒント、メッセージおよびヘルプの表示」を参照してください。

    • shortDesc: クライアント・ユーザー・エージェントにより、トレイン・ストップのツールチップ・ヘルプ・テキストの表示に一般的に使用される値。

    • showRequired: 必要な値がそのトレイン・ストップ・ページに含まれていることを示すために、トレイン・ストップの隣にアスタリスクを表示するかどうかを決定するブール値。

    • textAndAccessKey: トレイン・ストップに表示するラベル・テキストと、使用するアクセス・キーの両方を設定する単一の値。

    • visited: トレイン・ストップがすでに表示済であるかどうかを示すブール値。使用するトレイン動作が、このプロパティ値に影響することに注意してください。詳細は、手順2を参照してください。

  2. MenuModelクラスに基づいてクラスを作成し、トレイン・モデルの構成を簡略化します。

    トレイン・モデルのMenuModel実装には、特定のトレイン動作が必要です。org.apache.myfaces.trinidad.modelパッケージのProcessMenuModelクラスは、Plus OneおよびMax Visitedという2つのトレイン動作をサポートするMenuModelクラスの参照実装です。トレイン・モデルにトレイン動作を実装するには、ProcessMenuModelクラスを拡張するか独自のクラスを作成できます。

    トレイン・モデル・クラスで、getFocusRowKey()メソッド(MenuModelクラスを参照)をオーバーライドし、トレイン動作(ProcessMenuModelクラスおよびProcessUtilsクラスを参照)を実装します。

    ProcessMenuModelクラスに指定されているトレイン動作は、commandNavigationItemコンポーネントのvisitedimmediate、およびdisabledプロパティに影響があります。

    visited属性をtrueに設定するのは、トレインのそのページが表示済の場合のみです。ProcessMenuModelクラスでは、visited属性の値の決定に次のロジックが使用されます。

    • Max Visited: Max Visitedストップは、現在のセッションでユーザーが表示した最も進んだストップです。Max Visitedストップより前である場合、またはMax Visitedストップ自体である場合は、どのストップでもvisitedtrueに設定されます。

    • Plus One: Plus Oneストップでは、表示された最も進んでいるストップは追跡されません。現在のストップ、または現在のストップの前のストップでは、visited属性がtrueに設定されます。

    現在のページのデータを検証する必要がない場合は、immediate属性をtrueに設定する必要があります。前述のPlus One動作のページ4に、検証が必要なデータがあるとします。ページ4に進んでページ2に戻った場合、ページ5に進むためにユーザーは後からページ4に戻る必要があります。これは、ページ4からページ1、2または3に戻る場合はページ4のデータを検証する必要はないが、ページ5に進む場合にはデータを検証する必要があることを意味します。immediate属性がどのように機能するかの詳細は、4.2項「immediate属性の使用」を参照してください。

    ProcessMenuModelクラスでは、immediate属性の値の決定に次のロジックが使用されます。

    • Plus One: immediate属性は、前のステップに対してはtrueに設定され、それ以外に対してはfalseに設定されます。

    • Max Visited: 現在のページと、表示した最大ページが同じである場合、動作はPlus Oneシナリオと同じです。現在のページが表示された最大ページよりも前にある場合、immediate属性はfalseに設定されます。


      注意:

      ADFモデル・レイヤーを使用するアプリケーションでは、ページ定義ファイルのpageDefinition要素で、trueに設定されている場合に、ページのデータ検証をスキップする属性(SkipValidation)がサポートされています。データ検証を起動せずに、ユーザーがページからナビゲートできるようにするには、SkipValidationtrueに設定します。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』pageNamePageDef.xmlに関する項を参照してください。


    disabled属性をtrueに設定するのは、現在のページからそのページに移動できない場合のみです。ProcessMenuModelクラスでは、disabled属性の値の決定に次のロジックが使用されます。

    • Plus One: 次に使用可能なページより先のページでは、disabled属性がtrueになります。

    • Max Visited: 現在のストップと、表示した最大ページが同じである場合、動作はPlus One動作と同じです。現在のページが表示された最大ページよりも前にある場合、表示された最大ページより先のページではdisabledtrueに設定されます。

ADF Facesでは、トレイン・モデルにnull以外のmaxPathKey値が渡されると、動作をサポートするために作成するマネージドBeanで決定されているとおりに、デフォルトで、Max Visited動作が使用されます(詳細は、18.8.2項「トレイン・モデルへのマネージドBeanの構成方法」を参照してください)。maxPathKey値がnullの場合には、Plus One動作が使用されます。

18.8.2 トレイン・モデルへのマネージドBeanの構成方法

トレイン・モデルのマネージドBeanを使用して、個々のトレイン・ストップをArraylistオブジェクトにまとめます。これは、トレイン・モデルを作成するためにメニュー・モデルに組み込まれるツリー・モデルになります。モデルへの挿入に適切な値でBeanをインスタンス化し、トレイン内の各トレイン・ストップまたはページにマネージドBeanも構成する必要があります。

トレイン・モデルにマネージドBeanを構成する手順:

  1. インストール時に設定する必要のあるプロパティ値が含まれるマネージドBeanをトレインの各ストップに構成し、ArrayListに渡すトレイン・ストップを作成します。

    トレイン・ストップに子のサブプロセス・トレインがある場合は、各サブプロセス・トレイン・ストップにもマネージドBeanが必要です。

    各Beanは、18.8.1項「トレイン・モデルの作成方法」で作成したトレイン・ストップ・モデル・クラスのインスタンスである必要があります。例18-22に、faces-config.xmlファイルのトレイン・ストップのサンプルのマネージドBeanコードを示します。

    例18-22 すべてのトレイン・ストップのマネージドBean

    <!-- First train stop -->
    <managed-bean>
      <managed-bean-name>train1</managed-bean-name>
      <managed-bean-class>project1.DemoTrainStopModel</managed-bean-class>
      <managed-bean-scope>none</managed-bean-scope>
      <managed-property>
        <property-name>viewId</property-name>
        <value>/train.jspx</value>
      </managed-property>
      <managed-property>
        <property-name>outcome</property-name>
        <value>guide.train</value>
      </managed-property>
      <managed-property>
        <property-name>label</property-name>
        <value>First Step</value>
      </managed-property>
      <managed-property>
        <property-name>model</property-name>
        <value>trainMenuModel</value>
      </managed-property>
    </managed-bean>
    
    <!-- Second train stop -->
    <managed-bean>
      <managed-bean-name>train2</managed-bean-name>
      <managed-bean-class>project1.DemoTrainStopModel</managed-bean-class>
      <managed-bean-scope>none</managed-bean-scope>
      <managed-property>
        <property-name>viewId</property-name>
        <value>/train2.jspx</value>
      </managed-property>
      <managed-property>
        <property-name>outcome</property-name>
        <value>guide.train2</value>
      </managed-property>
      <managed-property>
        <property-name>label</property-name>
        <value>Second Step</value>
      </managed-property>
      <managed-property>
        <property-name>model</property-name>
        <value>trainMenuModel</value>
      </managed-property>
    </managed-bean>
    
    <!-- And so on -->
    .
    .
    .
    

    マネージド・プロパティにより、トレイン・ストップ・モデル・オブジェクト(18.8.1項「トレイン・モデルの作成方法」の手順1で作成されたクラス)に値が設定されます。

    viewId値は、ユーザーがトレイン・ストップをクリックした場合にナビゲートされるページへのパスおよびファイル名です。

    outcomeプロパティ値は、JSFナビゲーション・ケースに一致するアクション結果文字列です。デフォルトのJSF ActionListenerメカニズムは、トレイン・ストップが選択された際のナビゲート先のビューとしてトレイン・ストップに関連付けられたページの選択に使用されます。

    labelプロパティ値は、トレイン・ストップ・イメージの下に表示されるトレイン・ストップのラベル・テキストです。値は静的にすることも、リソース・バンドルの文字列に評価されるEL式にすることもできます。

    modelプロパティ値は、トレイン・モデルのマネージドBean名です(例18-26を参照)。

    トレイン・ストップに子のサブプロセス・トレインがある場合には、例18-23に示すように、マネージドBean構成にも、値式(#{train4a}など)でサブプロセス・トレイン・ストップのマネージドBean名をリストするプロパティ(childrenなど)を指定する必要があります。

    例18-23 子のサブプロセス・トレインを含むトレイン・ストップのマネージドBean

    <managed-bean>
      <managed-bean-name>train4</managed-bean-name>
      <managed-bean-class>project1.DemoTrainStopModel</managed-bean-class>
      <managed-bean-scope>none</managed-bean-scope>
      <managed-property>
        <property-name>viewId</property-name>
        <value>/train4.jspx</value>
      </managed-property>
      <managed-property>
        <property-name>outcome</property-name>
        <value>guide.train4</value>
      </managed-property>
      <managed-property>
        <property-name>label</property-name>
        <value>Fourth Step</value>
      </managed-property>
      <managed-property>
        <property-name>children</property-name>
        <list-entries>
          <value-class>project1.DemoTrainStopModel</value-class>
          <value>#{train4a}</value>
          <value>#{train4b}</value>
          <value>#{train4c}</value>
        </list-entries>
      </managed-property>
      <managed-property>
        <property-name>model</property-name>
        <value>trainMenuModel</value>
      </managed-property>
    </managed-bean>
    
  2. ArrayListオブジェクトのインスタンスであるマネージドBeanを構成し、トレイン・ツリー・モデルに渡すトレイン・ストップのリストを作成します。

    例18-24に、トレイン・ストップのリストを作成するためのサンプルのマネージドBeanコードを示します。

    例18-24 トレイン・リストのマネージドBean

    <managed-bean>
      <managed-bean-name>trainList</managed-bean-name>
      <managed-bean-class>
        java.util.ArrayList
      </managed-bean-class>
      <managed-bean-scope>
        none
      </managed-bean-scope>
      <list-entries>
        <value-class>project1.DemoTrainStopModel</value-class>
        <value>#{train1}</value>
        <value>#{train2}</value>
        <value>#{train3}</value>
        <value>#{train4}</value>
        <value>#{train5}</value>
      </list-entries>
    </managed-bean>
    

    list-entries要素には、トレインにストップが表示される順序でリストされた値式(#{train1}など)のトレイン・ストップ(サブプロセス・トレイン・ストップを除く)のマネージドBean名が含まれます。

  3. マネージドBeanを構成して、トレイン・リストからトレイン・ツリー・モデルを作成します。

    トレイン・ツリー・モデルは、サブプロセス・トレインのリストも含む、トレイン・リスト全体をラップします。トレイン・モデルのマネージドBeanは、子のサブプロセス・トレインのリストを表すプロパティ名と同一であるchildProperty値を使用して、インスタンス化する必要があります(例18-23を参照)。

    例18-25 トレイン・ツリー・モデルのマネージドBean

    <managed-bean>
      <managed-bean-name>trainTree</managed-bean-name>
        <managed-bean-class>
         org.apache.myfaces.trinidad.model.ChildPropertyTreeModel
        </managed-bean-class>
      <managed-bean-scope>none</managed-bean-scope>
      <managed-property>
        <property-name>childProperty</property-name>
        <value>children</value>
      </managed-property>
      <managed-property>
        <property-name>wrappedData</property-name>
        <value>#{trainList}</value>
      </managed-property>
    </managed-bean>
    

    childPropertyプロパティには、サブプロセス・トレインのある各トレイン・ストップの子のリスト・エントリの取得に使用するプロパティ名を定義します。

    wrappedDataプロパティ値は、ステップ2でマネージドBeanにより作成された、ラップするトレイン・リスト・インスタンスです。

  4. マネージドBeanを構成して、トレイン・ツリー・モデルからトレイン・モデルを作成します。

    これが、各ページのtrainコンポーネントがバインドされるBeanです。トレイン・モデルは、トレイン・ツリー・モデルをラップします。トレイン・モデルのマネージドBeanは、トレイン・ストップに関連付けられたページを表すプロパティ名と同一であるviewIdProperty値を使用して、インスタンス化する必要があります。

    例18-26に、トレイン・モデルのサンプルのマネージドBeanコードを示します。

    例18-26 トレイン・モデルのマネージドBean

    <managed-bean>
      <managed-bean-name>trainMenuModel</managed-bean-name>
        <managed-bean-class>
         org.apache.myfaces.trinidad.model.ProcessMenuModel
        </managed-bean-class>
      <managed-bean-scope>session</managed-bean-scope>
      <managed-property>
        <property-name>viewIdProperty</property-name>
        <value>viewId</value>
      </managed-property>
      <managed-property>
        <property-name>wrappedData</property-name>
        <value>#{trainTree}</value>
      </managed-property>
      <!-- to enable plusOne behavior instead, comment out the maxPathKey property -->
      <managed-property>
        <property-name>maxPathKey</property-name>
        <value>TRAIN_DEMO_MAX_PATH_KEY</value>
      </managed-property>
    </managed-bean>
    

    viewIdPropertyプロパティ値は、ユーザーがトレイン・ストップをクリックした場合にナビゲートされるページの指定に使用されるプロパティに設定されます。

    wrappedDataプロパティ値は、ステップ3でマネージドBeanにより作成された、ラップするトレイン・ツリー・インスタンスです。

    maxPathKeyプロパティ値は、Max Visitedトレイン動作を使用するためにトレイン・モデルに渡される値です。ADF Facesでは、トレイン・モデルにnull以外のmaxPathKey値が渡されるとMax Visited動作が使用されます。maxPathKey値がnullの場合には、Plus One動作が使用されます。

18.8.3 JSFページでのトレイン・モデルへのバインド方法

トレインの各ストップは、1つのJSFページに対応します。各ページに、trainコンポーネント、およびオプションでtrainButtonBarコンポーネントを1つずつ使用し、ユーザーがトレインを移動できるようにするボタンを作成します。

トレイン・コンポーネントをトレイン・モデルにバインドする手順:

  1. コンポーネント・パレットからJSFページに「トレイン」をドラッグ・アンド・ドロップして、trainコンポーネントを作成します。オプションで、「トレイン・ボタン・バー」をドラッグ・アンド・ドロップします。

  2. コンポーネントをバインドします。トレイン・モデルのMenuModel実装により、public抽象クラスoracle.adf.view.rich.model.TrainStopModelに似たrowDataオブジェクトが返される場合は、次のコードに示すように、trainコンポーネントにトレイン・バインディングの簡略化されたフォームを使用できます。

    <af:train value="#{trainMenuModel}"/>
      <af:trainButtonBar value="#{trainMenuModel}"/>
    

EL式のtrainMenuModelは、トレイン・モデルのマネージドBean名です(例18-26を参照)。

簡略化されたバインディングを使用できない場合は、トレイン値をトレイン・モデルBeanにバインドし、トレインにnodeStampファセットを手動で追加する必要があります。さらに、例18-27に示すように、そのトレインにcommandNavigationItemコンポーネントを追加します。

例18-27 trainコンポーネントをトレイン・モデルのBeanにバインドするメタデータ

<af:train value="#{aTrainMenuModel}" var="stop">
  <f:facet name="nodeStamp">
    <af:commandNavigationItem
      text="#{stop.label}"
      action="#{stop.outcome}"
      ...
    </af:commandNavigationItem>
  </f:facet>
</af:train>