別のブラウザで表示すると、JavaScriptによってこのドキュメントの表示形式が変わる場合があります。ただしドキュメントの内容に影響はありません。

UIX開発者ガイド Go to Table of Contents
目次
Go to previous page
前へ
Go to next page
次へ

11. データ・ツリー

TreeBeanBrowseMenuBeanおよびHGridBeanを使用すると、ユーザーは複雑な階層データを参照できます。このトピックではこれらの3つのBeanを説明し、このBeanの使用方法に関する例を示します。

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

ツリー構造のデータ

データには、ツリー構造の性質を持つものがあります。たとえば、ショッピング・アプリケーションのカテゴリ、サブカテゴリおよび項目などが該当します。小さなデータ・ツリーの例から説明します。最上位ノードは「店」で、その下に独自のサブノードを含む「本」および「ハードウェア」というノードがあります。

図15-1: 階層ツリー

Diagram of hierarchical "Shop" tree

データ・ツリーはUIXではどのようになるのでしょうか。uiXMLでのツリーの作成方法を見てみましょう。ツリーの各ノードは、キーと値のペアを含むDataObjectです。多くの場合、テキスト・キーに関連付けられている値を使用してノードを参照します。このため、次のツリーではルートとして「店」ノードを参照します。uiXMLには、DataObjectListとなる値を作成するための特殊構文があります。次の例では、nodesというキーでノードに問い合せると、子を含むDataObjectListが返されます。たとえば、「店」ノードをnodesキーで問い合せると、ノード「本」および「ハードウェア」を含むDataObjectListが返されます。

ツリーの各DataObjectには、キーと値のペアのセットが含まれる場合があります。特別な意味を持つ特定のキーについては後述します。ここでは、上の例をuiXMLで記述し、そこに、いくつかのキーと値のペアを追加しています。

       <nodes text="店"
               destination="http://www.oracle.com"
               destinationText="詳細情報"
               expandable="expanded">
         <nodes text="本"
                 destination="http://www.oracle.com"
                 destinationText="詳細情報"
                 description="詳細情報:お買得、お買得、お買得!"
                 expandable="expanded">
           <nodes text="セール"
                   destination="http://www.oracle.com"
                   expandable="expanded">
             <nodes text="文庫"
                     destination="http://www.oracle.com"/>
           </nodes>
           <nodes text="フィクション"
                   destination="http://www.oracle.com"/>
           <nodes text="ノンフィクション"
                   destination="http://www.oracle.com"/>
         </nodes>
         <nodes text="ハードウェア"
                 expandable="expanded" >
           <nodes text="デスクトップ"
                   destination="http://www.oracle.com"/>
           <nodes text="ノートブック"
                   destination="http://www.oracle.com"/>
         </nodes>
       </nodes>

TreeBeanおよびBrowseMenuBeanは、このようなツリー構造のデータを表示するためのUIX Componentsです。この2つのBeanを使用すると、同じデータソースを2つの異なるビューで表示できます。例を使用して、これらのBeanが同じデータをどのように表示するかを示します。まず、このデータをTreeBeanで表示したイメージを示します。

図15-2: ブラウザにレンダリングされた階層ツリー

The "Shop" tree rendered as a graphical tree control in a browser

次に、ユーザーが「本」ノードを参照したときに、BrowseMenuBeanで表示される同じデータのイメージを示します。

図15-3: ブラウザに句としてレンダリングされた階層ツリー

The "Shop" tree rendered as a hierarchy of phrases in a browser

どちらのBeanを使用しても、ユーザーはツリー階層を移動できます。TreeBeanでは、データの階層は非常に明確に表示されます。BrowseMenuBeanでは階層全体は表示されませんが、ユーザーは最上部のナビゲータでルートから現在のノードまでのパスを知ることができます。「カテゴリ」ヘッダーおよび「項目」ヘッダーの下に、リンクとして現在のノードの子も確認することができます。「カテゴリ」ヘッダーの下のリンクにはリーフ・ノードではないものが、「項目」ヘッダーの下のリンクにはリーフ・ノードが表示されます。したがって、「本」ノードを参照すると、ルートからのパスが「店 > 本」であることがわかります。また、「本」には「セール」、「フィクション」および「ノンフィクション」という子があり、ノード「フィクション」および「ノンフィクション」はリーフで、「セール」ノードはリーフではないこともわかります。最上部のナビゲータ内のリンクでも、ヘッダー「カテゴリ」の下のリンクでも、ユーザーは同じようなページに移動します。たとえば、「セール」というリンクをクリックすると、最上部のナビゲータが「店 > 本 > セール」で、「項目」ヘッダーの下にリンク「文庫」がある同じページが表示されます。この例は後でもう少し詳しく説明します。

データを見ると、「本」ノードでdescriptionキーに「説明:お買い得、お買い得、お買い得!」という値が関連付けられています。イメージから、このテキストはTreeBeanではなくBrowseMenuBeanで表示されることがわかります。descriptionキーの値はTreeBeanでは無視されます。同様に、expandableキーに関連付けられている値はBrowseMenuBeanでは無視されますが、TreeBeanではノードの子を表示するかどうかを決めるためにこの情報を使用します。両方のBeanで必要なキーは後述します。

TreeBean

TreeBeanを説明します。

子および属性

TreeBeanは次の名前の付けられた子をサポートします。

uiXMLのキー UIConstant 説明
nodeStamp NODE_STAMP_CHILD

データ・ツリー内で、各DataObjectごとに1回レンダリングされるBean。

TreeBeanは次の属性をサポートします。

uiXMLのキー UIConstant 説明
id ID_ATTR String

ページ全体で一意のID。

formName FORM_NAME_ATTR String

送信されるフォームの名前。

formSubmitted FORM_SUBMITTED_ATTR Boolean

フォーム送信を使用するかどうかを設定します。フォーム送信はデフォルトではありません。したがってフォーム送信が必要な場合は、この属性を明示的にtrueに設定してください。

TreeBeanは特殊な属性構文を持つ次の子をサポートします。属性構文で使用する場合、データ・バインドの必要があります。

uiXMLのキー UIConstant 説明
nodes NODES_ATTR DataObjectList

データのツリー。このDataObjectListは、すべてのルート、つまり最上位ノードを示します。

proxy PROXY_ATTR TreeDataProxy

proxyは、ツリーを開く/閉じる際のイベントのリンク先を設定し、そのツリーの状態を管理します。ツリーで現在選択されているノードもオプションで管理します。

まず、最も基本的なツリーを説明します。

これ以降の例では、説明をわかりやすくするために実際のuiXMLの一部を省略します。

 <tree/>

この例はまさに基礎部分だけであるため、何も表示されません。tree要素の表示のみを宣言しましたが、何かを表示するにはデータを追加する必要があります。

ツリー・データ

ツリー・データは、nodes属性で設定されます。当然、TreeBeanのデータはツリーのフォーム内にあります。このデータ・ツリーにあるノードはDataObjectです。各DataObjectは、特定のキーで特定のデータを格納します。次の表に、各DataObjectで扱うキーと値のペアを示します。

uiXMLのキー UIConstant 説明
text TEXT_KEY String

ノードに表示するテキスト。

icon ICON_KEY String

ノードに表示するアイコンのURI。幅が16ピクセル、高さが22ピクセルのイメージ・ファイルを使用します。デフォルトでは、リーフ・ノードにはアイコンはレンダリングされず、子のあるノードにはデフォルトのフォルダ・アイコンが表示されます。

selected SELECTED_KEY Boolean

選択されているノードとしてレンダリングするには、これをtrueに設定してください。

destination DESTINATION_KEY String

テキストをクリックした際に移動する先のURI。

targetFrame TARGET_FRAME_KEY String

リンク先のターゲット・フレーム。

expandable EXPANDABLE_KEY String

ノードが開いているか、閉じているか、またはリーフであるかを判断するために使用されます。設定できる値は次のとおりです。

  • expanded: ノードは開いた状態でレンダリングされます。これは、子が表示されることを意味します。
  • collapsed: ノードは、現在非表示の子があるものとしてレンダリングされます。
  • no: ノードはリーフとしてレンダリングされます。
collapseDestination COLLAPSE_DESTINATION_KEY String

現在開いているノードを閉じる際に表示するURI。

expandDestination EXPAND_DESTINATION_KEY String

現在閉じているノードを開く際に表示するURI。

nodes NODES_KEY DataObjectList

ノードの子。

次に、データを追加する例を示します。

<dataScope xmlns="http://xmlns.oracle.com/uix/ui"
           xmlns:data="http://xmlns.oracle.com/uix/ui"
           xmlns:ctrl="http://xmlns.oracle.com/uix/controller" >
 <contents>

   <!-- UIX Components -->
   <form name="myForm" >
     <contents>
       <tree data:nodes="nodes@data:Nodes" />
     </contents>
   </form>
 </contents>

 <!-- Data -->
 <provider>
   <data name="data:Nodes">
     <inline>
       <nodes text="店"
               destination="http://www.oracle.com"
               expandable="expanded">
         <nodes text="本"
                 destination="http://www.oracle.com"
                 expandable="collapsed">
           <nodes text="セール"
                   destination="http://www.oracle.com"
                   expandable="collapsed">
             <nodes text="文庫"
                     expandable="no"
                     destination="http://www.oracle.com" />
           </nodes>
           <nodes text="フィクション"
                   destination="http://www.oracle.com"
                   expandable="no"/>
           <nodes text="ノンフィクション"
                   destination="http://www.oracle.com"
                   expandable="no"/>
         </nodes>
         <nodes text="ハードウェア"
                 expandable="collapsed">
           <nodes text="デスクトップ"
                   destination="http://www.oracle.com"
                   expandable="no"/>
           <nodes text="ノートブック"
                   destination="http://www.oracle.com"/>
         </nodes>
       </nodes>
     </inline>
   </data>

 </provider>
</dataScope>

まず、DataObjectのキーと値のペアのリンク、およびこれらがツリーでどのように表示されるかを説明します。textキーで返される値は、ノードのテキストとして表示されます。ノード「店」および「本」については、destinationキーの値を設定してリンクにしています。「ハードウェア」には設定していないため、このノードはクリックできません。expandableキーで返される値は、子を表示するかどうかを決定します。したがって、「店」の子は表示されますが、「本」の子は表示されません。

プラス・アイコンとマイナス・アイコンをクリックしても、何も起こりません。これは、TreeBeanでは各DataObjectのキーと値のペアで指示されたようにツリーをレンダリングするのみで、ツリーを対話型にする処理は行わないためです。TreeBeanはUIX Componentsの1つであることに注意してください。つまり、子および属性を受け取り、Beanを介してレンダリングまたはパスに適切な内容を出力します。対話型にするには、ある状態から別の状態へのフローを処理するものが必要です。これを行うには、UIX Controllerを使用するか、サーブレットを作成します。ツリーを簡単に対話型にできるクラスを用意しており、これについては後述します。まずは、ツリーの外観の変更方法を説明します。

collapsed値をいくつかexpandedに変更し、違いを示します。

<dataScope xmlns="http://xmlns.oracle.com/uix/ui"
           xmlns:data="http://xmlns.oracle.com/uix/ui"
           xmlns:ctrl="http://xmlns.oracle.com/uix/controller" >
   <contents>

   <!-- UIX Components -->
   <form name="myForm" >
     <contents>
       <tree data:nodes="nodes@data:Nodes" />
     </contents>
   </form>
 </contents>

 <!-- Data -->
 <provider>
   <data name="data:Nodes">
     <inline>
       <nodes text="店"
               destination="http://www.oracle.com"
               expandable="expanded">
         <nodes text="本"
                 destination="http://www.oracle.com"
                 expandable="expanded">
           <nodes text="セール"
                   destination="http://www.oracle.com"
                   expandable="expanded">
             <nodes text="文庫"
                     expandable="no"
                     destination="http://www.oracle.com" />
           </nodes>
           <nodes text="フィクション"
                   destination="http://www.oracle.com"
                   expandable="no"/>
           <nodes text="ノンフィクション"
                   destination="http://www.oracle.com"
                   expandable="no"/>
         </nodes>
         <nodes text="ハードウェア"
                 expandable="expanded">
           <nodes text="デスクトップ"
                   destination="http://www.oracle.com"
                   expandable="no"/>
           <nodes text="ノートブック"
                   destination="http://www.oracle.com"
                   expandable="no"/>
         </nodes>
       </nodes>
     </inline>
   </data>

 </provider>
</dataScope>

デフォルトがexpandable="no"であるため、リーフに対してはこのキーと値のペアを取り除くことができます。リーフ以外の項目でexpandableを設定しなかった場合、または値としてnoを指定した場合は、プラス・アイコン(+)またはマイナス・アイコン(-)は表示されません。次の例では「店」ノードにexpandableキーがなく、アイコンが削除されていることに注意してください。また、「ハードウェア」ノードはリーフでないにもかかわらずexpandableキーがnoに設定されており、アイコンが削除されていることにも注意してください。

<dataScope xmlns="http://xmlns.oracle.com/uix/ui"
           xmlns:data="http://xmlns.oracle.com/uix/ui"
           xmlns:ctrl="http://xmlns.oracle.com/uix/controller" >
 <contents>

   <!-- UIX Components -->
   <form name="myForm" >
     <contents>
       <tree data:nodes="nodes@data:Nodes" />
     </contents>
   </form>
 </contents>

 <!-- Data -->
 <provider>
   <data name="data:Nodes">
     <inline>
        <!-- "expandable" key removed -->
       <nodes text="店"
               destination="http://www.oracle.com" >
         <nodes text="本"
                 destination="http://www.oracle.com"
                 expandable="expanded">
           <nodes text="セール"
                   destination="http://www.oracle.com"
                   expandable="expanded">
             <nodes text="文庫"
                     destination="http://www.oracle.com" />
           </nodes>
           <nodes text="フィクション"
                   destination="http://www.oracle.com"/>
           <nodes text="ノンフィクション"
                   destination="http://www.oracle.com"/>
         </nodes>
          <!-- "expandable" changed to "no" -->
         <nodes text="ハードウェア"
                 expandable="no" >
           <nodes text="デスクトップ"
                   destination="http://www.oracle.com"/>
           <nodes text="ノートブック"
                   destination="http://www.oracle.com"/>
         </nodes>
       </nodes>
     </inline>
   </data>

 </provider>
</dataScope>

selectedキーの値をtrueに設定することにより、ノードを選択された状態で表示することもできます。次の例では、「店」および「セール」を青の背景色に白の文字でハイライト表示します。

<dataScope xmlns="http://xmlns.oracle.com/uix/ui"
           xmlns:data="http://xmlns.oracle.com/uix/ui"
           xmlns:ctrl="http://xmlns.oracle.com/uix/controller" >
 <contents>

   <!-- UIX Components -->
   <form name="myForm" >
     <contents>
       <tree data:nodes="nodes@data:Nodes" />
     </contents>
   </form>
 </contents>

 <!-- Data -->
 <provider>
   <data name="data:Nodes">
     <inline>
       <nodes text="店"
               destination="http://www.oracle.com"
               expandable="expanded"
               selected="true">
         <nodes text="本"
                 destination="http://www.oracle.com"
                 expandable="expanded">
           <nodes text="セール"
                   destination="http://www.oracle.com"
                   expandable="expanded"
                   selected="true">
             <nodes text="文庫"
                     destination="http://www.oracle.com" />
           </nodes>
           <nodes text="フィクション"
                   destination="http://www.oracle.com"/>
           <nodes text="ノンフィクション"
                   destination="http://www.oracle.com"/>
         </nodes>
         <nodes text="ハードウェア"
                 expandable="expanded" >
           <nodes text="デスクトップ"
                   destination="http://www.oracle.com"/>
           <nodes text="ノートブック"
                   destination="http://www.oracle.com"/>
         </nodes>
       </nodes>
     </inline>
   </data>

 </provider>
</dataScope>

デフォルトでは、子を持つノードはフォルダ・アイコンでレンダリングされます。iconキーの値を別のイメージのURIに設定し、リーフにアイコンを追加したり、フォルダ・アイコンを置き換えることができます。次に例を示します。


<dataScope xmlns="http://xmlns.oracle.com/uix/ui"
           xmlns:data="http://xmlns.oracle.com/uix/ui"
           xmlns:ctrl="http://xmlns.oracle.com/uix/controller" >
 <contents>

   <!-- UIX Components -->
   <form name="myForm" >
     <contents>
       <tree data:nodes="nodes@data:Nodes" />
     </contents>
   </form>
 </contents>

 <!-- Data -->
 <provider>
   <data name="data:Nodes">
     <inline>
       <nodes text="店"
               destination="http://www.oracle.com"
               expandable="expanded"
               icon="/docs/devguide/images/data_trees/info.gif">
         <nodes text="本"
                 destination="http://www.oracle.com"
                 expandable="expanded"
                 icon="/docs/devguide/images/data_trees/info.gif">
           <nodes text="セール"
                   destination="http://www.oracle.com"
                   expandable="expanded"
                   icon="/docs/devguide/images/data_trees/info.gif">
             <nodes text="文庫"
                     destination="http://www.oracle.com" />
           </nodes>
           <nodes text="フィクション"
                   destination="http://www.oracle.com"/>
           <nodes text="ノンフィクション"
                   destination="http://www.oracle.com"/>
         </nodes>
         <nodes text="ハードウェア"
                 expandable="expanded"
                 icon="/docs/devguide/images/data_trees/info.gif">
           <nodes text="デスクトップ"
                   destination="http://www.oracle.com"/>
           <nodes text="ノートブック"
                   destination="http://www.oracle.com"/>
         </nodes>
       </nodes>
     </inline>
   </data>

 </provider>
</dataScope>

ノード・スタンプ

デフォルトでは、リンクはツリーの各ノードに対して表示されますが、nodeStampを設定すると表示内容をさらに制御できます。nodeStampは、TreeBeanの名前の付けられた子です。

スタンプとは何でしょうか。スタンプとは、(任意の)UINodeで、さらに特定のページで複数回レンダリングされるものを意味します。ツリーにはスタンプが1つ定義され、このスタンプがツリーのノードごとに1回繰り返し、レンダリングされます。このため各ノードは同じように見えますが、データ・バインドを介して異なるデータを指定できます。ノード・スタンプを使用した例を次に示します。DataObjectに追加された任意のキーと値のペアをツリーが、データ・バインドを使用して値を抽出されていることに注意してください。

<dataScope xmlns="http://xmlns.oracle.com/uix/ui"
           xmlns:data="http://xmlns.oracle.com/uix/ui"
           xmlns:ctrl="http://xmlns.oracle.com/uix/controller" >
 <contents>

   <!-- UIX Components -->
   <form name="myForm" >
     <contents>
       <tree data:nodes="nodes@data:Nodes" >
         <nodeStamp>
           <flowLayout>
             <contents>
               <checkBox data:rendered="rendered"
                          data:disabled="disabled"
                          data:checked="checked"/>
               <styledText data:text="text" />
             </contents>
           </flowLayout>
         </nodeStamp>
       </tree>
     </contents>
   </form>
 </contents>

 <!-- Data -->
 <provider>
   <data name="data:Nodes">
     <inline>
       <nodes text="店"
               destination="http://www.oracle.com"
               expandable="expanded"
               rendered="false" 
               icon="/docs/devguide/images/data_trees/info.gif">
         <nodes text="本"
                 destination="http://www.oracle.com"
                 expandable="expanded"
                 rendered="false"
                 icon="/docs/devguide/images/data_trees/info.gif">
           <nodes text="セール"
                   destination="http://www.oracle.com"
                   expandable="expanded"
                   rendered="false"
                   icon="/docs/devguide/images/data_trees/info.gif">
             <nodes text="文庫"
                     destination="http://www.oracle.com"
                     disabled="true" />
           </nodes>
           <nodes text="フィクション"
                   destination="http://www.oracle.com"
                   checked="true"/>
           <nodes text="ノンフィクション"
                   destination="http://www.oracle.com"/>
         </nodes>
         <nodes text="ハードウェア"
                 expandable="expanded"
                 rendered="false"
                 icon="/docs/devguide/images/data_trees/info.gif">
           <nodes text="デスクトップ"
                   destination="http://www.oracle.com"/>
           <nodes text="ノートブック"
                   destination="http://www.oracle.com"/>
         </nodes>
       </nodes>
     </inline>
   </data>

 </provider>
</dataScope>

Warning icon ノードの高さは任意ではないので注意してください。現状では、ノードの高さは約45ピクセルです。

ツリー・プロキシ

ツリーを対話型にしましょう。ノードが閉じている場合、expandDestinationキーに関連付けられている値がノードが開いた状態を表すリンク先として使用されます。ノードが開いている場合は、collapseDestinationキーに関連付けられている値がノードが閉じた状態を表すリンク先として使用されます。これらのリンク先をユーザー自身で設定する際は、ツリーの状態を把握する必要があります。つまり、開いているノード、閉じているノード、および選択されているノードを把握する必要があります。

簡単にツリーを使用できるように、ClientStateTreeDataProxyクラスが用意されています。このプロキシは、開くリンク先および閉じるリンク先を設定して、ツリーが開く状態と閉じる状態を管理します。使用するプロキシは、proxy属性で設定します。

ClientStateTreeDataProxyを使用すると、ツリーの状態がクライアントで保持されます。プロキシは、ノードが開かれるとき、または閉じられるときに次の名前と値のペアがサーバーに送信されるよう、開くリンク先および閉じるリンク先を設定します。

eventの値は、UIX Controllerのイベントの名前です。ノードが開いていても閉じていても、値はexpandなので注意してください。

sourceの値は、ID属性の値です。ID属性はまだ使用していませんが、次の例で使用します。

nodestateおよびselectionに関連付けられている値は、サーバー上で新規プロキシを作成するために使用されます。ユーザーは、これらの値が実際に何であるかを知る必要はありません。値を要求して、ClientStateTreeDataProxyコンストラクタに渡します。このプロセスは、次の例でわかりやすく説明します。

ツリーを適切な状態に設定し、ツリーの状態としてnullが指定されたClientStateTreeDataProxyコンストラクタを使用することで、プロキシはノード・データから、開いているか閉じているかの状態の取得を試行します。デフォルトでツリーを特定のノードまで開いた状態にするには、ルートまでのパスとともにノードを開くよう設定する必要があります。ClientStateTreeDataProxyの使用方法も、次の例でわかりやすく説明します。

この例では、Javaコードが必要です。Javaは、uiXMLの例の後に記述されています。


<ctrl:page xmlns="http://xmlns.oracle.com/uix/ui"
  xmlns:ctrl="http://xmlns.oracle.com/uix/controller"
  xmlns:data="http://xmlns.oracle.com/uix/ui">

 <ctrl:content xmlns:ui="http://xmlns.oracle.com/uix/ui">
   <body>
     <contents>

       <dataScope xmlns="http://xmlns.oracle.com/uix/ui">
         <contents>

           <!-- UIX Components -->
           <form name="myForm" >
             <contents>
               <tree id="tree"
                  formSubmitted="true"
                  data:nodes="nodes@data:Nodes"
                  data:proxy="proxy@TreeProxy"/>
             </contents>
           </form>
         </contents>

         <!-- Data -->
         <provider>

           <data name="TreeProxy">
             <method class="oracle.cabo.doc.demo.DataTrees"
                      method="getTreeProxy"/>
           </data>

           <data name="data:Nodes">
             <inline>
               <nodes text="店"
                       destination="http://www.oracle.com"
                       expandable="expanded">
                 <nodes text="本"
                         destination="http://www.oracle.com"
                         expandable="expanded">
                   <nodes text="セール"
                           destination="http://www.oracle.com"
                           expandable="expanded">
                     <nodes text="文庫"
                             destination="http://www.oracle.com" />
                   </nodes>
                   <nodes text="フィクション"
                           destination="http://www.oracle.com"/>
                   <nodes text="ノンフィクション"
                           destination="http://www.oracle.com"/>
                 </nodes>
                 <nodes text="ハードウェア"
                         expandable="expanded">
                   <nodes text="デスクトップ"
                           destination="http://www.oracle.com"/>
                   <nodes text="ノートブック"
                           destination="http://www.oracle.com"/>
                 </nodes>
               </nodes>
             </inline>
           </data>
         </provider>
       </dataScope>
     </contents>
   </body>
 </ctrl:content>

 <!-- UIX Controller -->
  <ctrl:handlers xmlns="http://xmlns.oracle.com/uix/controller">

   <event name="expand">
     <method class="oracle.cabo.doc.demo.DataTrees"
        method="expandEventHandler"/>
   </event>

 </ctrl:handlers>
</ctrl:page>

次に示すのは、上の例で太字で示した2つのメソッドです。この後のTreeBeanの例では、必ずこのメソッドを使用します。最初のメソッドは、プロキシを返すDataObjectを返すgetTreeProxyメソッドです。


  public static DataObject getTreeProxy(
  RenderingContext rc,
  String ns,
  String name)
  {
    return new TreeProxyDataObject(null);
  }

  private static class TreeProxyDataObject implements DataObject
  {
        public TreeProxyDataObject(
            String submitURL
          )
        {
          _submitURL = submitURL;
        }

        public Object selectValue(
            RenderingContext rc,
            Object key
          )
        {
          BajaContext bc = BajaRenderingContext.getBajaContext(rc);
          EventResult result = EventResult.getEventResult(bc);
          Object proxy = (result==null) ? null : result.getProperty("proxy");
          if (proxy==null)
            proxy =  new ClientStateTreeDataProxy( _submitURL, null, null, null);

          return proxy;
        }

        String _submitURL;
  }

expandEventHandlerメソッドは、expandイベントの発生時にこのイベントを処理します。expandEventHandlerでは、state(UIConstants.STATE_PARAM)、node(UIConstants.NODE_PARAM)およびselection(UIConstants.SELECTION_PARAM)の各パラメータに関連付けられている値を新規のClientStateTreeProxyに渡すことに注意してください。この新規のプロキシは、コンテキストでプロパティとして設定された後、前述のメソッドで作成されたTreeProxyDataObjectによってデータ・ツリーへと返されます。


  public static EventResult expandEventHandler(
    BajaContext context,
    Page page,
    PageEvent event )throws Throwable
  {
    String state = event.getParameter(UIConstants.STATE_PARAM);
    String node = event.getParameter(UIConstants.NODE_PARAM);
    String selection = event.getParameter(UIConstants.SELECTION_PARAM);
    EventResult result = new EventResult(page);
    Object proxy = new ClientStateTreeDataProxy(null, state, node, selection);
    result.setProperty("proxy", proxy);
    return result;
  }

ノードの選択状態は、selectionパラメータを受け取るコンストラクタが使用されている場合はプロキシで処理されます。現状では、プロキシでサポートされているのは1つのみです。表示されていない場合でも、ノードは(新規選択が行われるまで)選択されたままになります。選択の状態はonClickハンドラを介して処理されます。ノード・スタンプを使用した例を次に示します。ノードのチェックボックスがクリックされたときに、背景色とテキスト色が変更されることに注意してください。

Warning iconプロキシを使用している場合、Netscapeではノードの選択状態は表示されません。これはNetscapeの制限です。


<ctrl:page xmlns="http://xmlns.oracle.com/uix/ui"
  xmlns:ctrl="http://xmlns.oracle.com/uix/controller"
  xmlns:data="http://xmlns.oracle.com/uix/ui"
  xmlns:html="http://www.w3.org/TR/REC-html40">

 <ctrl:content xmlns:ui="http://xmlns.oracle.com/uix/ui">
   <body>
     <contents>

       <dataScope xmlns="http://xmlns.oracle.com/uix/ui">
         <contents>

           <!-- UIX Components -->
           <form name="myForm" >
             <contents>
               <tree id="tree"
                  formSubmitted="true"
                  data:nodes="nodes@data:Nodes"
                  data:proxy="proxy@TreeProxy">
                 <nodeStamp>
                   <flowLayout>
                     <contents>
                       <checkBox data:rendered="rendered"
                                  data:disabled="disabled"
                                  data:checked="checked"/>
                       <link data:destination="destination" data:text="text" />
                     </contents>
                   </flowLayout>
                 </nodeStamp>
               </tree>
             </contents>
           </form>
         </contents>

         <!-- Data -->
         <provider>

           <data name="TreeProxy">
             <method class="oracle.cabo.doc.demo.DataTrees"
                      method="getTreeProxy"/>
           </data>

           <data name="data:Nodes">
             <inline>
               <nodes text="店"
                       destination="http://www.oracle.com"
                       expandable="expanded"
                       rendered="false"
                       icon="/docs/devguide/images/data_trees/info.gif" >
                 <nodes text="本"
                         destination="http://www.oracle.com"
                         expandable="expanded"
                         rendered="false"
                         icon="/docs/devguide/images/data_trees/info.gif" >
                   <nodes text="セール"
                           destination="http://www.oracle.com"
                           expandable="expanded"
                           rendered="false"
                           icon="/docs/devguide/images/data_trees/info.gif">
                     <nodes text="文庫"
                             destination="http://www.oracle.com"
                             disabled="true" />
                   </nodes>
                   <nodes text="フィクション"
                           destination="http://www.oracle.com"
                           checked="true"/>
                   <nodes text="ノンフィクション"
                           destination="http://www.oracle.com"/>
                 </nodes>
                 <nodes text="ハードウェア"
                         expandable="expanded"
                         rendered="false"
                         icon="/docs/devguide/images/data_trees/info.gif" >
                   <nodes text="デスクトップ"
                           destination="http://www.oracle.com"/>
                   <nodes text="ノートブック"
                           destination="http://www.oracle.com"/>
                 </nodes>
               </nodes>
             </inline>
           </data>
         </provider>
       </dataScope>
     </contents>
   </body>
 </ctrl:content>

 <!-- UIX Controller -->
 <ctrl:handlers xmlns="http://xmlns.oracle.com/uix/controller">

   <event name="expand">
     <method class="oracle.cabo.doc.demo.DataTrees"
        method="expandEventHandler"/>
   </event>

 </ctrl:handlers>

</ctrl:page>

ツリーおよびフレーム

開発時に、TreeBeanでフレームを使用する場合がよくあります。この使用方法を、次の例で示します。この例では、3つのuiXMLファイルを使用しています。最初のファイルではフレームを設定します。

<page xmlns="http://xmlns.oracle.com/uix/controller"
      xmlns:ctrl="http://xmlns.oracle.com/uix/controller"
      xmlns:data="http://xmlns.oracle.com/uix/ui"
      xmlns:http="http://www.w3.org/TR/REC-html40">
 <content>

   <frameBorderLayout  xmlns="http://xmlns.oracle.com/uix/ui" >

    <left>
     <frame source="B-2-11.uix" name="tree" width="30%" />
    </left>

    <center>
     <frame source="B-2-12.uix" name="contents" />
    </center>

   </frameBorderLayout>

 </content>
</page>

次のファイルでは、新規のリンク先をいくつか含むツリー自体を設定し、コンテンツの転送先のフレームを指定するtargetFrameキーを追加します。

<ctrl:page xmlns="http://xmlns.oracle.com/uix/ui"
  xmlns:ctrl="http://xmlns.oracle.com/uix/controller"
  xmlns:data="http://xmlns.oracle.com/uix/ui"
  xmlns:html="http://www.w3.org/TR/REC-html40">

 <ctrl:content xmlns:ui="http://xmlns.oracle.com/uix/ui">
   <body>
     <contents>

       <dataScope xmlns="http://xmlns.oracle.com/uix/ui">
         <contents>
      <!-- UIX Components -->
           <form name="myForm" >
             <contents>
               <tree id="tree"
                  formSubmitted="true"
                  data:nodes="nodes@data:Nodes"
                  data:proxy="proxy@TreeProxy"/>
             </contents>
           </form>
         </contents>

         <provider>

           <!-- Data -->
           <data name="TreeProxy">
             <method class="oracle.cabo.doc.demo.DataTrees"
                      method="getTreeProxy"/>
           </data>

           <data name="data:Nodes">
             <inline>
               <nodes text="店"
                       destination="http://otn.oracle.com/index.html"
                       targetFrame="contents"
                       expandable="expanded">
                 <nodes text="本"
                         destination="http://www.osborne.com/oracle/"
                         targetFrame="contents"
                         expandable="expanded">
                   <nodes text="セール"
                           destination="http://www.oracle.com"
                           targetFrame="contents"
                           expandable="expanded">
                     <nodes text="文庫"
                             destination="http://www.oracle.com/appsnet/"
                             targetFrame="contents"/>
                   </nodes>
                   <nodes text="フィクション"
                           destination="http://www.oracle.com/oramag/"
                           targetFrame="contents"/>
                   <nodes text="ノンフィクション"
                           destination="http://otn.oracle.com/support/content.html"
                           targetFrame="contents"/>
                 </nodes>

                 <nodes text="ハードウェア"
                         expandable="expanded" >
                   <nodes text="デスクトップ"
                           destination="http://otn.oracle.com/training/content.html"
                           targetFrame="contents"/>
                   <nodes text="ノートブック"
                           destination="http://otn.oracle.com/tech/content.html"
                           targetFrame="contents"/>
                 </nodes>
               </nodes>
             </inline>
           </data>
         </provider>
       </dataScope>
     </contents>
   </body>
 </ctrl:content>

 <!-- UIX Controller -->
 <ctrl:handlers xmlns="http://xmlns.oracle.com/uix/controller">

   <event name="expand">
     <method class="oracle.cabo.doc.demo.DataTrees"
        method="expandEventHandler"/>
   </event>

 </ctrl:handlers>
</ctrl:page>

最後のファイルは、空のuiXMLファイルです。

<ctrl:page xmlns="http://xmlns.oracle.com/uix/ui"
  xmlns:ctrl="http://xmlns.oracle.com/uix/controller"
  xmlns:data="http://xmlns.oracle.com/uix/ui"
  xmlns:html="http://www.w3.org/TR/REC-html40"/>

BrowseMenuBean

BrowseMenuBeanは、階層構造またはツリー構造のデータを表示するもう1つの方法です。

名前の付けられた子および属性

BrowseMenuBeanは4つの名前の付けられた子をサポートします。

uiXMLのキー UIConstant 説明
location LOCATION_CHILD

BrowseMenuの最上部でのロケータ要素のレンダリングに使用するBean。

contentLink CONTENT_LINK_CHILD

現在のカテゴリのコンテンツへのリンクに使用するBean。

categories CATEGORIES_CHILD

カテゴリのレンダリングに使用するBean。

items ITEMS_CHILD

項目のレンダリングに使用するBean。

BrowseMenuBeanは、実際にこれらの名前の付けられた子を適切な場所に配置するレイアウト・マネージャです。ブラウザ・ルック&フィール(BLAF)のガイドラインでは、BreadCrumbsBeanは位置の要素、LinkBeanはコンテンツ・リンクの要素、BulletedListBeanはカテゴリを表示するもの、別のBulletedListBeanは項目を表示するものとされています。

BrowseMenuBeanは次の属性をサポートします。

uiXMLのキー UIConstant 説明
id ID_ATTR String

ページ全体で一意のID。

title TITLE_ATTR String

BrowseMenuのタイトルを設定します。このテキストは最上部のヘッダーに表示されます。この属性が設定されていない場合、デフォルトのテキストは「参照」に設定されます。

categoryTitle CATEGORY_TITLE_ATTR String

カテゴリ・セクションのタイトルを設定します。このテキストはカテゴリの上のヘッダーに表示されます。この属性が設定されていない場合、デフォルトのテキストは「カテゴリ」に設定されます。

itemTitle ITEM_TITLE_ATTR String

項目セクションのタイトルを設定します。このテキストは項目の上のヘッダーに表示されます。この属性が設定されていない場合、デフォルトのテキストは「項目」に設定されます。

longDesc LONG_DESC_ATTR String

タイトルのすぐ下に表示される、現在の位置を表す記述を設定します。この属性が設定されていない場合、デフォルトのテキストは空の文字列に設定されます。

formName FORM_NAME_ATTR String

送信されるフォームの名前。

formSubmitted FORM_SUBMITTED_ATTR Boolean

フォーム送信を使用するかどうかを設定します。フォーム送信はデフォルトではありません。したがってフォーム送信が必要な場合は、この属性を明示的にtrueに設定してください。

次のイメージは、これらの名前の付けられた子および属性がどのように使用されるかを示したものです。

図15-4: ブラウザにレンダリングされた階層ツリー

"Shop" tree, with callouts identifying named children and attributes

すべてをハードコードした単純な例を使用して、BrowseMenuBeanを説明します。複雑な例はその後で説明します。

    <browseMenu/>

これは最も単純な例で、「参照」というテキストの付いたヘッダーのみが表示されます。これを興味深い例にするには、データを追加する必要があります。

まず、categoriesという子を追加します。categoriesは子を持つツリー・ノードに対応します。リーフには対応しません。

   <browseMenu>
      <categories>
       <bulletedList rows="10">
         <contents>
           <link text="セール" destination="http://www.oracle.com"/>
         </contents>
       </bulletedList>
     </categories>
   </browseMenu>

このトピックの始めに、「セール」リンクをクリックすると、最上部にナビゲータ「店 > 本 > セール」があり、「項目」ヘッダーの下にリンク「文庫」のあるページが表示されると説明しましたが、この例の「セール」リンクでは表示されません。TreeBeanと同様に、BrowseMenuBeanのみではツリーを対話型にする処理を行わないためです。BrowseMenuBeanはUIX Componentsの1つであることに注意してください。つまり、子および属性を受け取り、Beanを介してレンダリングまたはパスに適切な内容を出力します。対話型にするには、ある状態から別の状態へのフローを処理するものが必要です。これを行うには、UIX Controllerを使用するか、サーブレットを作成します。BrowseMenuBeanでの対話型の処理を簡単にするクラスを用意しており、これについては後述します。まずは、BrowseMenuBeanの外観の変更方法を説明します。

続いて、itemsという子を追加します。itemsは、ツリーのリーフに対応します。

   <browseMenu>
     <categories>
       <bulletedList rows="10">
         <contents>
           <link text="セール" destination="http://www.oracle.com"/>
         </contents>
       </bulletedList>
     </categories>
      <items>
       <bulletedList rows="10">
         <contents>
           <link text="フィクション" destination="http://www.oracle.com"/>
           <link text="ノンフィクション" destination="http://www.oracle.com"/>
         </contents>
       </bulletedList>
     </items>
   </browseMenu>

locationという子を追加します。これにより、ツリーでのユーザーの位置を示すことができます。

   <browseMenu>
      <location>
       <breadCrumbs>
         <contents>
           <link text="店" destination="http://www.oracle.com"/>
           <link text="本" destination="http://www.oracle.com"/>
         </contents>
       </breadCrumbs>
     </location>
     <categories>
       <bulletedList rows="10">
         <contents>
           <link text="セール" destination="http://www.oracle.com"/>
         </contents>
       </bulletedList>
     </categories>
     <items>
       <bulletedList rows="10">
         <contents>
           <link text="フィクション" destination="http://www.oracle.com"/>
           <link text="ノンフィクション" destination="http://www.oracle.com"/>
         </contents>
       </bulletedList>
     </items>
   </browseMenu>

最後に、contentLinkという子を追加します。コンテンツ・リンクが表示され、ユーザーは追加の情報または指示にアクセスできます。

   <browseMenu>
     <location>
       <breadCrumbs>
         <contents>
           <link text="店" destination="http://www.oracle.com"/>
           <link text="本" destination="http://www.oracle.com"/>
         </contents>
       </breadCrumbs>
     </location>
      <contentLink>
       <link text="詳細情報" destination="http://www.oracle.com"/>
     </contentLink>
     <categories>
       <bulletedList rows="10">
         <contents>
           <link text="セール" destination="http://www.oracle.com"/>
         </contents>
       </bulletedList>
     </categories>
     <items>
       <bulletedList rows="10">
         <contents>
           <link text="フィクション" destination="http://www.oracle.com"/>
           <link text="ノンフィクション" destination="http://www.oracle.com"/>
         </contents>
       </bulletedList>
     </items>
   </browseMenu>

ここまででBrowseMenuの基本的なレイアウトを見ました。次は属性を説明します。

まずtitle属性を設定し、タイトルを「参照」から「本」に変更します。

   <browseMenu title="本">
     <location>
       <breadCrumbs>
         <contents>
           <link text="店" destination="http://www.oracle.com"/>
           <link text="本" destination="http://www.oracle.com"/>
         </contents>
       </breadCrumbs>
     </location>
     <contentLink>
       <link text="詳細情報" destination="http://www.oracle.com"/>
     </contentLink>
     <categories>
       <bulletedList rows="10">
         <contents>
           <link text="セール" destination="http://www.oracle.com"/>
         </contents>
       </bulletedList>
     </categories>
     <items>
       <bulletedList rows="10">
         <contents>
           <link text="フィクション" destination="http://www.oracle.com"/>
           <link text="ノンフィクション" destination="http://www.oracle.com"/>
         </contents>
       </bulletedList>
     </items>
   </browseMenu>

次にcategoryTitle属性を設定し、テキストを「カテゴリ」から「Have Subcategories」に変更します。itemTitle属性も設定し、テキストを「項目」から「No Subcategories」に変更します。

   <browseMenu title="本"
                categoryTitle="Have Subcategories"
                itemTitle="No Subcategories">
     <location>
       <breadCrumbs>
         <contents>
           <link text="店" destination="http://www.oracle.com"/>
           <link text="本" destination="http://www.oracle.com"/>
         </contents>
       </breadCrumbs>
     </location>
     <contentLink>
       <link text="詳細情報" destination="http://www.oracle.com"/>
     </contentLink>
     <categories>
       <bulletedList rows="10">
         <contents>
           <link text="セール" destination="http://www.oracle.com"/>
         </contents>
       </bulletedList>
     </categories>
     <items>
       <bulletedList rows="10">
         <contents>
           <link text="フィクション" destination="http://www.oracle.com"/>
           <link text="ノンフィクション" destination="http://www.oracle.com"/>
         </contents>
       </bulletedList>
     </items>
   </browseMenu>

longDesc属性を設定します。説明や指示はこの領域に記述します。

   <browseMenu title="本"
                categoryTitle="Have Subcategories"
                itemTitle="No Subcategories"
                longDesc="説明:お買得、お買得、お買得!">
     <location>
       <breadCrumbs>
         <contents>
           <link text="店" destination="http://www.oracle.com"/>
           <link text="本" destination="http://www.oracle.com"/>
         </contents>
       </breadCrumbs>
     </location>
     <contentLink>
       <link text="詳細情報" destination="http://www.oracle.com"/>
     </contentLink>
     <categories>
       <bulletedList rows="10">
         <contents>
           <link text="セール" destination="http://www.oracle.com"/>
         </contents>
       </bulletedList>
     </categories>
     <items>
       <bulletedList rows="10">
         <contents>
           <link text="フィクション" destination="http://www.oracle.com"/>
           <link text="ノンフィクション" destination="http://www.oracle.com"/>
         </contents>
       </bulletedList>
     </items>
   </browseMenu>

formSubmittedおよびformNameという2つの属性が残ります。これらの属性の使用例は次項で示されます。

ツリー構造のデータはどうなったのでしょうか。次のセクションで、ツリー構造のデータでBrowseMenuBeanを使用する方法を説明します。

BrowseNodeDataObject

BrowseMenuBeanを使用する目的は、ユーザーが複雑な階層構造のオブジェクトを参照できるようにすることですが、階層構造のデータはTreeBeanの際に提示したそのままの状態であればBrowseMenuには追加されません。実際、BrowseMenuBeanでは、すべての名前の付けられた子および属性に適切なデータを含める必要があります。このデータのバインドを比較的簡単にするBrowseNodeDataObjectというクラスを用意しています。このクラスは、DataObjectのツリーおよび現在の位置を受け取り、適切な情報を抽出します。DataObjectのツリーという意味を理解できている必要があります。BrowseNodeDataObjectのインスタンスは、TreeBeanで使用されるデータ・ツリーと同じデータ・ツリーを受け取ることができます。

BrowseNodeDataObjectでは、ツリーのノードで次のキーを使用します。

uiXMLのキー UIConstant 説明
text TEXT_KEY String

ノードのテキスト。

destination DESTINATION_KEY String

リンクのURI。

destinationText DESTINATION_TEXT_KEY String

リンクのテキスト。

description DESCRIPTION_KEY String

説明または指示。

nodes NODES_KEY DataObjectList

ノードの子。

これらのキーについてはほとんど説明済です。新規のキーが2つあります。descriptionキーに関連付けられる値はlongDesc属性の値にマップされます。

destinationTextキーの値はcontentLinkという子のテキストになります。TreeBeanでは、子の有無に関係なくノードのリンク先がリンクとして表示されます。たとえば、前述のツリー例では「本」というテキストをクリックすると、リンク先が表示されました。BrowseMenuでは「本」というテキストはヘッダーになっており、クリックできません。このような場合はcontentLinkという子を使用してリンクを別に作成します。

これらのキーを使用するよう更新したデータ・ツリーを示します。BrowseMenuで不要なキーと値のペアをDataObjectに含めても問題ありません。たとえば、expandedキーおよびそれに関連付けられている値はBrowseMenuでは無視されます。

       <nodes text="店"
               destination="http://www.oracle.com"
               destinationText="詳細情報"
               expandable="expanded">
         <nodes text="本"
                 destination="http://www.oracle.com"
                 destinationText="詳細情報"
                 description="詳細情報:お買得、お買得、お買得!"
                 expandable="expanded">
           <nodes text="セール"
                   destination="http://www.oracle.com"
                   expandable="expanded">
             <nodes text="文庫"
                     destination="http://www.oracle.com"/>
           </nodes>
           <nodes text="フィクション"
                   destination="http://www.oracle.com"/>
           <nodes text="ノンフィクション"
                   destination="http://www.oracle.com"/>
         </nodes>
         <nodes text="ハードウェア"
                 expandable="expanded" >
           <nodes text="デスクトップ"
                   destination="http://www.oracle.com"/>
           <nodes text="ノートブック"
                   destination="http://www.oracle.com"/>
         </nodes>
       </nodes>

BrowseNodeDataObjectコンストラクタは、データ・ツリーおよびツリーでの現在の位置を受け取ります。そこから、次のキーの値が作成されます。

uiXMLのキー Javaキー 説明
locationData BrowseNodeDataObject.
LOCATION_DATA_KEY
DataObjectList

locationという子のノード・データ。ツリーのルートから現在の位置にあるノードまでのパス上にあるノードすべてです。

categoriesData BrowseNodeDataObject.
CATEGORIES_DATA_KEY
DataObjectList

categoriesという子のノード・データ。現在の位置にあるデータ・オブジェクトの子のうち、それ自体が子を持ち、リーフではない子すべてです。

itemsData BrowseNodeDataObject.
ITEMS_DATA_KEY
DataObjectList

itemsという子のノード・データ。現在の位置にあるデータ・オブジェクトの子のうち、それ自体に子がなく、リーフである子すべてです。

renderLocation BrowseNodeDataObject.
RENDER_LOCATION_KEY
Boolean

現在の位置にあるノードがツリーのルートである場合、Boolean.FALSEに設定されます。これは、locationの子は、ルートからの相対位置を表示するために利用するからです。

renderContentLink BrowseNodeDataObject.
RENDER_CONTENT_LINK_KEY
Boolean

現在の位置にあるノードをUIConstants.DESTINATION_TEXT_KEYで問合せし、値を返さない、または空の文字列を返す場合、これはBoolean.FALSEに設定されます。

renderCategories BrowseNodeDataObject.
RENDER_CATEGORIES_KEY
Boolean

現在の位置にあるノードに、カテゴリに属す子またはツリーの内部ノードに当たる子がない場合、これはBoolean.FALSEに設定されます。

renderItems BrowseNodeDataObject.
RENDER_ITEMS_KEY
Boolean

現在の位置にあるノードに、項目に属す子またはツリーのリーフに当たる子がない場合、これはBoolean.FALSEに設定されます。

currentState BrowseNodeDataObject.
CURRENT_STATE_KEY
String

コンストラクタに渡されたBrowseMenuの現在の状態。

ユーザーが前述のツリーの「本」ノードを現在の位置として表示しているとします。表に示したキーでは、次のものが返されます。

locationおよびcategoriesのデータは、DataObjectListで、その各DataObjectのdestinationはUIConstant.DESTINATION_KEYキーで取得されます。これによって作成されるリンク先は、locationまたはcategories要素がクリックされると次の名前と子のペアがサーバーに返されるよう設定されます。

eventの値はUIX Controllerのイベントの名前で、この場合はbrowseです。

sourceの値は、ID属性の値です。ID属性はまだ使用していませんが、次の例で使用します。

locationに関連付けられる値は、新規BrowseNodeDataObjectの作成時にサーバーで使用されます。ユーザーは、これらの値が実際に何であるかを知る必要はなく、値を要求して、BrowseNodeDataObjectコンストラクタに渡すだけです。このプロセスは、次の例でわかりやすく説明します。

ユーザーは、表示するツリーのノードの位置を表すString、または現在の位置として参照されるStringを渡して、初期BrowseNodeDataObjectを設定する必要があります。Stringは、ゼロから始まる索引のカンマ区切りの文字列です。たとえば、要求されたノードが最初のルート・ノードの4番目の子である場合、値は0,3です。0は最初のルート・ノードを表し、3は4番目の子を表します。最初のルート・ノードの4番目の子の7番目の子の位置は、0,3,6と格納されます。初期BrowseNodeDataObjectでの現在の位置の値は、通常、0や1などデータ・ツリーのルートを示す値です。渡された現在の位置がnullの場合、デフォルトは0です。これも次の例で説明します。

BrowseNodeDataObjectの使用例を示します。この例で使用するJavaコードは、uiXMLの例の次に記述します。この例では、title属性の値とcategoriesという子のデータをバインドしています。

<ctrl:page xmlns="http://xmlns.oracle.com/uix/ui"
  xmlns:ctrl="http://xmlns.oracle.com/uix/controller"
  xmlns:data="http://xmlns.oracle.com/uix/ui" >

 <ctrl:content xmlns:ui="http://xmlns.oracle.com/uix/ui">
   <body>
     <contents>

       <dataScope xmlns="http://xmlns.oracle.com/uix/ui">
         <contents>

           <!-- UIX Components -->

           <browseMenu id="myBrowseMenu"
                        data:title="text@data:browseData">
             <categories>
               <bulletedList>
                 <contents data:childData="categoriesData@data:browseData">
                   <link data:text="text" data:destination="destination"/>
                 </contents>
               </bulletedList>
             </categories>
           </browseMenu>
         </contents>

         <!-- Data -->
         <provider>

           <data name="data:browseData">
             <method class="oracle.cabo.doc.demo.DataTrees" method="getBrowseNodeDataObject"/>
           </data>

           <data name="data:Nodes">
             <inline>
               <nodes text="店"
                       destination="http://www.oracle.com"
                       destinationText="詳細情報"
                       expandable="expanded">
                 <nodes text="本"
                         destination="http://www.oracle.com"
                         destinationText="詳細情報"
                         description="詳細情報:お買得、お買得、お買得!"
                         expandable="expanded">
                   <nodes text="セール"
                           destination="http://www.oracle.com"
                           expandable="expanded">
                     <nodes text="文庫"
                             destination="http://www.oracle.com"/>
                   </nodes>
                   <nodes text="フィクション"
                           destination="http://www.oracle.com"/>
                   <nodes text="ノンフィクション"
                           destination="http://www.oracle.com"/>
                 </nodes>
                 <nodes text="ハードウェア"
                         expandable="expanded" >
                   <nodes text="デスクトップ"
                           destination="http://www.oracle.com"/>
                   <nodes text="ノートブック"
                           destination="http://www.oracle.com"/>
                 </nodes>
               </nodes>
             </inline>
           </data>
         </provider>
       </dataScope>
     </contents>
   </body>
 </ctrl:content>

 <!-- UIX Controller -->
  <ctrl:handlers xmlns="http://xmlns.oracle.com/uix/controller">

   <event name="browse">
     <method class="oracle.cabo.doc.demo.DataTrees" method="browseEventHandler"/>
   </event>

 </ctrl:handlers>

</ctrl:page>

次に示すのは、この例を対話型にするJavaメソッドです。この後のBrowseMenuBeanの例では、必ずこのメソッドを使用します。最初のメソッドは、データのインライン・ツリーおよび位置を渡すことでBrowseNodeDataObjectのインスタンスを作成します。このメソッドが初めてコールされたとき、locationの値はnullで、0がデフォルトとして使用されます。0は、「店」ノードである最初のルートを示します。

  public static DataObject getBrowseNodeDataObject(
    RenderingContext context,
    String           namespace,
    String           name
    )
  {
    BajaContext bajaContext = BajaRenderingContext.getBajaContext(context);

    // get location property stored on context
    String location = (String) bajaContext.getProperty("browse", "location");

    // get inline data object
    DataObject data =
         context.getDataObject(UIConstants.MARLIN_NAMESPACE , "Nodes");

    if ( data == null )
      return null;

    // get tree roots
    DataObjectList tree = (DataObjectList) data.selectValue(context, "nodes");

    // if location is null the default of "0" is used
    return new BrowseNodeDataObject( tree, location);
  }

次のメソッドは、browseイベントがある場合にコールされます。locationパラメータ(UIConstants.LOCATION_PARAM)の値は、コンテキスト上のプロパティとして設定されます。このプロパティはその後、上のメソッドの中のBrowseNodeDataObjectコンストラクタに渡されます。


  public static EventResult browseEventHandler(
    BajaContext context,
    Page page,
    PageEvent event ) throws Throwable
  {
    String location = event.getParameter( UIConstants.LOCATION_PARAM );

    // set value on context as property
    context.setProperty( "browse", "location", location);

    EventResult result = new EventResult( page );
    return result;
  }

次の完全な例で、BrowseNodeDataObjectの残りのキーの使用方法を示します。その後で、BrowseMenuBeanBrowseNodeDataObjectに簡単に結び付けるユーティリティ・クラスを説明します。


<ctrl:page xmlns="http://xmlns.oracle.com/uix/ui"
  xmlns:ctrl="http://xmlns.oracle.com/uix/controller"
  xmlns:data="http://xmlns.oracle.com/uix/ui" >

 <ctrl:content xmlns:ui="http://xmlns.oracle.com/uix/ui">
   <body>
     <contents>

       <dataScope xmlns="http://xmlns.oracle.com/uix/ui">
         <contents>

           <!-- UIX Components -->
           <browseMenu id="myBrowseMenu"
                        data:title="text@data:browseData"
                        data:longDesc="description@data:browseData">
             <location>
               <breadCrumbs data:rendered="renderLocation@data:browseData">
                 <contents data:childData="locationData@data:browseData">
                   <link data:text="text" data:destination="destination"/>
                 </contents>
               </breadCrumbs>
             </location>
             <contentLink>
               <link data:text="destinationText@data:browseData"
                      data:destination="destination@data:browseData"
                      data:rendered="renderContentLink@data:browseData"/>
             </contentLink>
             <categories>
               <bulletedList data:rendered="renderCategories@data:browseData">
                 <contents data:childData="categoriesData@data:browseData">
                   <link data:text="text" data:destination="destination"/>
                 </contents>
               </bulletedList>
             </categories>
              <items>
               <bulletedList data:rendered="renderItems@data:browseData">
                 <contents data:childData="itemsData@data:browseData">
                   <link data:text="text" data:destination="destination"/>
                 </contents>
               </bulletedList>
             </items>
           </browseMenu>

         </contents>

         <!-- Data -->
         <provider>

           <data name="data:browseData">
             <method class="oracle.cabo.doc.demo.DataTrees" method="getBrowseNodeDataObject"/>
           </data>

           <data name="data:Nodes">
             <inline>
               <nodes text="店"
                       destination="http://www.oracle.com"
                       destinationText="詳細情報"
                       expandable="expanded">
                 <nodes text="本"
                         destination="http://www.oracle.com"
                         destinationText="詳細情報"
                         description="詳細情報:お買得、お買得、お買得!"
                         expandable="expanded">
                   <nodes text="セール"
                           destination="http://www.oracle.com"
                           expandable="expanded">
                     <nodes text="文庫"
                             destination="http://www.oracle.com"/>
                   </nodes>
                   <nodes text="フィクション"
                           destination="http://www.oracle.com"/>
                   <nodes text="ノンフィクション"
                           destination="http://www.oracle.com"/>
                 </nodes>
                 <nodes text="ハードウェア"
                         expandable="expanded" >
                   <nodes text="デスクトップ"
                           destination="http://www.oracle.com"/>
                   <nodes text="ノートブック"
                           destination="http://www.oracle.com"/>
                 </nodes>
               </nodes>
             </inline>
           </data>
         </provider>
       </dataScope>
     </contents>
   </body>
 </ctrl:content>

 <!-- UIX Controller -->
 <ctrl:handlers xmlns="http://xmlns.oracle.com/uix/controller">

   <event name="browse">
     <method class="oracle.cabo.doc.demo.DataTrees" method="browseEventHandler"/>
   </event>

 </ctrl:handlers>

</ctrl:page>

例を実行してポインタをリンクに合せると、ステータス・バーにリンク先が表示されます。前述の例では、ナビゲータおよび「カテゴリ」ヘッダーの下のリンクのリンク先には、BrowseNodeDataObjectコンストラクタに渡されるリンク先が含まれています。前述の名前と値のペアはこのリンクに追加されています。データ・ツリーにリンク先が指定されていない場合、context.getURLEncoder().getDefaultURL()をコールして返される値がデフォルトとして使用されます。このデフォルトのリンク先の例は、リンク先のないコンストラクタを使用した前述のgetBrowseNodeDataObjectメソッドを参照してください。

BrowseMenuのformSubmitted属性をtrueに設定すると、名前と値のペアがフォーム送信を介して返されます。フォーム送信を使用した例を次に示します。ナビゲータおよび「カテゴリ」ヘッダーの下のリンクをクリックすると、フォームを送信する関数がコールされます。

<ctrl:page xmlns="http://xmlns.oracle.com/uix/ui"
  xmlns:ctrl="http://xmlns.oracle.com/uix/controller"
  xmlns:data="http://xmlns.oracle.com/uix/ui" >

 <ctrl:content xmlns:ui="http://xmlns.oracle.com/uix/ui">
   <body>
     <contents>

       <dataScope xmlns="http://xmlns.oracle.com/uix/ui">
         <contents>

           <!-- UIX Components -->

            <form name="myForm">
             <contents>

               <browseMenu id="myBrowseMenu"
                            data:title="text@data:browseData"
                            data:longDesc="description@data:browseData"
                            formSubmitted="true"
                            formName="myForm">
                 <location>
                   <breadCrumbs data:rendered="renderLocation@data:browseData">
                     <contents data:childData="locationData@data:browseData">
                       <link data:text="text" data:destination="destination"/>
                     </contents>
                   </breadCrumbs>
                 </location>
                 <contentLink>
                   <link data:text="destinationText@data:browseData"
                          data:destination="destination@data:browseData"
                          data:rendered="renderContentLink@data:browseData"/>
                 </contentLink>
                 <categories>
                   <bulletedList data:rendered="renderCategories@data:browseData">
                     <contents data:childData="categoriesData@data:browseData">
                       <link data:text="text" data:destination="destination"/>
                     </contents>
                   </bulletedList>
                 </categories>
                 <items>
                   <bulletedList data:rendered="renderItems@data:browseData">
                     <contents data:childData="itemsData@data:browseData">
                       <link data:text="text" data:destination="destination"/>
                     </contents>
                   </bulletedList>
                 </items>
               </browseMenu>

              </contents>
           </form>

         </contents>

         <!-- Data -->
         <provider>

           <data name="data:browseData">
             <method class="oracle.cabo.doc.demo.DataTrees" method="getBrowseNodeDataObject"/>
           </data>

           <data name="data:Nodes">
             <inline>
               <nodes text="店"
                       destination="http://www.oracle.com"
                       destinationText="詳細情報"
                       expandable="expanded">
                 <nodes text="本"
                         destination="http://www.oracle.com"
                         destinationText="詳細情報"
                         description="詳細情報:お買得、お買得、お買得!"
                         expandable="expanded">
                   <nodes text="セール"
                           destination="http://www.oracle.com"
                           expandable="expanded">
                     <nodes text="文庫"
                             destination="http://www.oracle.com"/>
                   </nodes>
                   <nodes text="フィクション"
                           destination="http://www.oracle.com"/>
                   <nodes text="ノンフィクション"
                           destination="http://www.oracle.com"/>
                 </nodes>
                 <nodes text="ハードウェア"
                         expandable="expanded" >
                   <nodes text="デスクトップ"
                           destination="http://www.oracle.com"/>
                   <nodes text="ノートブック"
                           destination="http://www.oracle.com"/>
                 </nodes>
                 </nodes>
               </nodes>
             </inline>
           </data>
         </provider>
       </dataScope>
     </contents>
   </body>
 </ctrl:content>

 <!-- UIX Controller -->
 <ctrl:handlers xmlns="http://xmlns.oracle.com/uix/controller">

   <event name="browse">
     <method class="oracle.cabo.doc.demo.DataTrees" method="browseEventHandler"/>
   </event>

 </ctrl:handlers>

</ctrl:page>

BrowseMenuUtils

BrowseMenuUtilsはユーティリティ・クラスで、location要素にbreadCrumbs、項目のリンクにbulletedListを使用してBLAFに適した形式でBrowseMenuBeanを設定するようなメソッドが含まれています。Javaでは、次のようなコードを作成します。

// create the browse menu
BrowseMenuBean browseMenu = new BrowseMenuBean();

// give it page-wide unique id - sent as value of 'source' parameter
browseMenu.setID("myBrowseMenu");

// not using form submission
browseMenu.setFormSubmitted(false);

// add the "default" containers
BrowseMenuUtils.configureBrowseMenu(NAMESPACEURI,  LOCALNAME, browseMenu);

NAMESPACEURIおよびLOCALNAMEは、ネームスペースおよびDataObjectの名前です。DataObjectはほとんどの場合、データがバインドされるBrowseNodeDataObjectです。

uiXMLでは、2つの追加属性を使用してこの機能にアクセスできます。defaultContents属性は、BrowseMenuがBLAFのデフォルトを使用し、BrowseMenuUtils.configureBrowseMenuがコールされることを示します。source属性は、BrowseMenuUtils.configureBrowseMenuメソッドに渡すコロン区切りのネームスペースおよび名前です。

<ctrl:page xmlns="http://xmlns.oracle.com/uix/ui"
  xmlns:ctrl="http://xmlns.oracle.com/uix/controller"
  xmlns:data="http://xmlns.oracle.com/uix/ui">

 <ctrl:content xmlns:ui="http://xmlns.oracle.com/uix/ui">
   <body>
     <contents>

       <dataScope xmlns="http://xmlns.oracle.com/uix/ui">
         <contents>

           <!-- UIX Components -->
           <form name="myForm">
             <contents>

               <browseMenu id="myBrowseMenu"
                            formSubmitted="true"
                            defaultContents="true"
                            source="data:browseData"/>

             </contents>
           </form>
         </contents>

         <!-- Data -->
         <provider>

           <data name="data:browseData">
             <method class="oracle.cabo.doc.demo.DataTrees" method="getBrowseNodeDataObject"/>
           </data>

           <data name="data:Nodes">
             <inline>
               <nodes text="店"
                       destination="http://www.oracle.com"
                       destinationText="詳細情報"
                       expandable="expanded">
                 <nodes text="本"
                         destination="http://www.oracle.com"
                         destinationText="詳細情報"
                         description="詳細情報:お買得、お買得、お買得!"
                         expandable="expanded">
                   <nodes text="セール"
                           destination="http://www.oracle.com"
                           expandable="expanded">
                     <nodes text="文庫"
                             destination="http://www.oracle.com"/>
                   </nodes>
                   <nodes text="フィクション"
                           destination="http://www.oracle.com"/>
                   <nodes text="ノンフィクション"
                           destination="http://www.oracle.com"/>
                 </nodes>
                 <nodes text="ハードウェア"
                         expandable="expanded" >
                   <nodes text="デスクトップ"
                           destination="http://www.oracle.com"/>
                   <nodes text="ノートブック"
                           destination="http://www.oracle.com"/>
                 </nodes>
               </nodes>
             </inline>
           </data>
         </provider>
       </dataScope>
     </contents>
   </body>
 </ctrl:content>

 <!-- UIX Controller -->
 <ctrl:handlers xmlns="http://xmlns.oracle.com/uix/controller">

   <event name="browse">
     <method class="oracle.cabo.doc.demo.DataTrees" method="browseEventHandler"/>
   </event>

 </ctrl:handlers>

</ctrl:page>

デフォルトを使用し、変更が必要な部分のみをオーバーライドできます。たとえば表を利用したレイアウトで項目を表示し、カテゴリおよび項目のヘッダーのテキストは変更して、それ以外はデフォルトを使用する場合を想定します。上の例に示したようにdefaultContents属性およびsource属性を設定しますが、変更する値も設定する必要があります。この場合はcategoryTitle属性およびitemTitle属性を設定し、itemsという子を適切にバインドされたデータで設定します。次に例を示します。

<ctrl:page xmlns="http://xmlns.oracle.com/uix/ui"
  xmlns:ctrl="http://xmlns.oracle.com/uix/controller"
  xmlns:data="http://xmlns.oracle.com/uix/ui">

 <ctrl:content xmlns:ui="http://xmlns.oracle.com/uix/ui">
   <body>
     <contents>

       <dataScope xmlns="http://xmlns.oracle.com/uix/ui">
         <contents>

           <!-- UIX Components -->
           <form name="myForm">
             <contents>

               <browseMenu id="myBrowseMenu"
                            formSubmitted="true"
                            defaultContents="true"
                            source="data:browseData"
                            categoryTitle="Have Subcategories"
                            itemTitle="No Subcategories">
                  <items>
                   <table data:tableData="itemsData@data:browseData"
                           data:rendered="renderItems@data:browseData">
                     <contents>
                       <button data:text="text" data:destination="destination"/>
                       <text data:text="definition"/>
                     </contents>
                   </table>
                 </items>
               </browseMenu>
             </contents>
           </form>
         </contents>

         <!-- Data -->
         <provider>

           <data name="data:browseData">
             <method class="oracle.cabo.doc.demo.DataTrees" method="getBrowseNodeDataObject"/>
           </data>

           <data name="data:Nodes">
             <inline>
               <nodes text="店"
                       destination="http://www.oracle.com"
                       destinationText="詳細情報"
                       expandable="expanded">
                 <nodes text="本"
                         destination="http://www.oracle.com"
                         destinationText="詳細情報"
                         description="詳細情報:お買得、お買得、お買得!"
                         expandable="expanded">
                   <nodes text="セール"
                           destination="http://www.oracle.com"
                           expandable="expanded">
                     <nodes text="文庫"
                             destination="http://www.oracle.com"
                             definition="The madness of 1000 years"/>
                   </nodes>
                   <nodes text="フィクション"
                           destination="http://www.oracle.com"
                           definition="Fiction is fantasy"/>
                   <nodes text="nonfiction"
                           destination="http://www.oracle.com"
                           definition="nonfiction is true"/>
                 </nodes>
                 <nodes text="ハードウェア"
                         expandable="expanded" >
                   <nodes text="デスクトップ"
                           destination="http://www.oracle.com"
                           definition="Desktops aren't portable"/>
                   <nodes text="ノートブック"
                           destination="http://www.oracle.com"
                           definition="NoteBooks fit in your lap"/>
                 </nodes>
               </nodes>
             </inline>
           </data>
         </provider>
       </dataScope>
     </contents>
   </body>
 </ctrl:content>

 <!-- UIX Controller -->
 <ctrl:handlers xmlns="http://xmlns.oracle.com/uix/controller">

   <event name="browse">
     <method class="oracle.cabo.doc.demo.DataTrees" method="browseEventHandler"/>
   </event>

 </ctrl:handlers>

</ctrl:page>

DataObjectBrowseNodeDataObjectでは不要なキーと値のペアを追加し、これらの値を表で使用していることに注意してください。

HGridBean

HGridBeanは、ツリー構造のデータを表示する別の方法です。このBeanはTreeBeanおよびTableBeanの結合体で、TableBeanの形式を使用するとともにTreeBeanの機能を実装(および拡張)します。TreeBeanを開くおよび閉じる機能に加えて、HGridでは、ユーザーがサブツリーの内外にフォーカスを移動できるズーム・インおよびズーム・アウト機能をサポートしています。HGridとツリーの重要な違いは、ツリーでは複数のルートをサポートできるのに対し、HGridでサポートできるルートは1つのみという点です。HGridの説明を読み進める前に、「表」を読むことをお薦めします。

HGridの例を図15-5に示します。

図15-5: HGrid

HGrid

図15-5に示したHGridのそれぞれの部分は、次のリストのとおりです。リストの番号は、図に示した番号に対応しています。

  1. ナビゲータ
  2. フォーカス・アイコン
  3. 閉じているノードを示す矢印
  4. 開いているノードを示す矢印
  5. フォーカス列
  6. オブジェクト階層列

この例では、番号6のオブジェクト階層列にツリー・ノードが表示されています。この列の矢印(番号3および4)をクリックすると、対応するツリー・ノードが開いたり閉じたりします。ツリー全体はノード「すべての色」をルートとしていますが、HGridではノード「主要な色」をルートとするサブツリーにフォーカスが当たっています。番号5のフォーカス列で番号2のフォーカス・アイコンをクリックすると、ユーザーはサブツリーのズームを継続できます。番号1のナビゲータ領域には、現在フォーカスが当たっているルートの親ノードすべてが表示されます。これらのリンクをクリックすると、ユーザーは親レベルにズーム・アウトできます。(コントロール・バーの下にある)「すべて展開」リンクおよび「すべて閉じる」リンクをクリックすると、ユーザーは現在フォーカスが当たっているルートの下にあるツリー・ノードすべてを一度に開いたり閉じたりできます。

HGridの名前の付けられた子

uiXMLのキー UIConstant 説明
nodeStamp NODE_STAMP_CHILD オブジェクト階層列のヘッダーをカスタマイズできます。オブジェクト階層列自体をカスタマイズするスタンプとしても使用できます。
columnHeaderStamp COLUMN_HEADER_STAMP_CHILD ユーザー定義の列ヘッダーをすべてスタンプする際に使用します。
tableSelection TABLE_SELECTION_CHILD HGridで選択を実装する際に使用します。

HGridの属性

uiXMLのキー UIConstant 説明
id ID_ATTR String ページ全体で一意のID。
treeData TREE_DATA_ATTR DataObject HGridで表示されるツリーのルート。
proxy PROXY_ATTR HGridDataProxy プロキシは、ツリーを開く/閉じる際のイベントのリンク先、フォーカスを当てる際のイベントのリンク先を設定し、HGridのツリー状態やフォーカスの状態を管理します。
columnHeaderData COLUMN_HEADER_DATA_ATTR DataObjectList columnHeaderStampで列ヘッダーをスタンプする際に使用するデータ。
formSubmitted FORM_SUBMITTED_ATTR Boolean フォーム送信を使用するかどうかを設定します。フォーム送信はデフォルトではありません。したがってフォーム送信が必要な場合は、この属性を明示的にtrueに設定してください。

この表には、HGridBeanの重要な名前の付けられた子および属性の一部をリスト表示しました。HGridプロパティの完全なリストは、uiXML要素のドキュメントでhGrid(またはJavadocのHGridBean)を参照してください。

次に単純なHGridの例を示します。この例は、「主要な色」というルート・ノードのあるツリーを表示します。データ・プロバイダの部分はツリー用のコードと非常に似ています。表示されるHGridは対話型ではありません(プロキシのないツリーと同じです)。

<dataScope>
 <contents>
  <hGrid id="hg1" data:treeData="nodes@treeData"/>
 </contents>
 <provider>
  <data name="treeData">
   <inline>
    <nodes text="主要な色" expandable="expanded">
     <nodes text="赤色"/>
     <nodes text="緑色" expandable="expanded">
      <nodes text="薄い"/>
      <nodes text="濃い"/>
     </nodes>
     <nodes text="青色"/>
    </nodes>
   </inline>
  </data>
 </provider>
</dataScope>

この単純な例には、HGridがツリーより優れている点が示されていません。HGridの優れた視覚効果は、次の例で示すように、表の書式設定プロパティを使用して初めてわかります。

<dataScope>
 <contents>
  <hGrid id="hg1" data:treeData="nodes@treeData">
   <tableSelection>
    <multipleSelection text="選択して ...">
     <contents>
      <button text="コピー"/>
     </contents>
    </multipleSelection>
   </tableSelection>
   <columnHeaderData>
    <col text="赤色コード"/>
    <col text="緑色コード"/>
    <col text="青色コード"/>
   </columnHeaderData>
   <columnHeaderStamp>
    <text data:text="text"/>
   </columnHeaderStamp>
   <columnFormats>
    <col columnDataFormat="numberFormat"/>
    <col columnDataFormat="numberFormat"/>
    <col columnDataFormat="numberFormat"/>
   </columnFormats>
   <contents>
    <text data:text="r"/>
    <text data:text="g"/>
    <text data:text="b"/>
   </contents>
  </hGrid>
 </contents>
 <provider>
  <data name="treeData">
   <inline>
    <nodes text="主要な色" expandable="expanded">
     <nodes text="赤色" r="Any" g="00" b="00" />
     <nodes text="緑色" r="00" g="Any" b="00" expandable="expanded">
      <nodes text="薄い" r="00" g="FF" b="00" />
      <nodes text="濃い" r="00" g="88" b="00" />
     </nodes>
     <nodes text="青色" r="00" g="00" b="Any"/>
    </nodes>
   </inline>
  </data>
 </provider>
</dataScope>

上の例では、HGridの列ヘッダーはcolumnHeaderDataおよびcolumnHeaderStamp、列書式はcolumnFormats、選択はtableSelectionを使用して設定し、MultipleSelectionBeanで実装しています。これらの書式設定オプションの詳細は、「表」のトピックを参照してください。「表」のトピックでは、HGridにも関連する列バンドまたはグリッドのカスタマイズなど、その他の書式設定オプションも説明しています。ただし、表でサポートされる行のカスタマイズは、HGridではいずれもサポートされません。表のデータ・ナビゲーションやディテール公開もサポートされません。

NodeStamp

HGridのnodeStampという子を使用するとオブジェクト階層列をカスタマイズできます。この列のヘッダーおよびデータの両面でカスタマイズ可能です。HGridではオブジェクト階層列にデフォルトの列ヘッダーが使用されるので注意してください。このデフォルトのヘッダーは「Name」です。これは、次の例のようにColumnBeanをHGridのnodeStampとして使用すると、簡単にカスタマイズできます。

<hGrid ... >
 <nodeStamp>
  <column>
   <columnHeader>
     色
   </columnHeader>
  </column>
 </nodeStamp>
 ...
</hGrid>

次の例では、nodeStampを使用してオブジェクト階層列のカスタム要素を表示しています。

<hGrid ... >
 <nodeStamp>
  <column>
    ...
   <contents>
    <flowLayout>
     <contents>
      <messagePrompt messageType="info"/>
      <text data:text="text"/>
     </contents>
    </flowLayout>
   </contents>
  </column>
 </nodeStamp>
 ...
</hgrid>

HGridDataProxy

これまでの例のHGridはすべて静的(非対話型)でした。HGridを対話型にするには、HGridDataProxyを使用する必要があります(プロキシの概念は、TreeBeanのセクションで説明済です)。プロキシは、開く、閉じる、フォーカスを当てるためのリンクの処理、およびナビゲータのリンクの処理をHGridで行う場合に必須です。HGridを対話型にするには、プロキシで要求にまたがってHGridの状態を保持する必要があります。oracle.cabo.ui.data.tree.ClientStateHGridDataProxyは、URLをエンコードすることでクライアント側の状態を保持するプロキシのインスタンスです。次に、UIX Controllerのイベント・ハンドラでClientStateHGridDataProxyを作成し、プロキシをEventResultに格納する例を示します(イベント・ハンドラの詳細は、「UIX Controllerの概要」のトピックを参照してください)。

package oracle.cabo.doc.demo;
public class HGridDemo
{
  public static EventResult doHGridEvent(BajaContext bc, Page page,
                                         PageEvent event)
  {
    HGridDataProxy hGridProxy = new ClientStateHGridDataProxy();
    EventResult result = new EventResult(page);
    result.setProperty("hGridProxy", hGridProxy);
    return result;
  }
}

このコードをコールするには、次に示すように、このメソッドをuiXMLファイルでデフォルトのイベント・ハンドラとして登録する必要があります。


<handlers>
 <event name="*">
  <method class="oracle.cabo.doc.demo.HGridDemo"
     method="doHGridEvent"/>
 </event>
</handlers>

イベント・ハンドラで作成され、EventResultに格納されたプロキシは、HGridのproxy属性にデータ・バインドする必要もあります。次の例にこのプロセスを示します。

<hGrid id="hg1" data:treeData="nodes@treeData"
   data:proxy="hGridProxy@ctrl:eventResult">

これで、HGridの開く、閉じる、およびフォーカスを当てるためのリンクが使えるようになりました。ただし、これを実際に使用する前にいくつかの処理が必要です。ClientStateHGridDataProxyにより、サーバー側で処理する必要のある特定のUIX Controllerのイベントが生成されます。さらに、イベント・パラメータが4つ生成される場合もあります。次の表に、これらのイベント・パラメータを示します。

イベント・パラメータ 説明
uiXML UIConstant
source SOURCE_PARAM このイベントを生成したHGridのID。
state STATE_PARAM HGridが現在開いているか閉じているかを示す状態。
root ROOT_PARAM HGridで現在フォーカスが当たっているルートを示します。
node NODE_PARAM 開く、または閉じる必要のあるツリー・ノードを示します。

次の表には、ClientStateHGridDataProxyによって起動されるイベントを説明し、各イベントに付随するイベント・パラメータを示します。

イベント イベント・パラメータ 説明
uiXML UIConstant source state root node
focus FOCUS_EVENT X X X
HGridのフォーカスを変更します。
expand EXPAND_EVENT X X X X ツリー・ノードが開いたり閉じたりします。
expandAll EXPAND_ALL_EVENT X X X
現在フォーカスが当たっているルートの下のツリー・ノードすべてを再帰的に開きます。
collapseAll COLLAPSE_ALL_EVENT X X X
現在フォーカスが当たっているルートの下のツリー・ノードすべてを再帰的に閉じます。

この4つのイベントはサーバーで処理する必要があります。ClientStateHGridDataProxyは、それぞれのケースで作成される必要があります。これは単に、どのコンストラクタをコールするかという問題です。次のコードはHGridの各イベントの処理に使用します(コンストラクタの詳細は、JavadocのClientStateHGridDataProxyを参照してください)。

public static EventResult doHGridEvent(BajaContext bc, Page page,
                                       PageEvent event)
{
  HGridDataProxy hGridProxy;

  if (event!=null)
  {
    String state = event.getParameter(UIConstants.STATE_PARAM);
    String root = event.getParameter(UIConstants.ROOT_PARAM);
    String node = event.getParameter(UIConstants.NODE_PARAM);

    String eventName = event.getName();
    if (eventName.equals(UIConstants.COLLAPSE_ALL_EVENT))
    {
      hGridProxy = new ClientStateHGridDataProxy(state, root, false);
    }
    else if (eventName.equals(UIConstants.EXPAND_ALL_EVENT))
    {
      hGridProxy = new ClientStateHGridDataProxy(state, root, true);
    }
    else if (eventName.equals(UIConstants.FOCUS_EVENT))
    {
      hGridProxy = new ClientStateHGridDataProxy(state, root);
    }
    else // eventName.equals(UIConstants.EXPAND_EVENT)
    {
      hGridProxy = new ClientStateHGridDataProxy(state, root, node);
    }
  }
  else // there is no event. This is the initial state.
  {
    hGridProxy = new ClientStateHGridDataProxy();
  }

  // create an EventResult such that the current page is rendered again, in
  // response to the event
  EventResult result = new EventResult(page);
  // set the HGrid proxy as a property on the EventResult
  result.setProperty("hGridProxy", hGridProxy);
  return result;
}

HGridの「すべて展開」/「すべて閉じる」機能は、多くの場合で有用です。ただし非常に多くの項目が含まれるサブツリーで、「すべて展開」を使用すると、望ましくない結果になることがあります。そのため、ClientStateHGridDataProxyには、特定のノードで「すべて展開」/「すべて閉じる」機能を使用不可にする方法が用意されています。これは、キーClientStateHGridDataProxy.EXPAND_ALL_KEY(uiXMLではexpandAll)を利用します。このキーの値がBoolean.FALSE(uiXMLではfalse)の場合、そのツリー・ノードに対しては「すべて展開」/「すべて閉じる」のためのリンクは生成されません。

<data name="treeData">
<inline>
 <nodes text="すべての色" expandAll="false" expandable="collapsed">
   ...  <!-- lets say there are tons and tons of subnodes -->
 </nodes>
</inline>
</data>

ClientStateHGridDataProxy(int[] focusPath)コンストラクタを使用して、あるサブノード(リーフ・ノードを含む)で最初にフォーカスが当てられるHGridを作成することができます。intの配列は、フォーカスのあるサブノードへのパスです。ルートからフォーカス・ノードへのパスで、各要素は次のノードの(ゼロ・ベースの)子索引となります。最初の要素はルート・ノードの子索引で、パス上の次のノード、Aを生成します。次の要素はノードAの子索引で、ノードBを生成する、と続きます。たとえば、ルートの1番目の子の、3番目の子にフォーカスを当てるには次のようにします。

// Starting from the root, follow the first child (ie: index zero)
// and then follow the 3rd child (ie: index 2)
int[] focusPath = {0, 2};
hGridProxy = new ClientStateHGridDataProxy(focusPath);

HGridで表示されるツリーが小さいため、フォーカス機能が不必要な場合があります。フォーカス列(およびbreadcrumbs)をオフにするには、ClientStateHGridDataProxyインスタンスについてsetBreadCrumbsEnabled(false)をコールします。これは、HGridがルート上でフォーカスを当てられている(デフォルト・フォーカス)場合のみ実行できるので注意してください。HGridがサブノード上でフォーカスを当てられている場合は、breadcrumbsを使用不可にしないでください。これは、ユーザーにフォーカスを外す手段がなくなるためです(実際、このケースでbreadcrumbsを使用不可にすると例外がスローされます)。

HGridからデータを取得する方法の詳細は、「表」のトピックを参照してください。HGridは、表と同じメカニズムを使用します。これには、フォーム送信モードの使用、およびクライアント側の選択データの取得、サーバー側の選択データの取得が含まれます。

まとめ

このトピックでは、ツリー構造のデータについて説明し、UIXでこのようなツリーを作成する方法を説明しました。TreeBeanBrowseMenuBeanおよびHGridBeanなども紹介し、それらのツリー構造データの表示方法も示しました。最後に、これらのBeanおよびUIX Controllerを使用して対話型にする方法を説明しました。