Oracle ADF UIX Developer's Guide | ![]() Contents |
![]() Previous |
![]() Next |
The Oracle ADF UIX TreeBean
, BrowseMenuBean
and HGridBean
components allow users to browse through complex sets of hierarchical data. This chapter examines these three beans and provide extensive examples on
how to use them.
This chapter contains the following sections:
Some data is naturally tree structured. Consider, for example, the categories, subcategories and items in a shopping application. Let's start with an example of a small tree of data. The top node is "Shop," and under it are the nodes "Books" and "Hardware," which contain their own subnodes.
So what does a tree of data look like in UIX? Let's look at how to build such a tree in UIX XML. Each node in the tree is a DataObject
containing key-value pairs. We will often refer to a node by the value associated with the 'text' key. So we will refer to the root of the tree below as the "Shop" node. Note that UIX XML has some special syntax for creating a value that is a DataObjectList
. In the example below a node queried with the key 'nodes' will return a DataObjectList
containing its children. So for example when the "Shop" node is queried with the 'nodes' key a DataObjectList
containing the nodes "Books" and "Hardware" is returned.
Each DataObject
in the tree may contain any set of key-value pairs. We shall see a little later that certain keys have special meaning. For now let's take the example above and write it in UIX XML, with the addition of some seemingly arbitrary key-value pairs.
<nodes text="Shop"
destination="http://www.oracle.com"
destinationText="More Information"
expandable="expanded">
<nodes text="Books"
destination="http://www.oracle.com"
destinationText="More Information"
description="Instructions: buy, buy, buy!"
expandable="expanded">
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Paperbacks"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"/>
<nodes text="Nonfiction"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Hardware"
expandable="expanded" >
<nodes text="Desktops"
destination="http://www.oracle.com"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"/>
</nodes>
</nodes>
The TreeBean
and BrowseMenuBean
are the UIX Components designed to view such tree-structured data. In fact these two beans can show two different views of the same data source. Let's look at an example of how each bean displays the same data. First let's look at an image of how the above data is viewed in a TreeBean
.
Now let's look at an image of the same data displayed in a BrowseMenuBean
when the user is looking at the "Books" node.
Both beans allow the user to navigate through the tree hierarchy. The hierarchy of the data as displayed by the TreeBean
should be fairly obvious. In the BrowseMenuBean
the entire hierarchy is not seen, however the user can see the path from the root to the current node in the breadcrumbs at the top. The user can also see the children of the current node as links under the "Categories" and "Items" headers. Links under the "Categories" header are non-leaf nodes, while links under the "Items" header are leaf nodes. Thus when we are looking at the "Books" node we see that the path from the root is "Shop> Books". We also see that the children of "Books" are "Sale", "Fiction", and "Nonfiction" and that the nodes "Fiction" and "Nonfiction" are leaves, while the "Sale" node is not a leaf. Clicking on the links in the breadcrumbs or the links under the header "Categories" should bring the user to a similar page. For example if we clicked on the link that says "Sale" we should see a similar page with the breadcrumbs "Shop> Books> Sale" at the top and the link "Paperbacks" under the "Items" header. Later we will see an interactive version of this example.
Looking at the data we see that in the "Books" node the value associated with the 'description' key is "Instructions: buy, buy, buy!". Looking at the images we see that this text is displayed by the BrowseMenuBean
but not by the TreeBean
. Indeed, the TreeBean
ignores the value for the 'description' key. Similarly the BrowseMenuBean
ignores the value associated with the 'expandable' key, while the TreeBean
uses this information to determine whether the children of a node should be displayed. We will discuss the exact keys expected by both beans extensively in later sections.
We will begin with a discussion of the TreeBean
.
The TreeBean
supports the following named child:
UIX XML Key | UIConstant | Description |
---|---|---|
nodeStamp |
NODE_STAMP_CHILD |
Bean to render once for each |
The TreeBean
supports the following attributes:
UIX XML Key | UIConstant | Type | Description |
---|---|---|---|
id |
ID_ATTR |
String |
A page-wide unique id. |
formName |
FORM_NAME_ATTR |
String |
The name of the form to submit. |
formSubmitted |
FORM_SUBMITTED_ATTR |
Boolean |
Whether or not to use form submission. Form submission is not the default, thus if form submission is desired then this attribute must be explicitly set to true. |
The TreeBean
supports the following children which have a special attribute syntax. When used with the attribute syntax they must be databound.
UIX XML Key | UIConstant | Type | Description |
---|---|---|---|
nodes |
NODES_ATTR |
DataObjectList |
The tree of data. This |
proxy |
PROXY_ATTR |
TreeDataProxy |
The proxy keeps track of the expanded/collapsed state of the tree by setting up the expand and collapse destinations. It optionally tracks the currently selected node in the tree. |
Let's start with a look at the most basic tree.
In this example and those that follow some of the actual UIX is left out in order to focus attention on the issue at hand, however the examples themselves have a link to view the full source.
<tree/>
This example is so basic you don't see a thing. In it, we've only declared that we want to show a tree element, however in order to display something we need to add some data.
The tree data is set with the NODES
attribute.
Not surprisingly, the data for a TreeBean
is itself in tree form. The nodes in this tree of data are DataObject
s. Each DataObject
is expected to store certain data at specific keys. The following table describes the key-value pairs expected in each DataObject
.
UIX XML Key | UIConstant | Type | Description |
---|---|---|---|
text |
TEXT_KEY |
String |
The text displayed for the node. |
icon |
ICON_KEY |
String |
The URI of the icon to display for the node. The image file should be 16 pixels wide and 22 pixels high. The defaults are that no icon is rendered for leaf nodes, and a default folder icon is rendered for nodes with children. |
selected |
SELECTED_KEY |
Boolean |
This is set to true for nodes to be drawn as selected. |
destination |
DESTINATION_KEY |
String |
The URI to go to when the text is clicked. |
targetFrame |
TARGET_FRAME_KEY |
String |
The target frame for the destination. |
expandable |
EXPANDABLE_KEY |
String |
Used to determine if node is expanded, collapsed, or leaf. The possible values are:
|
collapseDestination |
COLLAPSE_DESTINATION_KEY |
String |
The URI used to collapse the node when it's currently expanded. |
expandDestination |
EXPAND_DESTINATION_KEY |
String |
The URI used to expand the node when it's currently collapsed. |
nodes |
NODES_KEY |
DataObjectList |
The children of the node. |
Now let's take a look at how to create tree data. The next section describes how to create tree data inline in the UIX XML. The section following that describes how to create the data in Java.
Here's an example which adds some tree data. The tree data is created inline in the UIX XML:
<page xmlns="http://xmlns.oracle.com/uix/ui"
xmlns:data="http://xmlns.oracle.com/uix/ui"
expressionLanguage="el" >
<content>
<dataScope>
<contents>
<!-- UIX Components -->
<form name="myForm" >
<contents>
<tree nodes="${data:data().Nodes.nodes}" />
</contents>
</form>
</contents>
<!-- Data -->
<provider>
<data name="data:Nodes">
<inline>
<nodes text="Shop"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Books"
destination="http://www.oracle.com"
expandable="collapsed">
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="collapsed">
<nodes text="Paperbacks"
expandable="no"
destination="http://www.oracle.com" />
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"
expandable="no"/>
<nodes text="Nonfiction"
destination="http://www.oracle.com"
expandable="no"/>
</nodes>
<nodes text="Hardware"
expandable="collapsed">
<nodes text="Desktops"
destination="http://www.oracle.com"
expandable="no"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"/>
</nodes>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</content>
</page>
The example above should start to clarify the link between the key-value pairs on the DataObject
s and how these are displayed by the tree. The value returned by the "text"
key is displayed as the text for the node. The nodes "Shop" and "Books" are links because we have set a value for the "destination"
key, while we have not done so for "Hardware" and so this node is therefore not clickable. The value returned by the "expandable"
key determines whether or not the children are visible. Thus the children of "Shop" are visible while those for "Books" are not.
You might wonder why nothing happens when you click on the plus and minus icons. The TreeBean
itself only renders the tree as indicated by the key-value pairs on each DataObject
, it does not handle making the tree interactive. Remember, the TreeBean
is a UIX Component; it is meant to take its children and attributes and output the appropriate content for one render, or one pass through the bean. To make it interactive we need something to handle the flow from one state to another. This can be accomplished with the UIX Servlet, for example, or a servlet that you write. We have provided a class to simplify making the tree interactive, which will be discussed below. First, however, we will discuss how to influence the way the tree looks.
Now let's change a few "collapsed" values to "expanded" and look at the difference.
<page xmlns="http://xmlns.oracle.com/uix/ui"
xmlns:data="http://xmlns.oracle.com/uix/ui"
expressionLanguage="el" >
<content>
<dataScope>
<contents>
<!-- UIX Components -->
<form name="myForm" >
<contents>
<tree nodes="${data:data().Nodes.nodes}" />
</contents>
</form>
</contents>
<!-- Data -->
<provider>
<data name="data:Nodes">
<inline>
<nodes text="Shop"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Books"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Paperbacks"
expandable="no"
destination="http://www.oracle.com" />
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"
expandable="no"/>
<nodes text="Nonfiction"
destination="http://www.oracle.com"
expandable="no"/>
</nodes>
<nodes text="Hardware"
expandable="expanded">
<nodes text="Desktops"
destination="http://www.oracle.com"
expandable="no"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"
expandable="no"/>
</nodes>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</content>
</page>
Note that the default is expanded="no" so you can leave off this key-value pair for leaves. If you leave it off for non-leaf items or put "no" as the value then the icon indicating +/- is missing. Note that on the "Shop" node there is no expandable key and the icon is removed. Note also that the "Hardware" node has the "expandable" key set to "no" despite it's not being a leaf, and the icon is removed.
<page xmlns="http://xmlns.oracle.com/uix/ui"
xmlns:data="http://xmlns.oracle.com/uix/ui"
expressionLanguage="el" >
<content>
<dataScope>
<contents>
<!-- UIX Components -->
<form name="myForm" >
<contents>
<tree nodes="${data:data().Nodes.nodes}" />
</contents>
</form>
</contents>
<!-- Data -->
<provider>
<data name="data:Nodes">
<inline>
<!-- "expandable" key removed -->
<nodes text="Shop"
destination="http://www.oracle.com" >
<nodes text="Books"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Paperbacks"
destination="http://www.oracle.com" />
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"/>
<nodes text="Nonfiction"
destination="http://www.oracle.com"/>
</nodes>
<!-- "expandable" changed to "no" -->
<nodes text="Hardware"
expandable="no" >
<nodes text="Desktops"
destination="http://www.oracle.com"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"/>
</nodes>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</content>
</page>
You can also set nodes to look selected by setting the value for the "selected"
key to true. In the following example "Shop" and "Sale" are highlighted with a blue background and white text.
<page xmlns="http://xmlns.oracle.com/uix/ui"
xmlns:data="http://xmlns.oracle.com/uix/ui"
expressionLanguage="el" >
<content>
<dataScope>
<contents>
<!-- UIX Components -->
<form name="myForm" >
<contents>
<tree nodes="${data:data().Nodes.nodes}" />
</contents>
</form>
</contents>
<!-- Data -->
<provider>
<data name="data:Nodes">
<inline>
<nodes text="Shop"
destination="http://www.oracle.com"
expandable="expanded"
selected="true">
<nodes text="Books"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="expanded"
selected="true">
<nodes text="Paperbacks"
destination="http://www.oracle.com" />
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"/>
<nodes text="Nonfiction"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Hardware"
expandable="expanded" >
<nodes text="Desktops"
destination="http://www.oracle.com"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"/>
</nodes>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</content>
</page>
By default nodes with children will render with a folder icon. You can add icons to leaves or replace the folder icon by setting the value for the "icon"
key to the URI of another image. Let's look at an example:
<page xmlns="http://xmlns.oracle.com/uix/ui"
xmlns:data="http://xmlns.oracle.com/uix/ui"
expressionLanguage="el" >
<content>
<dataScope>
<contents>
<!-- UIX Components -->
<form name="myForm" >
<contents>
<tree nodes="${data:data().Nodes.nodes}" />
</contents>
</form>
</contents>
<!-- Data -->
<provider>
<data name="data:Nodes">
<inline>
<nodes text="Shop"
destination="http://www.oracle.com"
expandable="expanded"
icon="/docs/devguide/images/data_trees/info.gif">
<nodes text="Books"
destination="http://www.oracle.com"
expandable="expanded"
icon="/docs/devguide/images/data_trees/info.gif">
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="expanded"
icon="/docs/devguide/images/data_trees/info.gif">
<nodes text="Paperbacks"
destination="http://www.oracle.com" />
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"/>
<nodes text="Nonfiction"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Hardware"
expandable="expanded"
icon="/docs/devguide/images/data_trees/info.gif">
<nodes text="Desktops"
destination="http://www.oracle.com"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"/>
</nodes>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</content>
</page>
Now that we have seen how to create tree data in UIX XML, let's see how it can
be done in Java. Ideally, application developers should write a class that
extends oracle.cabo.ui.data.DataObject
and recognizes the keys
listed in Tree Data. UIX provides a simple
implementation of this class called
oracle.cabo.ui.data.tree.SimpleTreeData
, which implements a
single tree node. The following method creates a single tree node:
/**
* @param text the text label of the tree node
* @param expandable one of UIConstants.EXPANDABLE_NO,
* UIConstants.EXPANDABLE_EXPANDED, UIConstants.EXPANDABLE_COLLAPSED.
* @param isSelected true if this node is initially selected.
*/
private static SimpleTreeData createNode(String text, String expandable
boolean isSelected)
{
SimpleTreeData data = new SimpleTreeData();
data.setText(text);
data.setDestination( "http://www.oracle.com");
data.setExpandable(expandable);
data.setSelected(isSelected);
return data;
}
To create a tree, individual nodes must be added as children of other nodes. The following example creates the tree that we built in Example B-2-5:
public static DataObject getTreeData(RenderingContext context,
String namespace, String name)
{
SimpleTreeData shop = createNode("Shop", UIConstants.EXPANDABLE_EXPANDED,
true);
SimpleTreeData books = createNode("Books", UIConstants.EXPANDABLE_EXPANDED,
false);
SimpleTreeData sale = createNode("Sale", UIConstants.EXPANDABLE_EXPANDED,
true);
SimpleTreeData pbacks = createNode("Paperbacks", UIConstants.EXPANDABLE_NO,
false);
sale.addChild(pbacks);
books.addChild(sale);
SimpleTreeData fic = createNode("Fiction", UIConstants.EXPANDABLE_NO,
false);
books.addChild(fic);
SimpleTreeData nonfic = createNode("Nonfiction", UIConstants.EXPANDABLE_NO,
false);
books.addChild(nonfic);
shop.addChild(books);
SimpleTreeData hw = createNode("Hardware", UIConstants.EXPANDABLE_EXPANDED,
false);
SimpleTreeData desktops = createNode("Desktops", UIConstants.EXPANDABLE_NO,
false);
hw.addChild(desktops);
SimpleTreeData nbks = createNode("Notebooks", UIConstants.EXPANDABLE_NO,
false);
hw.addChild(nbks);
shop.addChild(hw);
return shop;
}
We need to databind the tree
element's nodes
attribute to the tree data produced by the above method:
<dataScope>
<contents>
...
<!-- Since our data provider returns the root of the tree,
we do not need the 'nodes' parameter in front of
the 'demo:Nodes' -->
<tree data:nodes="@data:Nodes" ../>
...
</contents>
<provider>
<data name="data:Nodes">
<method class="MyDemoClass" method="getTreeData"/>
</data>
</provider>
</dataScope>
For more details, please see the JavaDoc for the SimpleTreeData
class.
By default a link is displayed for each node in the tree, but setting the "nodeStamp"
allows you more control over what is displayed. The "nodeStamp"
is a named child of the TreeBean
.
What is a stamp? A stamp is just a UINode -- any UINode -- that is rendered more than once on a given page. In the tree there is one stamp and this stamp is repeated, or rendered once for each node in the tree. This means each node looks similar, but can have different data through data binding. The following example uses a node stamp. Notice that we can add arbitrary key-value pairs into the DataObject
s in the tree and then use data binding to extract these values.
<page xmlns="http://xmlns.oracle.com/uix/ui"
xmlns:data="http://xmlns.oracle.com/uix/ui"
expressionLanguage="el" >
<content>
<dataScope>
<contents>
<!-- UIX Components -->
<form name="myForm" >
<contents>
<tree nodes="${data:data().Nodes.nodes}">
<nodeStamp>
<flowLayout>
<contents>
<checkBox rendered="${uix.current.rendered}"
disabled="${uix.current.disabled}"
checked="${uix.current.checked}"/>
<styledText text="${uix.current.text}" />
</contents>
</flowLayout>
</nodeStamp>
</tree>
</contents>
</form>
</contents>
<!-- Data -->
<provider>
<data name="data:Nodes">
<inline>
<nodes text="Shop"
destination="http://www.oracle.com"
expandable="expanded"
rendered="false"
icon="/docs/devguide/images/data_trees/info.gif">
<nodes text="Books"
destination="http://www.oracle.com"
expandable="expanded"
rendered="false"
icon="/docs/devguide/images/data_trees/info.gif">
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="expanded"
rendered="false"
icon="/docs/devguide/images/data_trees/info.gif">
<nodes text="Paperbacks"
destination="http://www.oracle.com"
disabled="true" />
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"
checked="true"/>
<nodes text="Nonfiction"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Hardware"
expandable="expanded"
rendered="false"
icon="/docs/devguide/images/data_trees/info.gif">
<nodes text="Desktops"
destination="http://www.oracle.com"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"/>
</nodes>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</content>
</page>
Note that the height of the nodes cannot be arbitrarily large. Currently each node can be about 45 pixels high.
Now let's make the tree interactive. When a node is in the collapsed state, the value associated with the "expandDestination"
key is used as the destination to expand the node. When a node is in the expanded state, the value associated with the "collapseDestination"
key is used as the destination to collapse the node. Users setting these destinations themselves must keep track of the state of the tree, in other words which nodes are expanded/collapsed and which are selected.
In order to simplify using the tree, we have provided the class ClientStateTreeDataProxy
. This proxy keeps track of the expanded/collapsed state of the tree by setting up the expand and collapse destinations. The proxy to be used is set using the "proxy"
attribute.
When using the ClientStateTreeDataProxy
the state of the tree is kept on the client. The proxy sets the expand/collapse destinations such that the following name-value pairs are sent to the server when a node is expanded or collapsed.
The value of 'event' is the name of a UIX Servlet event. Note that the value is 'expand' whether or not a node is being expanded or collapsed.
The value of 'source' is the value set for the ID
attribute. We have not yet used the ID
attribute but we will include it in the next example.
The values associated with 'node', 'state', and 'selection' are used at the server to create a new proxy. Users do not need to worry about what these values actually are, they must only ask for the values and pass these values to the ClientStateTreeDataProxy
constructor. The example below should clarify this process.
If you set up the tree with the proper state and then use the ClientStateTreeDataProxy
constructor that takes null for the tree state, the proxy will attempt to pull the expanded/collapsed state from the node data. So, to have a tree opened up to a specific node by default, you need only set the nodes along the path to the root to be expanded. Again, the following examples should clarify how to use ClientStateTreeDataProxy
.
This example requires Java code. The Java follows the UIX example.
<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"
expressionLanguage="el">
<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"
nodes="${data:data().Nodes.nodes}"
proxy="${TreeProxy.proxy}"/>
</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="Shop"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Books"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Paperbacks"
destination="http://www.oracle.com" />
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"/>
<nodes text="Nonfiction"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Hardware"
expandable="expanded">
<nodes text="Desktops"
destination="http://www.oracle.com"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"/>
</nodes>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</contents>
</body>
</ctrl:content>
<!-- UIX Servlet -->
<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>
The following are the two methods in bold above. All subsequent TreeBean
examples use these same methods. The first method is the getTreeProxy
method which returns a DataObject
that returns a proxy.
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;
}
The expandEventHandler
method handles 'expand' events when they are generated. Note in expandEventHandler
you just pass the values associated with the parameters 'state'(UIConstants.STATE_PARAM)
, 'node'(UIConstants.NODE_PARAM)
, and 'selection'(UIConstants.SELECTION_PARAM)
to a new ClientStateTreeProxy
. This new proxy is set as a property on the context and is subsequently returned by the TreeProxyDataObject
created in the method above.
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 will be handled by the proxy if the constructor that takes a selection parameter is used. Currently the proxy only supports single selection. A node will remain selected (until a new selection is made) even if it is not visible. The selection state is handled through an onClick handler. Let's look at an example that uses a node stamp. Notice that the background and text change color as a node's check box is clicked.
SELECTION IS NOT AVAILABLE ON NETSCAPE WHEN USING A PROXY.
<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"
expressionLanguage="el">
<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"
nodes="${data:data().Nodes.nodes}"
proxy="${TreeProxy.proxy}">
<nodeStamp>
<flowLayout>
<contents>
<checkBox rendered="${uix.current.rendered}"
disabled="${uix.current.disabled}"
checked="${uix.current.checked}"/>
<link destination="${uix.current.destination}" text="${uix.current.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="Shop"
destination="http://www.oracle.com"
expandable="expanded"
rendered="false"
icon="/docs/devguide/images/data_trees/info.gif" >
<nodes text="Books"
destination="http://www.oracle.com"
expandable="expanded"
rendered="false"
icon="/docs/devguide/images/data_trees/info.gif" >
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="expanded"
rendered="false"
icon="/docs/devguide/images/data_trees/info.gif">
<nodes text="Paperbacks"
destination="http://www.oracle.com"
disabled="true" />
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"
checked="true"/>
<nodes text="Nonfiction"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Hardware"
expandable="expanded"
rendered="false"
icon="/docs/devguide/images/data_trees/info.gif" >
<nodes text="Desktops"
destination="http://www.oracle.com"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"/>
</nodes>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</contents>
</body>
</ctrl:content>
<!-- UIX Servlet -->
<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>
Many developers will want to use frames with the TreeBean
. The following is an example of how to do just that. This involves three UIX XML files. The first sets up the frames.
<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>
The next is the tree itself with some new destinations and the addition of the "targetFrame"
key which specifies the frame to direct the content to.
<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"
expressionLanguage="el">
<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"
nodes="${data:data().Nodes.nodes}"
proxy="${TreeProxy.proxy}"/>
</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="Shop"
destination="http://otn.oracle.com/index.html"
targetFrame="contents"
expandable="expanded">
<nodes text="Books"
destination="http://www.osborne.com/oracle/"
targetFrame="contents"
expandable="expanded">
<nodes text="Sale"
destination="http://www.oracle.com"
targetFrame="contents"
expandable="expanded">
<nodes text="Paperbacks"
destination="http://www.oracle.com/appsnet/"
targetFrame="contents"/>
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com/oramag/"
targetFrame="contents"/>
<nodes text="Nonfiction"
destination="http://otn.oracle.com/support/content.html"
targetFrame="contents"/>
</nodes>
<nodes text="Hardware"
expandable="expanded" >
<nodes text="Desktops"
destination="http://otn.oracle.com/training/content.html"
targetFrame="contents"/>
<nodes text="Notebooks"
destination="http://otn.oracle.com/tech/content.html"
targetFrame="contents"/>
</nodes>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</contents>
</body>
</ctrl:content>
<!-- UIX Servlet -->
<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>
The last is an empty UIX XML file.
<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"/>
The BrowseMenuBean
provides another way to view hierarchical or tree-structured data.
The BrowseMenuBean
supports four named children:
UIX XML Key | UIConstant | Description |
---|---|---|
location |
LOCATION_CHILD |
Bean to use to render locator element on top of BrowseMenu. |
contentLink |
CONTENT_LINK_CHILD |
Bean to use to link to content of the current category. |
categories |
CATEGORIES_CHILD |
Bean to use to render categories. |
items |
ITEMS_CHILD |
Bean to use to render items. |
The BrowseMenuBean
is essentially a layout manager which places these named children at the appropriate locations. The Browser Look and Feel (BLAF) guidelines show a BreadCrumbsBean
as the location element, a LinkBean
as the content link element, a BulletedListBean
to display categories and another BulletedListBean
to display items.
The BrowseMenuBean
supports the following attributes:
UIX XML Key | UIConstant | Type | Description |
---|---|---|---|
id |
ID_ATTR |
String |
A page-wide unique id. |
title |
TITLE_ATTR |
String |
Sets the title of the BrowseMenu. This text will be displayed in the top header. If this attribute is not set the default text will be set to "Browse". |
categoryTitle |
CATEGORY_TITLE_ATTR |
String |
Sets the title of the category section. This text will be displayed in the header above the categories. If this attribute is not set the default text will be set to "Categories". |
itemTitle |
ITEM_TITLE_ATTR |
String |
Sets the title of the items section. This text will be displayed in the header above the items. If this attribute is not set the default text will be set to "Items". |
longDesc |
LONG_DESC_ATTR |
String |
Sets the description seen just under the title to describe the current location. If this attribute is not set the default text will be set to the empty string. |
formName |
FORM_NAME_ATTR |
String |
The name of the form to submit. |
formSubmitted |
FORM_SUBMITTED_ATTR |
Boolean |
Whether or not to use form submission. Form submission is not the default, thus if form submission is desired then this attribute must be explicitly set to true. |
Let's look at an image which may clarify how these named children and attributes are used.
We will start our BrowseMenuBean
discussion with some simple examples in which everything is hardcoded. We will provide more complicated examples below.
Note that the "View Source" link has been moved to the bottom of the page.
<browseMenu/>
This is the simplest example and all we see is a header with the text "Browse". In order to make this more interesting we need to add data.
First we will add a "categories"
child. The categories correspond to tree nodes that have children, or are not leaves.
<browseMenu>
<categories>
<bulletedList rows="10">
<contents>
<link text="Sale" destination="http://www.oracle.com"/>
</contents>
</bulletedList>
</categories>
</browseMenu>
You might remember that in the introduction we said that when you click on the "Sale" link we should see a similar page with the breadcrumbs "Shop> Books> Sale" at the top and the link "Paperbacks" under the "Items" header, however the sale link in the above example doesn't do this. Like the TreeBean
, the BrowseMenuBean
itself does not handle interactivity. Remember, the BrowseMenuBean
is a UIX Component; it is meant to take its children and attributes and output the appropriate content for one render, or one pass through the bean. To make it interactive we need something to handle the flow from one state to another. This can be accomplished with the UIX Servlet, for example, or a servlet that you write. We have provided a class to simplify making the BrowseMenuBean
interactive, which will be discussed below. First, however, we will discuss how to influence the way the BrowseMenuBean
looks.
To continue we will add an "items"
child. The items correspond to leaves in the tree.
<browseMenu>
<categories>
<bulletedList rows="10">
<contents>
<link text="Sale" destination="http://www.oracle.com"/>
</contents>
</bulletedList>
</categories>
<items>
<bulletedList rows="10">
<contents>
<link text="Fiction" destination="http://www.oracle.com"/>
<link text="Nonfiction" destination="http://www.oracle.com"/>
</contents>
</bulletedList>
</items>
</browseMenu>
Now we will add a "location"
child. This helps orient the user as to their location in the tree.
<browseMenu>
<location>
<breadCrumbs>
<contents>
<link text="Shop" destination="http://www.oracle.com"/>
<link text="Books" destination="http://www.oracle.com"/>
</contents>
</breadCrumbs>
</location>
<categories>
<bulletedList rows="10">
<contents>
<link text="Sale" destination="http://www.oracle.com"/>
</contents>
</bulletedList>
</categories>
<items>
<bulletedList rows="10">
<contents>
<link text="Fiction" destination="http://www.oracle.com"/>
<link text="Nonfiction" destination="http://www.oracle.com"/>
</contents>
</bulletedList>
</items>
</browseMenu>
Finally we will add a "contentLink"
child. The content link allows the user to access additional information/instructions.
<browseMenu>
<location>
<breadCrumbs>
<contents>
<link text="Shop" destination="http://www.oracle.com"/>
<link text="Books" destination="http://www.oracle.com"/>
</contents>
</breadCrumbs>
</location>
<contentLink>
<link text="More Information" destination="http://www.oracle.com"/>
</contentLink>
<categories>
<bulletedList rows="10">
<contents>
<link text="Sale" destination="http://www.oracle.com"/>
</contents>
</bulletedList>
</categories>
<items>
<bulletedList rows="10">
<contents>
<link text="Fiction" destination="http://www.oracle.com"/>
<link text="Nonfiction" destination="http://www.oracle.com"/>
</contents>
</bulletedList>
</items>
</browseMenu>
Now that we've seen the basic layout of the BrowseMenu let's take a look at the attributes.
First we will set the "title"
attribute, changing the title from "Browse" to "Books".
<browseMenu title="Books">
<location>
<breadCrumbs>
<contents>
<link text="Shop" destination="http://www.oracle.com"/>
<link text="Books" destination="http://www.oracle.com"/>
</contents>
</breadCrumbs>
</location>
<contentLink>
<link text="More Information" destination="http://www.oracle.com"/>
</contentLink>
<categories>
<bulletedList rows="10">
<contents>
<link text="Sale" destination="http://www.oracle.com"/>
</contents>
</bulletedList>
</categories>
<items>
<bulletedList rows="10">
<contents>
<link text="Fiction" destination="http://www.oracle.com"/>
<link text="Nonfiction" destination="http://www.oracle.com"/>
</contents>
</bulletedList>
</items>
</browseMenu>
Next we will set the "categoryTitle"
attribute, changing the text from "Categories" to "Have Subcategories". We will also set the "itemTitle"
attribute, changing the text from "Items" to "No Subcategories".
<browseMenu title="Books"
categoryTitle="Have Subcategories"
itemTitle="No Subcategories">
<location>
<breadCrumbs>
<contents>
<link text="Shop" destination="http://www.oracle.com"/>
<link text="Books" destination="http://www.oracle.com"/>
</contents>
</breadCrumbs>
</location>
<contentLink>
<link text="More Information" destination="http://www.oracle.com"/>
</contentLink>
<categories>
<bulletedList rows="10">
<contents>
<link text="Sale" destination="http://www.oracle.com"/>
</contents>
</bulletedList>
</categories>
<items>
<bulletedList rows="10">
<contents>
<link text="Fiction" destination="http://www.oracle.com"/>
<link text="Nonfiction" destination="http://www.oracle.com"/>
</contents>
</bulletedList>
</items>
</browseMenu>
Now we will set the "longDesc"
attribute. This area can be used for descriptions or instructions.
<browseMenu title="Books"
categoryTitle="Have Subcategories"
itemTitle="No Subcategories"
longDesc="Instructions: buy, buy, buy!">
<location>
<breadCrumbs>
<contents>
<link text="Shop" destination="http://www.oracle.com"/>
<link text="Books" destination="http://www.oracle.com"/>
</contents>
</breadCrumbs>
</location>
<contentLink>
<link text="More Information" destination="http://www.oracle.com"/>
</contentLink>
<categories>
<bulletedList rows="10">
<contents>
<link text="Sale" destination="http://www.oracle.com"/>
</contents>
</bulletedList>
</categories>
<items>
<bulletedList rows="10">
<contents>
<link text="Fiction" destination="http://www.oracle.com"/>
<link text="Nonfiction" destination="http://www.oracle.com"/>
</contents>
</bulletedList>
</items>
</browseMenu>
There are two final attributes, "formSubmitted"
and "formName"
. We will see the application of these attributes below.
So what happened to our tree-structured data? The next section discusses how to use a BrowseMenuBean
with tree-structured data.
While the purpose of the BrowseMenuBean
is to allow users to browse through complex sets of hierarchical objects, the hierarchical data isn't added to the BrowseMenu itself as it is for the TreeBean
. In fact the BrowseMenuBean
expects the named children and attributes to contain all the appropriate data. We provide a class to make binding this data relatively simple. BrowseNodeDataObject
takes a tree of DataObject
s and a current location and extracts the appropriate information. The "tree of DataObject
s" part should sound familiar. In fact an instance of BrowseNodeDataObject
can take the same tree of data used by a TreeBean
.
BrowseNodeDataObject
expects the nodes in the tree to use the following keys.
UIX XML Key | UIConstant | Type | Description |
---|---|---|---|
text |
TEXT_KEY |
String |
The text for the node. |
destination |
DESTINATION_KEY |
String |
The URI for a link. |
destinationText |
DESTINATION_TEXT_KEY |
String |
The text for a link. |
description |
DESCRIPTION_KEY |
String |
A description or instruction. |
nodes |
NODES_KEY |
DataObjectList |
The children of the node. |
Again, this should be familiar. There are two new keys. The value associated with the "description"
key is intended to map to the value of the "longDesc"
attribute.
The value of the "destinationText"
key is intended to be the text for the "contentLink"
child. In the TreeBean
if a node has a destination it can be displayed as a link, even if the node has children. For example looking at a tree example if we click on the text "Books" it is a link. In the BrowseMenu the text "Books" is in a header, and is not clickable. Thus a separate link is needed and this is the purpose of the "contentLink"
child.
Let's look at an updated version of the tree of data that uses these keys. Notice that it is fine for a DataObject
to include key-value pairs not needed by the BrowseMenu. For example, the BrowseMenu will ignore the "expanded"
key and its associated value.
<nodes text="Shop"
destination="http://www.oracle.com"
destinationText="More Information"
expandable="expanded">
<nodes text="Books"
destination="http://www.oracle.com"
destinationText="More Information"
description="Instructions: buy, buy, buy!"
expandable="expanded">
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Paperbacks"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"/>
<nodes text="Nonfiction"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Hardware"
expandable="expanded" >
<nodes text="Desktops"
destination="http://www.oracle.com"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"/>
</nodes>
</nodes>
The BrowseNodeDataObject
constructor takes a tree of data and the current location in the tree. From that it creates values for the following keys:
UIX XML Key | Java Key | Type | Description |
---|---|---|---|
locationData |
BrowseNodeDataObject. |
DataObjectList |
The nodes for the location child. These are all the nodes along the path from the root of the tree to the current location node. |
categoriesData |
BrowseNodeDataObject. |
DataObjectList |
The nodes for the categories child. These are all the children of the current location data object who have children themselves, or are not leaves in the tree. |
itemsData |
BrowseNodeDataObject. |
DataObjectList |
The nodes for the items child. These are all the children of the current location data object who do not have children themselves, or are leaves in the tree. |
renderLocation |
BrowseNodeDataObject. |
Boolean |
If the current location node is one of the 'roots' of the tree, this is set to |
renderContentLink |
BrowseNodeDataObject. |
Boolean |
If the current location node is queried with |
renderCategories |
BrowseNodeDataObject. |
Boolean |
If the current location node has no children who are categories, or internal nodes in the tree, this is set to |
renderItems |
BrowseNodeDataObject. |
Boolean |
If the current location node has no children who are items, or tree leaves, this is set to |
currentState |
BrowseNodeDataObject. |
String |
The current state of the browse menu as passed in to the constructor. |
So let's say the current location being viewed by the user is the "Books" node in the tree above. The keys above would return the following.
BrowseNodeDataObject.LOCATION_DATA_KEY
- A DataObjectList
containing the nodes "Shop" and "Books".
BrowseNodeDataObject.CATEGORIES_DATA_KEY
- A DataObjectList
containing "Sale".
BrowseNodeDataObject.ITEMS_DATA_KEY
- A DataObjectList
containing the nodes "Fiction" and "Nonfiction".
BrowseNodeDataObject.RENDER_LOCATION_KEY
- set to Boolean.TRUE
since "Books" is not one of the 'roots' - it is a child of "Shop".
BrowseNodeDataObject.RENDER_CONTENT_LINK_KEY
- set to Boolean.TRUE
since the "Books" node returns "more information" when queried with UIConstants.DESTINATION_TEXT_KEY
.
BrowseNodeDataObject.RENDER_CATEGORIES_KEY
- Set to Boolean.TRUE
since there are categories.
BrowseNodeDataObject.RENDER_ITEMS_KEY
- Set to Boolean.TRUE
since there are items.
BrowseNodeDataObject.CURRENT_STATE_KEY
- A String containing the state indicating we are looking at the "Books" node. In this case this string would be "0,0" since "Shop" is roots[0] and "Books" is its 0th child.
The "location" and "categories" data are DataObjectList
s where the destination on each DataObject
is retrieved with the key UIConstant.DESTINATION_KEY
. The destination is set such that if a location or categories element is pressed the following name-value pairs are returned to the server:
The value of 'event' is the name of a UIX Servlet event, which is 'browse' in this case.
The value of 'source' is the value set for the ID
attribute. We have not yet used the ID
attribute but we will include it in the next example.
The value associated with 'location' is used at the server to create a new BrowseNodeDataObject
. Users do not need to worry about what this value is, they must only ask for the value and pass this value to the BrowseNodeDataObject
constructor. The example below should clarify this process.
Users do have to set up an initial BrowseNodeDataObject
, passing in a String
representing the the location of the node in the tree to view, also referred to as the current location. This String
is a comma-separated string of zero-based indices. For example if the node requested is the 4th child of the first root node then the value would be "0,3". That's 0 for the first root node and 3 for its fourth child. The location for the 7th child of the 4th child of the first root node would be stored as "0,3,6" and so on. The value of the current location in the initial BrowseNodeDataObject
would normally be something like "0" or "1", indicating one of the roots of the tree of data. The default is "0" if the current location passed in is null. Again, the example below should clarify.
Let's look at an example of how to use BrowseNodeDataObject
. The Java code required by this example follows UIX XML example. In this example we have bound the value of the "title"
attribute and the data for the "categories"
child.
<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"
expressionLanguage="el">
<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"
title="${data:data().browseData.text}">
<categories>
<bulletedList>
<contents childData="${data:data().browseData.categoriesData}">
<link text="${uix.current.text}" destination="${uix.current.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="Shop"
destination="http://www.oracle.com"
destinationText="More Information"
expandable="expanded">
<nodes text="Books"
destination="http://www.oracle.com"
destinationText="More Information"
description="Instructions: buy, buy, buy!"
expandable="expanded">
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Paperbacks"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"/>
<nodes text="Nonfiction"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Hardware"
expandable="expanded" >
<nodes text="Desktops"
destination="http://www.oracle.com"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"/>
</nodes>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</contents>
</body>
</ctrl:content>
<!-- UIX Servlet -->
<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>
The following are the java methods that make this interactive. All subsequent BrowseMenuBean
examples use these same methods. The first method creates an instance of BrowseNodeDataObject
, passing in the inline tree of data and the location. The first time this method is called the value of location
is null and the default used is "0", indicating the first root which is the "Shop" node.
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);
}
The next method is called when there is a 'browse' event. The value of the 'location'(UIConstants.LOCATION_PARAM)
parameter is set as a property on the context. This property is subsequently passed to the BrowseNodeDataObject
constructor in the method above.
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;
}
Next we will look at a more complete example of how to use the rest of the keys of BrowseNodeDataObject
. A little later we will show you a utility class that simplifies wiring up a BrowseMenuBean
to a BrowseNodeDataObject
.
<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"
expressionLanguage="el">
<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"
title="${data:data().browseData.text}"
longDesc="${data:data().browseData.description}">
<location>
<breadCrumbs rendered="${data:data().browseData.renderLocation}">
<contents childData="${data:data().browseData.locationData}">
<link text="${uix.currennt.text}" destination="${uix.currennt.destination}"/>
</contents>
</breadCrumbs>
</location>
<contentLink>
<link text="${data:data().browseData.destinationText}"
destination="${data:data().browseData.destination}"
rendered="${data:data().browseData.renderContentLink}"/>
</contentLink>
<categories>
<bulletedList rendered="${data:data().browseData.renderCategories}">
<contents childData="${data:data().browseData.categoriesData}">
<link text="${uix.current.text}" destination="${uix.current.destination}"/>
</contents>
</bulletedList>
</categories>
<items>
<bulletedList rendered="${data:data().browseData.renderItems}">
<contents childData="${data:data().browseData.itemsData}">
<link text="${uix.current.text}" destination="${uix.current.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="Shop"
destination="http://www.oracle.com"
destinationText="More Information"
expandable="expanded">
<nodes text="Books"
destination="http://www.oracle.com"
destinationText="More Information"
description="Instructions: buy, buy, buy!"
expandable="expanded">
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Paperbacks"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"/>
<nodes text="Nonfiction"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Hardware"
expandable="expanded" >
<nodes text="Desktops"
destination="http://www.oracle.com"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"/>
</nodes>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</contents>
</body>
</ctrl:content>
<!-- UIX Servlet -->
<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>
While running the examples you can see the destination for a link in the status bar by resting your mouse over the link. In the previous examples the destinations for the links in the breadcrumbs and under the "Categories" header contain the destination passed in to the BrowseNodeDataObject
constructor, to which the name-value pairs described above are appended. If the destination is not specified then it defaults to the value returned by the call context.getURLEncoder().getDefaultURL(). An example of this default destination can be seen in the getBrowseNodeDataObject
method described above where we use a constructor which takes no destination.
When the BrowseMenu's "formSubmitted"
attribute is set to true, then the name-value pairs are returned through form submission. In the following example we will use form submission. Notice that now the destinations for the links in the breadcrumbs and under the "Categories" header call a function to submit the form.
<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"
expressionLanguage="el">
<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"
title="${data:data().browseData.text}"
longDesc="${data:data().browseData.description}"
formSubmitted="true"
formName="myForm">
<location>
<breadCrumbs rendered="${data:data().browseData.renderLocation}">
<contents childData="${data:data().browseData.locationData}">
<link text="${uix.current.text}" destination="${uix.current.destination}"/>
</contents>
</breadCrumbs>
</location>
<contentLink>
<link text="${data:data().browseData.destinationText}"
destination="${data:data().browseData.destination}"
rendered="${data:data().browseData.renderContentLink}"/>
</contentLink>
<categories>
<bulletedList rendered="${data:data().browseData.renderCategories}">
<contents childData="${data:data().browseData.categoriesData}">
<link text="${uix.current.text}" destination="${uix.current.destination}"/>
</contents>
</bulletedList>
</categories>
<items>
<bulletedList rendered="${data:data().browseData.renderItems}">
<contents childData="${data:data().browseData.itemsData}">
<link text="${uix.current.text}" destination="${uix.current.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="Shop"
destination="http://www.oracle.com"
destinationText="More Information"
expandable="expanded">
<nodes text="Books"
destination="http://www.oracle.com"
destinationText="More Information"
description="Instructions: buy, buy, buy!"
expandable="expanded">
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Paperbacks"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"/>
<nodes text="Nonfiction"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Hardware"
expandable="expanded" >
<nodes text="Desktops"
destination="http://www.oracle.com"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"/>
</nodes>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</contents>
</body>
</ctrl:content>
<!-- UIX Servlet -->
<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
is a utility class which contains a method to set up a BrowseMenuBean
to comply to BLAF, with breadCrumbs for the location element, a bulletedList of links for the items, and so on. In Java you might write code looking something like:
// 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);
Where NAMESPACEURI
and LOCALNAME
are the namespace and name of the DataObject
, most likely the BrowseNodeDataObject
, to which the data is bound.
In UIX XML this functionality can be accessed with two additional attributes. The "defaultContents"
attribute indicates that the BrowseMenu should use the BLAF defaults, in other words BrowseMenuUtils.configureBrowseMenu
should be called. The "source"
attribute is the colon-separated namespace and name to pass to the BrowseMenuUtils.configureBrowseMenu
method.
<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="Shop"
destination="http://www.oracle.com"
destinationText="More Information"
expandable="expanded">
<nodes text="Books"
destination="http://www.oracle.com"
destinationText="More Information"
description="Instructions: buy, buy, buy!"
expandable="expanded">
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Paperbacks"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"/>
<nodes text="Nonfiction"
destination="http://www.oracle.com"/>
</nodes>
<nodes text="Hardware"
expandable="expanded" >
<nodes text="Desktops"
destination="http://www.oracle.com"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"/>
</nodes>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</contents>
</body>
</ctrl:content>
<!-- UIX Servlet -->
<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>
Note that you can ask for the defaults and then override just the parts that need changing. For example let's say you wanted to display items in a table and you wanted to change the text of the headers above the categories and items, but otherwise you wanted to use the defaults. You would set the "defaultContents"
and the "source"
attributes as shown above, but you would also set the values you wanted to change. In this case you would set the "categoryTitle"
and "itemTitle"
attributes and set the "items"
child with the data appropriately bound. Let's look at an example.
<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"
expressionLanguage="el">
<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 tableData="${data:data().browseData.itemsData}"
rendered="${data:data().browseData.renderItems}">
<contents>
<button text="${uix.current.text}" destination="${uix.current.destination}"/>
<text text="${uix.current.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="Shop"
destination="http://www.oracle.com"
destinationText="More Information"
expandable="expanded">
<nodes text="Books"
destination="http://www.oracle.com"
destinationText="More Information"
description="Instructions: buy, buy, buy!"
expandable="expanded">
<nodes text="Sale"
destination="http://www.oracle.com"
expandable="expanded">
<nodes text="Paperbacks"
destination="http://www.oracle.com"
definition="The madness of 1000 years"/>
</nodes>
<nodes text="Fiction"
destination="http://www.oracle.com"
definition="Fiction is fantasy"/>
<nodes text="nonfiction"
destination="http://www.oracle.com"
definition="nonfiction is true"/>
</nodes>
<nodes text="Hardware"
expandable="expanded" >
<nodes text="Desktops"
destination="http://www.oracle.com"
definition="Desktops aren't portable"/>
<nodes text="Notebooks"
destination="http://www.oracle.com"
definition="NoteBooks fit in your lap"/>
</nodes>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</contents>
</body>
</ctrl:content>
<!-- UIX Servlet -->
<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>
Notice that we added key-value pairs to the DataObject
s that were not expected by the BrowseNodeDataObject
and used these values in the table.
The HGridBean
provides yet another way to view tree-structured data. This bean is the union of the TreeBean
and the TableBean
; it implements (and extends) the functionality of the TreeBean
while imitating the format of a TableBean
. In addition to the expand/collapse functionality of the TreeBean
, the HGrid supports a zoom in/out feature which allows users to focus in on (or out of) a subtree. One important difference between the HGrid and the Tree is that although the Tree supports multiple roots, the HGrid only supports a single root. It is recommended that you read Creating Tables in ADF UIX before continuing with the HGrid.
An example HGrid is presented in Figure 10-5.
The parts of the HGrid shown in Figure 10-5 are explained in the list below. The numbers of the list correspond to the numbers called out in the illustration.
In this example, the object hierarchy column (6) displays the tree nodes. Clicking the arrows (3 and 4) in this column will expand or collapse the corresponding tree node. The entire tree is rooted at the node "All Colors," but this HGrid is focused on a subtree rooted at the node "Primary Colors." Clicking on the focus icons (2) in the focus column (5) allows a user to continue zooming into subtrees. The breadcrumbs area (1) shows all the parent nodes above the current focus root; clicking on these links allows a user to zoom out to that parent level. The "Expand All" and "Collapse All" links (below the control bar) allow a user to expand or collapse all the tree nodes below the current focus root.
UIX XML Key | UIConstant | Description |
---|---|---|
nodeStamp |
NODE_STAMP_CHILD |
This child allows the header of the object-hierarchy column to be customized. It can also be used as a stamp to customize the object-hierarchy column itself. |
columnHeaderStamp |
COLUMN_HEADER_STAMP_CHILD |
This is the child used to stamp out all of the user-defined column headers. |
tableSelection |
TABLE_SELECTION_CHILD |
This is the child used to implement selection in the HGrid. |
UIX XML Key | UIConstant | Type | Description |
---|---|---|---|
id |
ID_ATTR |
String |
A page-wide unique id. |
treeData |
TREE_DATA_ATTR |
DataObject |
This is the root of the tree being displayed by the HGrid. |
proxy |
PROXY_ATTR |
HGridDataProxy |
The proxy keeps track of expand/collapse/focus state of the HGrid by setting up the expand, collapse and focus destinations. |
columnHeaderData |
COLUMN_HEADER_DATA_ATTR |
DataObjectList |
The data to use when stamping out the columnHeaderStamp child. |
formSubmitted |
FORM_SUBMITTED_ATTR |
Boolean |
Whether or not to use form submission. Form submission is not the default, thus if form submission is desired then this attribute must be explicitly set to true. |
The above tables list some of the important named children and attributes of
the HGridBean
. For an exhaustive list of these
HGrid properties see the hGrid
UIX element
documentation (or the HGridBean
JavaDoc).
The following is an example of a simple HGrid; it displays a tree with a root node called Primary Colors. The data provider part looks familiar; it is written just like it was for a Tree. The HGrid displayed is not interactive (just like a Tree without a proxy).
<page xmlns="http://xmlns.oracle.com/uix/ui"
expressionLanguage="el">
<content>
<dataScope>
<contents>
<hGrid id="hg1" treeData="${uix.data.treeData.nodes}"/>
</contents>
<provider>
<data name="treeData">
<inline>
<nodes text="Primary Colors" expandable="expanded">
<nodes text="Red"/>
<nodes text="Green" expandable="expanded">
<nodes text="Light"/>
<nodes text="Dark"/>
</nodes>
<nodes text="Blue"/>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</content>
</page>
The above simple example doesn't demonstrate the advantage of an HGrid over a Tree. The impressive visual effect of an HGrid is demonstrated when its Table formatting properties are used, as in the following example:
<page xmlns="http://xmlns.oracle.com/uix/ui"
expressionLanguage="el">
<content>
<dataScope>
<contents>
<hGrid id="hg1" treeData="${uix.data.treeData.nodes}">
<tableSelection>
<multipleSelection text="Select and ...">
<contents>
<button text="Copy"/>
</contents>
</multipleSelection>
</tableSelection>
<columnHeaderData>
<col text="Red Code"/>
<col text="Green Code"/>
<col text="Blue Code"/>
</columnHeaderData>
<columnHeaderStamp>
<text text="${uix.current.text}"/>
</columnHeaderStamp>
<columnFormats>
<columnFormat columnDataFormat="numberFormat"/>
<columnFormat columnDataFormat="numberFormat"/>
<columnFormat columnDataFormat="numberFormat"/>
</columnFormats>
<contents>
<text text="${uix.current.r}"/>
<text text="${uix.current.g}"/>
<text text="${uix.current.b}"/>
</contents>
</hGrid>
</contents>
<provider>
<data name="treeData">
<inline>
<nodes text="Primary Colors" expandable="expanded">
<nodes text="Red" r="Any" g="00" b="00" />
<nodes text="Green" r="00" g="Any" b="00" expandable="expanded">
<nodes text="Light" r="00" g="FF" b="00" />
<nodes text="Dark" r="00" g="88" b="00" />
</nodes>
<nodes text="Blue" r="00" g="00" b="Any"/>
</nodes>
</inline>
</data>
</provider>
</dataScope>
</content>
</page>
In the above example, the HGrid column headers are set using columnHeaderData
and columnHeaderStamp
, column formats are set using columnFormats
and selection is set using tableSelection
and implemented by MultipleSelectionBean
. Please refer to the Table chapter for detailed descriptions of these
formatting options. The Table chapter also describes other formatting options
such as column banding and grid customization which are also pertinent to the
HGrid; however, the HGrid does not support any of the row customizations
supported by the Table. In addition the HGrid does not support table
navigation or detail-disclosure.
The nodeStamp
child of the HGrid allows the
object-hierarchy column to be customized. It is possible to customize both the
header and the data of this column. Note that the HGrid picks a default column
header for the object hierarchy column; this header defaults to
Name. This is easily customized by using a ColumnBean
as the nodeStamp
of the HGrid, as in the following example:
<hGrid ... >
<nodeStamp>
<column>
<columnHeader>
Color
</columnHeader>
</column>
</nodeStamp>
...
</hGrid>
The following example makes use of the nodeStamp to stamp out a custom element in the object hierarchy column:
<hGrid ... >
<nodeStamp>
<column>
...
<contents>
<flowLayout>
<contents>
<messagePrompt messageType="info"/>
<text text="uix.current.text"/>
</contents>
</flowLayout>
</contents>
</column>
</nodeStamp>
...
</hgrid>
Until now, all the example HGrids have been static (non-interactive). In
order to make the HGrid interactive an HGridDataProxy
must be used (the concept of a proxy was
introduced in a previous section describing the TreeBean
). The proxy is responsible for handling the
expand, collapse, focus and breadcrumb links of the HGrid. In order to animate
the HGrid, the proxy needs to maintain the HGrid state across requests. oracle.cabo.ui.data.tree.ClientStateHGridDataProxy
is an
instance of such a proxy that maintains the state on the client side by
encoding the URL. Here is an example of creating a ClientStateHGridDataProxy
in a UIX Servlet event
handler, and storing the proxy on the EventResult
(event handlers are described in the Using a Controller in ADF UIX chapter):
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;
}
}
In order for the above code to be called, the UIX file needs to register the above method as the default event handler, as in the following code snippet:
<handlers>
<event name="*">
<method class="oracle.cabo.doc.demo.HGridDemo"
method="doHGridEvent"/>
</event>
</handlers>
Finally, the proxy created in the event handler and stored on the EventResult
must be data bound to the proxy
attribute of the HGrid. The following is an
example of this process (note that the XML namespace prefix data
is
bound to the UIX Components namespace http://xmlns.oracle.com/uix/ui
,
and ctrl
is bound to the UIX Servlet namespace
http://xmlns.oracle.com/uix/controller
):
<hGrid id="hg1" treeData="${uix.data.treeData.nodes}"
proxy="${uix.eventResult.hGridProxy}">
Now the expand/collapse/focus links on the HGrid come alive! However, there is
some more work that needs to be done before we can play with it. The ClientStateHGridDataProxy
generates certain UIX
Servlet events that must be handled on the server side. In addition, four
event parameters may be generated; the following table summarizes these event
parameters:
Event Parameter | Description | |
---|---|---|
UIX XML | UIConstant | |
source | SOURCE_PARAM | The ID of the HGrid that generated this event |
state | STATE_PARAM | The current expand/collapse state of the HGrid |
root | ROOT_PARAM | Identifies the current focus root of the HGrid |
node | NODE_PARAM | Identifies a tree node that must be expanded/collapsed |
The following table describes the events triggered by the ClientStateHGridDataProxy, and lists the event parameters accompanying each event:
Event | Event Parameters | Description | ||||
---|---|---|---|---|---|---|
UIX XML | UIConstant | source | state | root | node | |
focus | FOCUS_EVENT | X | X | X | Change the focus of the HGrid | |
expand | EXPAND_EVENT | X | X | X | X | A tree node must be expanded/collapsed |
expandAll | EXPAND_ALL_EVENT | X | X | X | Recursively expand all the tree nodes beneath the current focus root | |
collapseAll | COLLAPSE_ALL_EVENT | X | X | X | Recursively collapse all the tree nodes beneath the current focus root |
Each of these four events needs to be handled on the server. A ClientStateHGridDataProxy
needs to be created in each case; it is just a question of which constructor to call. The following code
is used to handle each of the HGrid events (for more information about the
constructors, see the ClientStateHGridDataProxy
JavaDoc):
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;
}
The HGrid has an expand/collapse-all feature that is useful most of the time;
however, in some cases the number of elements in a subtree can be huge -
performing an expand-all on such a subtree would lead to undesirable
results. Therefore, the ClientStateHGridDataProxy
exports a way to disable expand/collapse-all for a given node. It recognizes
the key ClientStateHGridDataProxy.EXPAND_ALL_KEY
(or expandAll in UIX XML). If the value of this key
is Boolean.FALSE
(or false
in UIX XML) then no expand/collapse-all
links are generated for that tree node.
<data name="treeData">
<inline>
<nodes text="All Colors" expandAll="false" expandable="collapsed">
... <!-- lets say there are tons and tons of subnodes -->
</nodes>
</inline>
</data>
It is possible to create an HGrid that is initially focused on some subnode
(including a leaf node), by using the ClientStateHGridDataProxy(int[] focusPath)
constructor. The array of int
s is a path to the
subnode that is the focus. Each element is a (zero based) child index of the
next node, on the path from root to focus node. The first element is a child
index of the root node; it produces the next node, A, on the path. The next
element is a child index of node A, and it produces node B, and so on. For
example, to focus in on the 3rd child of the 1st child of the root use:
// 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);
In some cases the tree displayed by the HGrid is small enough that the
focusing capability is unnecessary. The focus column (and the breadcrumbs) may
be turned off by calling setBreadCrumbsEnabled(false)
on the ClientStateHGridDataProxy instance. Note that this can
only be done if the HGrid is focused on the root (the default focus). If the
HGrid is focused on some subnode, the breadcrumbs should not be disabled, as
the user would have no way of focusing out (in fact, an exception will be
thrown if the breadcrumbs are disabled in this case).
Please see the Creating Tables in ADF UIX chapter for detailed descriptions on how to retrieve data from the HGrid, as the HGrid uses the same mechanisms. This includes using form submitted mode, and retrieving selection data on both the client and server sides.
This chapter discussed tree-structured data and looked at ways
of creating such trees in UIX. It also introduced the TreeBean
, BrowseMenuBean
and
HGridBean
and discussed how these are simply
alternate ways to view tree-structured data. Finally, it told how to use these beans and the UIX Servlet to provide interactivity.
Copyright © 2001, 2004, Oracle.
All rights reserved.