In-depth discussion of Tree2 component usage in JSF

Source: Internet
Author: User
Tags add config contains final return string client
The JS Tree2 component uses HTML tables to render your data as a tree. The tree is dynamic: they can be expanded or folded when the user clicks on them. The component also supports interaction between the client and the server, and JavaScript is used when the client interacts. In the following example, each user's click produces a request/response cycle, and the new tree structure is rendered anew in the new view state.

Note: In the following example, only the visible (already expanded node) data is transmitted to the client. In the first example (client tree), in each HTML response, the entire trees are sent to the client browser. Each node of the tree contains a lot of HTML code (assuming 200 characters per node, this size will depend on the amount of information you want to display on the node, which will be transmitted to the browser, including those that are not visible (no expanded nodes) because one of their ancestor nodes is expanded. If you have a tree with a depth of four layers, the average node has four sub nodes, at which point you need to transfer 10 + 102 + 103 + 104 = 11 110 nodes, each with 200 characters, the tree has 2 222 characters in total, that is, 2M data. This example will show the user that while pure client tree will bring a better user experience to the client, the resulting bandwidth problem is growing rapidly. Pure-Client trees apply to small trees or to medium-sized trees that are used in intranet and broadband connections. For large trees, or if you need to take care of the needs of some low-bandwidth users, you need to use the server-side tree. You can pass --> Clientsidetoggle This attribute to select the tree that you are using the client or the server, <t:tree2> clientsidetoggle This property to select the tree or server that you are using the client tree, <t:tree2 Clientsidetoggle= "false" ... > The server-side tree will be used, and the property value set to True will use the client's tree, and the default value is true.

backing Bean:

The Tree2 component operates on a treemodel in the backing Bean. Usually, you just have to bind this treemodel to this component, like this:

<t:tree2 value= "#{myhandler.treemodel}"
There is a need to establish a class MyHandler, where the managed bean in Faces-config.xml is configured as MyHandler, and in the example this class provides a method Gettreemodel () Used to return a TreeModel to represent your data.

public class MyHandler {
Public TreeModel Gettreemodel () {
......
}
}
TreeModel actually makes some simple packaging for the TreeNode instance.

TreeNode is an interface in which there are four methods associated with Tree2:

String GetType ()
Boolean isleaf ()
List GetChildren ()
int Getchildcount ()
Other methods are useless and may be canceled in future releases. They require developers to do unnecessary operations in developing backing beans.

the int getchildcount () method returns the number of child nodes for this node, and this method is easily implemented in the following way:

Public final int Getchildcount () {
Return GetChildren (). Size ();
}
The appearance of this method makes it feasible to delay loading of sub nodes. The implementation of this method only needs to return the number of child nodes of the node, without having to return an instance of each child node.

The Boolean IsLeaf () method returns True when the node has no child nodes. In this way, a very straightforward implementation can do this:

Public Final Boolean isleaf () {
Return GetChildren (). IsEmpty ();
}
No matter what kind of implementation you provide, at any time you have to keep GetChildren (). IsEmpty () ==> isleaf (). The IsLeaf () method actually controls how the node is rendered: whether it is treated as a leaf node (cannot be expanded).

The String GetType () method determines how the node is rendered. In a JSF page, you can nest facet,jsf in the tag of <t:tree2> to select facet for rendering with the same name as the GetType () method return value. If the node does not find a matching facet, an error is caused and the method does not return null.

The list GetChildren () method returns a list containing all the TreeNode under that node, which means that the nodes will be rendered as child nodes under that node. The list cannot contain NULL, and if the size of the list does not match the Getchildcount (), an error is expected. The child nodes appear in the order in which they are in the list.

Change the contents of the tree

(Delay loading in the background when the node of the tree is expanded)

There are a lot of questions and discussions about this task in the mailing list that I (Marcel, a JSF beginner) summarize here. If you have a better solution, please update the text.

One of the problems here is that I'm going to remove the "+" icon like this:

· <t:tree2 ... shownav= "false" ... >
 
Then let the folder icon (which represents the node containing the child nodes) become clickable:

·
It then accepts the mouse-click event in Java code. In the Processaction (ActionEvent e) method in the Navigationbacker.java file, I load the data of the child nodes from the ejb3-persistency.

The bad thing is that the "+" icon becomes invisible, but I have no way to get to the event of clicking on the "+" icon.

It appears that in Org.apache.myfaces.custom.tree2.HtmlTree.java this file is registered by the _expandcontrol = new Htmlcommandlink (); Get the "+" click event from the inside, but now I have no way to accept the event from my code.

To navigate, I used the treenode.getidentifier (see: #{node.identifier}) containing entries to look like this:

· Db_id= "car_id=7,person_id=2"

This represents the primary key for the Background database table (I haven't found a better solution for navigating)

The program code is as follows:

navigation.jsp

<t:tree2 id= "Servertree" value= "#{navigationbacker.treedata}"
Var= "Node" varnodetoggler= "T" clientsidetoggle= "false" shownav= "false"
Showrootnode= "false" >
<f:facet name= "Project-folder"
<t:graphicimage value= "/images/yellow-folder-open.png"
Rendered= "#{t.nodeexpanded}" border= "0"/>
<t:graphicimage value= "/images/yellow-folder-closed.png"
Rendered= "#{!t.nodeexpanded}" border= "0"/>
Styleclass= "#{t.nodeselected?" ' documentselected ': ' Document '} '
Actionlistener= "#{navigationbacker.nodeclicked}"
Value= "#{node.description}" immediate= "true" >
<f:param name= "db_id" value= "#{node.identifier}"/>

Rendered= "#{!empty Node.children}"/>
</f:facet>
<f:facet name= "Person-folder"
Navigationbacker.java

/** *//**
* Intercept the event that the node is expanded and load additional data
* @param Event
* @throws abortprocessingexception
*/
public void Processaction (ActionEvent event) throws Abortprocessingexception {
System.out.println ("Entering Processaction ()");
UIComponent component = (uicomponent) event.getsource ();
while (!) ( Component!= null && component instanceof Htmltree)) {
component = Component.getparent ();
}
if (component!= null) {
Htmltree tree = (htmltree) component;
Treenodebase node = (treenodebase) tree.getnode ();
if (!tree.isnodeexpanded () && Node.getchildren (). Size () = 0) {
map<string, string> map = splitkeyvalues (Node.getidentifier ()); Some auxiliary code to split "Car_id=7" or "car_id=7&person_id=12"
this.car_id = Map.get ("car_id");
if (this.car_id!= null) {
Appendpersonsnodes (node); See the example below
}
this.person_id = Map.get ("person_id");
if (this.person_id!= null) {
Appendlicensesnodes (node); Not shown
}
}
}
}

/** *//** Add the person child node under the current car_id to the navigation.
private void Appendpersonsnodes (Treenodebase cardetailnode) {
Variableresolver resolver = facescontext.getcurrentinstance (). Getapplication (). Getvariableresolver ();
Personstable personstable = (personstable) resolver.resolvevariable (Facescontext.getcurrentinstance (),
"Personstable");
List <Person> personslist = Personstable.getcarpersons ();
for (person O:personslist) {
List <TreeNodeBase> list = Cardetailnode.getchildren ();
List.add (New Treenodebase ("Person-folder", O.getdescription (), "person_id=" + O.getpersonid (), true));
}
System.out.println ("Navigationbacker fetched" + personslist.size () + "Persons for carid=" + this.car_id);
}
Here's a section of auxiliary code to get F:param from H:commandlink for a variety of purposes.

/** *//**
* When JSF component H:commandlink contains F:param members, these name-value pairs are placed
* Request parameter table for later action handler to use. Unfortunately, such usage cannot be used in
* on the H:commandbutton. We have no way to pass these parameters through the button.
*
* Because action Listeners is guaranteed to be executed before the action method, the action Listeners
* You can call this method to update any context that is required by the Action method.
*
* FROM http://cvs.sakaiproject.org/release/2.0.0/
* Sakai2/gradebook/tool/src/java/org/sakaiproject/tool/gradebook/jsf/facesutil.java
* Educational Community License Version 1.0
*/
public static final Map Geteventparametermap (Facesevent event) {
map<string, string> parametermap = new hashmap<string, string> ();
List children = event.getcomponent (). GetChildren ();
for (Iterator iter = Children.iterator (); Iter.hasnext ();) {
Object next = Iter.next ();
if (next instanceof Uiparameter) {
Uiparameter param = (uiparameter) Next;
Parametermap.put (Param.getname (), "" + Param.getvalue ());
}
}
System.out.println ("parametermap=" + parametermap);
return parametermap;
}
Note: In the above example, the backing bean is stored in the session scope and can be configured in Web-inf/examples-config.xml.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.