The tree component

The next example will show how to make and use a rich:tree component in an effective way.

First let's create the /view/examples/tree/treeExample.xhtml page, it might look like this:

<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
template="/layout/template.xhtml">
<ui:define name="body">
<h:form>
<rich:tree switchType="ajax" value="#{contactsTree}"
var="item">
<rich:treeNode iconLeaf="/img/contact.png"
icon="/img/files.png">
<h:outputText value="#{item.name}"/>
</rich:treeNode>
</rich:tree>
</h:form>
</ui:define>
</ui:composition>

Here, we've defined a tree that gets the data model from the contactsTree variable and uses Ajax to render the changes (switchType="ajax") during the user interaction.

Inside the tree, we've also defined what the standard tree node will look like.

Let's use the backing bean now create a book.richfaces.advcm.modules.main.examples.tree package, and inside it, a Java class called TreeExampleHelper.

This class might look like the following code:

package book.richfaces.advcm.modules.main.examples.tree;
@Name("treeExampleHelper")
@Scope(ScopeType.CONVERSATION)
public class TreeExampleHelper {
@In(create = true)
EntityManager entityManager;
@In
FacesMessages facesMessages;
@In(create = true)
GroupsListHelper groupsListHelper;
@In(create = true)
HomeContactsListHelper homeContactsListHelper;
@Factory(value = "contactsTree", autoCreate = true,
scope = ScopeType.CONVERSATION)
public TreeNode fillInContactsTree() {
TreeNode tree = new TreeNodeImpl();
for (ContactGroup group : groupsListHelper.getGroups()) {
TreeNode groupNode = new TreeNodeImpl();
// Add the sub level
// I want only the contacts inside the current
// group
homeContactsListHelper.setGroupFilter(group);
// Force the reloading of the list with the new
// filter
homeContactsListHelper.sand so onontactsList(null);
for (Contact contact : homeContactsListHelper.gand so onontactsList()) {
TreeNode contactNode = new TreeNodeImpl();
// Add the contact inside the group
contactNode.setData(contact);
groupNode.addChild(group.getId() + "_" +
contact.getId(), contactNode);
}
// Add the group with contacts inside
groupNode.setData(group);
tree.addChild(group.getId(), groupNode);
}
// Reset the filter
homeContactsListHelper.setGroupFilter(null);
homeContactsListHelper.sand so onontactsList(null);
return tree;
}
}

The fillInContactsTree() method is the factory of contactsTree variable that contains the tree data model (an implementation of the TreeNode interface). Our tree will contain the Groups/Contacts structure read from the database, and would look like the next screenshot:

The tree component

State saving

A feature we would like to add is state saving this way, we can put the current tree state into a property and keep it between the requests, or store and then reset in another moment (for example, when the user comes back).

In order to achieve that, we have just to add the DataComponentState property (with getter and setter) inside our bean:

private DataComponentState dataState;
public DataComponentState getDataState() {
return dataState;
}
public void setDataState(DataComponentState dataState) {
this.dataState = dataState;
}

Then we set the componentState attribute of the rich:tree component in the XHTML file:

<rich:tree ... componentState="#{treeExampleHelper.dataState}"

Action listeners

We can define some listener to control user interaction with the tree.

The first one we are going to define is the changeExpandListener, let's add the following method into our bean:

public void changeExpandListener(NodeExpandedEvent event) {
action listeners, richtree component:changeExpandListenerUITree tree = (UITree) event.gand so onomponent();
facesMessages.add(StatusMessage.Severity.INFO,
"Node changed/expanded: "+trefor exampleetRowData());
}

Notice how we get the UITree instance from the event passed to the method.

Note

In a seam-gen generated EAR project, in order to have UITree tree = (UITree) event.gand so onomponent(); working, we have to move all of our libraries to the EAR lib directory. Refer to the binding paragraph to see how to do that.

Now let's set the rich:tree changeExpandListener attribute:

<rich:tree ... changeExpandListener="#{treeExampleHelper.changeExpandListener}" ... >

Done! Now we can act when a user expands or closes a part of the tree.

Another useful listener we can set is the nodeSelectListened. It can be added the same way as the other listener. Let's add the following method into the bean:

public void selectionListener(NodeSelectedEvent event) {
UITree tree = (UITree) event.getComponent();
Object selectedObject = tree.getRowData();
if (selectedObject instanceof ContactGroup) {
facesMessages.add(StatusMessage.Severity.INFO, "Group selected: "+ ((ContactGroup)selectedObject).getName());
} else {
facesMessages.add(StatusMessage.Severity.INFO, "Contact selected: "+ ((Contact)selectedObject).getName()+" "+((Contact)selectedObject).getSurname());
}
}

And also add it to the XHTML file:

<rich:tree ... nodeSelectListener="#{treeExampleHelper.selectionListener}"
ajaxSubmitSelection="true" ... >

We have also set the ajaxSubmitSelection attribute to true in order to "Ajaxize" every listener submission.

You can see the result of selecting a group in the following screenshot:

Action listeners
Action listeners
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.51.246