1、jsf树型菜单使用JSF中的实现动态加载菜单,其中bar.getChildren().add(aSidebarGroup);是实现动态加载首节点,HtmlSidebarGroup aSidebarGroup = (HtmlSidebarGroup) application.createComponent(HtmlSidebarGroup.COMPONENT_TYPE);aSidebarGroup.setText(boardName);aSidebarGroup.setExpanded(true);aSidebarGroup.setId(viewRoot.createUniqueId();实现加
2、载该节点下的子节点,非常方便。private Sidebar buildSideBar(Sidebar bar)boolean isInitialised = bar.getAttributes().get(IS_INITIALISED)!=null;if (!isInitialised) / Get a reference to the JSF Application, / we need it to create value bindings later-onApplication application = FacesContext.getCurrentInstance().getApp
3、lication();UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();/* Create Infragistics SidebarGroup */ Set the Sidebars width and heightbar.getAttributes().put(style,width: 155px; height: 590px;);/ Create SidebarGroupList list = this.getBoardNameForMenu();for(int i = 0 ;ilist.size()
4、;i+)Object row = (Object)list.get(i);/Object row = (Object)list.listIterator().next();String boardId = String.valueOf(row0);String boardName = String.valueOf(row1);String parentId = String.valueOf(row2);HtmlSidebarGroup aSidebarGroup = (HtmlSidebarGroup) application.createComponent(HtmlSidebarGroup.
5、COMPONENT_TYPE);aSidebarGroup.setText(boardName);aSidebarGroup.setExpanded(true);aSidebarGroup.setId(viewRoot.createUniqueId();/ Add the newly created SidebarGroup to the Sidebars children listbar.getChildren().add(aSidebarGroup);List ls = this.getBoardNameForMenuBar(Integer.parseInt(boardId);if(ls.
6、size() != 0)for(int j=0;jls.size();j+)Object row1 = (Object)ls.get(j);String boardid = String.valueOf(row10);String boardname = String.valueOf(row11);/HtmlSidebarGroup aSidebarGroup = (HtmlSidebarGroup) application.createComponent(HtmlSidebarGroup.COMPONENT_TYPE);HtmlLink aLink1 = (HtmlLink)applicat
7、ion.createComponent(HtmlLink.COMPONENT_TYPE);aLink1.setId(viewRoot.createUniqueId();/aSidebarGroup.setText(sidebarGroupNameStr);/aSidebarGroup.setExpanded(true);/aSidebarGroup.setId(viewRoot.createUniqueId();/aLink1.setId(parentId);aLink1.setUrl(/pages/bbs/visitor/topic/topicforboard.jsf?boardid=+bo
8、ardid+);aLink1.setValue(boardname);aSidebarGroup.getChildren().add(aLink1);深入讨论JSF中Tree2组件使用方法2006-01-16 08:48作者:steady出处:Java博客责任编辑:方舟Tree2组件使用HTML表格将你的数据呈现为一个树。这个树是动态的:当用户点击它们时它们可以展开或者折叠。该组件同时支持客户端和服务端的交互方式,在客户端交互时使用了JavaScript。在随后的例子中,每次用户的点击将产生一个Request / Response 周期,并在新的视图状态(View State)中重新呈现新的树
9、结构。 注:在后面的例子中只有可见的(已经展开的节点)数据被传送到客户端。而在第一个例子(客户端Tree),在每个HTML Response中,整个树都被发送到客户端浏览器。树的每个节点都包含了不少的HTML代码(假定每个节点200个字符,这个大小将取决于你希望在节点上显示的信息的量),这些信息将被传送到浏览器,其中包括了那些不可见的节点(没有展开的节点),因为它们的一个祖系节点被展开。如果你有一个深度有四层的树,平均每个结点拥有四个子结点,这时候你就需要传输10 + 102 + 103 + 104 = 11 110个节点,每个节点有200个字符,这个树总共就有2 222 000个字符,也就是
10、2M的数据。这个例子将向用户说明,虽然纯客户端Tree会给客户端带来更好的用户体验,但随之而来的带宽问题迅速的增长。纯客户端的树适用于小型的树,或者在Intranet及宽带连接中使用的中型大小的树。对于大型的树,或者你需要照顾到一些低带宽的用户的需要时,你就需要使用服务端树。你可以通过的clientSideToggle这个属性来选择你使用的是客户端的树或者服务端的树,t:tree2的clientSideToggle这个属性来选择你使用的是客户端的树或者服务端的树,t:tree2 clientSideToggle=false .将会使用服务端的树,属性值设为true将会使用客户端的树,默认值为t
11、rue。Backing Bean:Tree2组件对Backing Bean中的一个TreeModel进行操作。通常情况,你只要把这个TreeModel绑定到这个组件上就可以了,就像这样:t:tree2 value=#myHandler.treeModel 下面需要建立一个类MyHandler,在faces-config.xml中的managed bean配置成myHandler,在例子中这个类提供了一个方法getTreeModel()用于返回一个TreeModel用于表示你的数据。public class MyHandler public TreeModel getTreeModel() .T
12、reeModel实际上是对TreeNode实例进行了一些简单的包装。TreeNode是一个接口,其中和tree2相关有四个方法:String getType()boolean isLeaf()List getChildren()int getChildCount()其它方法都没有什么用处了,可能会在今后的版本中取消。它们要求开发者在开发backing bean中做一些并不必要的操作。int getChildCount() 方法返回这个节点的子结点数量,这个方法了很容易的采用如下的方式实现:public final int getChildCount() return getChildren()
13、.size();该方法的出现使得对于子结点的延迟加载变的可行。该方法的实现只需要返回该节点的子结点数量,而不需要返回每个子结点的实例。boolean isLeaf() 方法在该节点没有子节点的时候返回true。这样,一个很直截了当的实现可以这样:public final boolean isLeaf() return getChildren().isEmpty();不管你提供了什么样的实现,在任何时间任何情况下你都得保持getChildren().isEmpty() = isLeaf()。isLeaf()方法实际上控制了节点被怎样呈现:是否被当做树叶节点(不能被继续展开)。String get
14、Type() 方法决定了用怎样的方式来呈现这个节点。在 JSF 页面中,可以在 t:tree2 的Tag 中嵌套facet,JSF将会选出与 getType() 方法返回值同名的 facet 用于呈现。如果该节点没有找到相符的 facet,将会导致一个错误,并且这个方法不会返回null。List getChildren() 方法返回一个 List,其中包含了该节点下所有的 TreeNode,这就表示这些节点将被呈现为该节点下的子结点。该 List 不能包含 null,如果该 List 的大小和getChildCount()不符,将会报错。子结点将按照它们在 List 中的顺序呈现出来。改变Tr
15、ee中的内容(当展开树的节点时,在后台延迟加载)在邮件列表中有很多关于这项任务的问题和讨论,我(Marcel,一个 JSF 的初学者)在这里总结一下。如果你有更好的解决方案,请更新这些文字。在这里存在的一个问题就是我要这样把“”图标去掉: t:tree2 . showNav=false . 然后再让文件夹图标(代表包含子节点的节点)变的可点击: h:commandLink action=#t.toggleExpanded actionListener=#navigationBacker.processAction 然后在 Java 代码中接受鼠标点击的事件。在 NavigationBacker
16、.java 文件中的processAction(ActionEvent e) 方法里,我从 EJB3-persistency 中加载子结点的数据。不好的是“”图标变的不可见,但是我现在没有办法获取点击“”图标的事件。看起来在org.apache.myfaces.custom.tree2.HtmlTree.java这个文件里是通过注册了_expandControl = new HtmlCommandLink(); 从内部获取“”的点击事件,但是我现在没有办法从我的代码中接受到这一事件。为了导航,我使用了含有entries的TreeNode.getIdentifier() (参见:#node.id
17、entifier),看起来就是这个样子: db_id=car_id=7,person_id=2 这代表了后台数据库表的主键(我还没有找到一个更好的解决方案用于导航)程序代码如下:navigation.jsp t:tree2 id=serverTree value=#navigationBacker.treeDatavar=node varNodeToggler=t clientSideToggle=false showNav=falseshowRootNode=falsef:facet name=project-folderh:panelGrouph:commandLink action=#t
18、.toggleExpanded actionListener=#navigationBacker.processActiont:graphicImage value=/images/yellow-folder-open.pngrendered=#t.nodeExpanded border=0 /t:graphicImage value=/images/yellow-folder-closed.pngrendered=#!t.nodeExpanded border=0 /h:commandLinkh:commandLink action=#navigationBacker.toViewIdsty
19、leClass=#t.nodeSelected ? documentSelected:documentactionListener=#navigationBacker.nodeClickedvalue=#node.description immediate=truef:param name=db_id value=#node.identifier /h:commandLinkh:outputText value= (#node.childCount) styleClass=childCountrendered=#!empty node.children /h:panelGroup/f:face
20、tf:facet name=person-folderh:panelGroupNavigationBacker.java /* */* 拦截节点被展开的事件,并加载额外的数据* param event* throws AbortProcessingException*/public void processAction(ActionEvent event) throws AbortProcessingException System.out.println(Entering processAction();UIComponent component = (UIComponent) event.
21、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) MapString, String map =
22、splitKeyValues(node.getIdentifier(); / 一些辅助代码,用于将 car_id=7 或 car_id=7&person_id=12 拆分开this.car_id = map.get(car_id);if (this.car_id != null) appendPersonsNodes(node); / 参见下面的例子this.person_id = map.get(person_id);if (this.person_id != null) appendLicensesNodes(node); / 没有显示/* */* 把当前car_id下的Person子结点
23、加入导航中 */private void appendPersonsNodes(TreeNodeBase carDetailNode) VariableResolver resolver = FacesContext.getCurrentInstance().getApplication().getVariableResolver();PersonsTable personsTable = (PersonsTable) resolver.resolveVariable(FacesContext.getCurrentInstance(),personsTable);ListPerson pers
24、onsList = personsTable.getCarPersons();for (Person o : personsList) ListTreeNodeBase 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
25、= + this.car_id);这里有一段辅助代码用于从 h:commandLink 中获取 f:param 用于多种用途。/* */* 当 JSF 组件 h:commandLink 包含有 f:param 成员, 这些 name-value 对被放到 * request 参数表中供后面的action handler使用。不幸的是,这样的用法不能用在* h:commandButton上。我们没有办法把通过 button 来传递这些参数。* 因为 Action Listeners 可以保证在 Action 方法前被执行到,所以 Action Listeners * 可以调用该方法更新 Acti
26、on 方法所需要的任何上下文。* 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) MapString, String parameterMap = new HashMapSt
27、ring, 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(para
28、meterMap= + parameterMap);return parameterMap;TreeNodeBase的构造方法有三种:TreeNodeBase()TreeNodeBase(java.lang.String type, java.lang.String description, boolean leaf)TreeNodeBase(java.lang.String type, java.lang.String description, java.lang.String identifier, boolean leaf)最后一个参数表示是否是未级节点。把XHTML中的代码与bean
29、中的方法和构造方法联系起来看就比较容易了。第一个参数是type,也就是对应的如何渲染的部分;第二个参数是description,也就是tree要显示的内容;第三个参数是treeNode的ID;第四个参数表示是否有下级节点1. 前言在JSF的项目开发中,用到树形菜单时可以考虑使用myfacs实现的tree2组件。网上已经有很多文章对tree2进行介绍,我这里主要对一些重点进行描述,提醒使用者一些注意事项。2. Tree2的组件您可以到http:/myfaces.apache.org/tomahawk下载tomahawk包,放到项目的lib路径中.我这里使用的是tomahawk-1.1.5.jar.然后再页面头部加上下面一行:3. 编写JS
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1