`
hekui1016
  • 浏览: 51111 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Creating your own TreeModel in ADF 11g

    博客分类:
  • ADF
 
阅读更多

转自http://www.yonaweb.be/creating_your_own_treemodel_adf_11g_0

published by Yannick on 22 February, 2011 - 08:20

 

Building your own tree in ADF does not seem that easy at first sight but in fact it is not that hard if you know what to do. On the forum at OTN you often find questions about building your own model.

In this post you will find the steps needed to build your own model. In the example i just use some static data but you can rewrite it to use whatever you want.

We will build a tree that has 2 nodes in the root and the first node has 2 children.

Our TreeModel contains objects of the type TreeItem. TreeItem is not a build in class. I call it TreeItem but you can name it whatever you want. It is a regular bean with getters and setters. In order to build a tree, the class should have a method that returns its children.
This is the TreeItem class we will be using:

 

public class TreeItem {
    private String text,action;
    private List<TreeItem> children;
   
    public TreeItem() {
        super();
    }
   
    public TreeItem(String text,String action){
      super();
      this.text = text;
      this.action = action;
    }
 
    public void setText(String text) {
        this.text = text;
    }
 
    public String getText() {
        return text;
    }
 
    public void setAction(String action) {
        this.action = action;
    }
 
    public String getAction() {
        return action;
    }
 
    public void setChildren(List<TreeItem> children) {
        this.children = children;
    }
 
    public List<TreeItem> getChildren() {
        return children;
    }
}

 As you can see, the TreeItem has 3 properties:

 

  • text: containing the text that we will be using to show the node in the tree
  • action: this is the action that will be set to the action property of the commandLink in the tree. This way we can use the tree for navigation.
  • children: this contains a list of the children of the current node. This is vital for building a tree.

You are free to add more properties. Every property you add to the TreeItem you can use it in the tree itself.

Next we need to create our managed bean. This will contain the TreeModel itself.
In fact we just create the rootNode and use a default TreeModel from ADF. This is the ChildPropertyTreeModel.

We will build the tree in the constructor of the bean:

public TreeExample() {
        root = new ArrayList<TreeItem>();
        TreeItem node1 = new TreeItem("Node1","node1");
        TreeItem node2 = new TreeItem("Node2","node2");
        root.add(node1);
        root.add(node2);
       
        ArrayList<TreeItem> node1Children = new ArrayList<TreeItem>();
        TreeItem node1Child1 = new TreeItem("Child 1","child1");
        TreeItem node1Child2 = new TreeItem("Child 2","child2");
      node1Children.add(node1Child1);
      node1Children.add(node1Child2);
      node1.setChildren(node1Children);
     
      setListInstance(root);
    }
 
  public void setListInstance(List instance) {
    this.instance = instance;
    model = null;
  }

 The af:tree component requires a TreeModel as value so we need to create such a property as well:

public TreeModel getModel() {
    if(model == null)
        model = new ChildPropertyTreeModel(instance,"children");
    return model;
  }
 In this methode we will create the actual TreeModel based upon the root we created in the constructor. As you can see we also need to specify the name of the method that will return the children. By specifying "children" as a second parameter of the ChildPropertyTreeModel constructor, we tell the framework to call getChildren() in order to retreive the list of children.

When this is done, we need to register the bean to the faces-config.xml:

<managed-bean>
    <managed-bean-name>TreeExample</managed-bean-name>
    <managed-bean-class>view.beans.TreeExample</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
  </managed-bean>

 As a final step we need to add the tree to the page:

<af:tree value="#{TreeExample.model}" var="node">
   <f:facet name="nodeStamp">
      <af:commandLink text="#{node.text}" action="#{node.action}"/>
  </f:facet>
</af:tree>

 

另附一篇文章:

Back to programming: Programmatic ADF Faces Tree component

http://one-size-doesnt-fit-all.blogspot.com/2007/05/back-to-programming-programmatic-adf.html

Typically ADF Faces components in our JDeveloper 10.1.3 applications are data bound, meaning they map to objects in the binding layer as specified in separate pageDef files. This is expressed in our components through EL references to bindings}.

However what if we don't want to map to a binding layer object, but instead want to construct the data elements programmatically? For this blog we'll consider the example of an <af:tree> component to demonstrate this, showing how we construct the elements in the tree programmatically rather than relying on bindings.

Our goal is to construct an <af:tree> component comprised of <af:goLink> tags and looks as follows:

Logically understanding our hierarchy

Before we consider the <af:tree> component specifically, have a think about what the hierarchy represents. Each node in the tree has a text title, and a hyperlink destination. Each node is a child to a parent node, and each node may be comprised of 0, 1 or more child nodes. Collectively this represents our tree and is a simple logical concept.

Understanding the ADF Faces Tree component

The code for an <af:tree> in a web page would typically look as follows:

<af:tree var="node" value="#{treeModel.model}">
  <f:facet name="nodeStamp">
    <af:goLink text="#{node.text}" destination="#{node.destination}"/>
  </f:facet>
</af:tree>


In our example you'll note that the nodes within the tree are comprised of <af:goLink> tags that render the links in our tree above. You'll also note if you constructed a <af:tree> tag using the drag n drop facilities of JDeveloper based on a data bound component from the data control palette, the code would look very similar. In other words there isn't anything really special about the code above besides the use of <af:goLink> tags.

The <af:tree value> attribute demands at runtime an oracle.adf.view.faces.model.TreeModel instance. This class is the data model for the ADF Faces Tree component, where rows in the tree may contain other trees, or alternatively described, nodes in the tree can contain children nodes which in turn can also have children nodes and so on.

The nodeStamp facet of the <af:tree> walks the TreeModel, creating for each node the subtags contained within the <f:facet> tag, in this case an <af:goLink> tag. You'll note the <af:goLink> tag makes reference to the current node in the TreeModel as it walks the tree via the <af:tree> tag's var="node" attribute.

So we now logically have an understanding of what we want to model, and we also understand what the <af:tree> component wants. Lets consider our design solution.

Keeping it simple with a POJO

From the design point of view, to model the hierarchy we'd like to create our own very simple POJO TreeItem that stores a String text and String destination required for each goLink, along with a List of children TreeItem objects to reflect the hierarchy. At runtime we'll construct this tree programmatically populating the hierarchy in any way we desire.

The POJO approach is very easy to understand and implement. However the problem with our POJO approach is the datatype doesn't match that required by the <af:tree>, namely oracle.adf.view.faces.model.TreeModel. How do we address this?

Creating an Adapter between our TreeItem and TreeModel

In the OO world they have the concept of the adapter design pattern. An Adapter class is one that wraps another interface, to provide an interface the client expects. In our case we have our POJO TreeItem interface, but our client the <af:tree> demands an oracle.adf.view.faces.model.TreeModel, so we'll provide a class called TreeModelAdapter to work as the adapter. It will be this class that we'll define in our faces-config.xml file as a managed bean for the <af:tree> control to make use of at runtime.

The TreeModelAdapter will internally store our TreeItem hierarchy and TreeModel, and provide accessor methods to access and manipulate these items.

Coding the solution

The following describes the steps in coding our design solution. It assumes you've already created your web page with the <af:tree> code as previous:

Create our POJO Java Bean TreeItem class as follows:

package view;

import java.util.List;

public class TreeItem {
  private String _text = null;
  private String _destination = null;
  private List<treeitem> _children = null;

  public TreeItem(String text, String destination) {
    setText(text);
    setDestination(destination);
  }

  public String getText() { return _text; }
  public void setText(String text) { this._text = text; }

  public String getDestination() { return _destination; }
  public void setDestination(String destination) { this._destination = destination; }

  public List getChildren() { return _children; }
  public void setChildren(List children) { this._children = children; }
}

Note the following about the TreeItem class:

  • Internally stores the Strings text and destination and provides appropriate accessors.
  • Contains a list of child TreeItems _children that may contain 0, 1 or many child TreeItem objects within the current TreeItem. This represents the hierarchy. Note that it is important the Java Bean provides accessors specifically named getChildren() and setChildren() to retrieve the private _children attribute as you'll see in a moment.
Create a TreeModelAdapter class:

package view;

import java.beans.IntrospectionException;
import java.util.ArrayList;
import java.util.List;
import oracle.adf.view.faces.model.ChildPropertyTreeModel;
import oracle.adf.view.faces.model.TreeModel;

public class TreeModelAdapter {
  private Object _instance = null;
  private transient TreeModel _model = null;

  public TreeModelAdapter() {

    ArrayList<TreeItem> rootTreeItems = new ArrayList<TreeItem>();

    TreeItem treeItem1 = new TreeItem("Fish", "http://www.someurl1.com");
    TreeItem treeItem2 = new TreeItem("Dog", "http://www.someurl2.com");
    TreeItem treeItem3 = new TreeItem("Cat", "http://www.someurl3.com");

    TreeItem treeItem2_1 = new TreeItem("Blue Heeler", "http://www.someurl4.com");

    TreeItem treeItem2_1_1 = new TreeItem("Rover", "http://www.someurl5.com");
    TreeItem treeItem2_1_2 = new TreeItem("Ruffus", "http://www.someurl6.com");

    rootTreeItems.add(treeItem1);
    rootTreeItems.add(treeItem2);
    rootTreeItems.add(treeItem3);

    ArrayList<TreeItem> treeItem2Children = new ArrayList<TreeItem>();
    ArrayList<TreeItem> treeItem2_1Children = new ArrayList<TreeItem>();

    treeItem2Children.add(treeItem2_1);
    treeItem2.setChildren(treeItem2Children);

    treeItem2_1Children.add(treeItem2_1_1);
    treeItem2_1Children.add(treeItem2_1_2);
    treeItem2_1.setChildren(treeItem2_1Children);

    this.setListInstance(rootTreeItems);
  }

  public TreeModel getModel() throws IntrospectionException {
    if (_model == null) {
      _model = new ChildPropertyTreeModel(_instance, "children");
    }
    return _model;
  }

  public void setListInstance(List instance) {
    _instance = instance;
    _model = null;
  }
}


Note the following about the TreeModelAdapter class:
  • It contains a private oracle.adf.view.faces.model.TreeModel _model attribute. This is the TreeModel we'll provide to the <af:tree> tag. It is exposed via the getModel() method, and you previously saw this method was called via the <af:tree value="#{treeModel.model"> EL expression.
  • The class also contains an Object named _instance. This is where we'll store our own programmatic tree constructed from our own home baked Java Bean TreeItem hierarchy. The nice thing about this implementation is it doesn't care if it gets our TreeItem class, or any other sort of Java Bean, as long as it follows the Java Bean spec by providing accessors to retrieve the attributes, including specifically accessors for _children (more on this soon). The setListInstance() accessor provides a method to set the Object _instance.
  • In our simple example here, the constructor creates 3 root TreeItem nodes "Fish", "Dog", "Cat". For the "Dog" TreeItem node it creates a child "Blue Heeler" node. For the "Blue Heeler" node it creates 2 TreeItem nodes "Rover" and "Ruffus" in turn. The constructors last action is to assign the TreeItem hierarchy we've populated into rootTreeItems into the TreeModelAdapter class's _instance private attribute.
  • The getModel() method requires further explanation. The ChildPropertyTreeModel class is a subclass of oracle.adf.view.faces.model.TreeModel. It allows the construction of a TreeModel based on a list of beans. This suites our purposes well as we've constructed a list of TreeItem beans stored in the TreeModelAdapter's _instance attribute. You'll note that the ChildPropertyTreeModel constructor for its 2nd parameter specifies the String "children". The ChildPropertyTreeModel class uses this name to work out what accessor methods it needs to use in the TreeItem Java Bean to access the hierarchical part of the TreeItem class. It's important that the string "children" matches the accessor names getChildren() and setChildren() in the TreeItem class following the Java Bean specification rules. If these mismatch you'll get a runtime error.
Finally in our faces-config.xml file we declare our managed bean as follows:

<managed-bean>
  <managed-bean-name>treeModel
  <managed-bean-class>view.TreeModelAdapter
  <managed-bean-scope>request
</managed-bean>

Note that the request scope used for treeModel will result in the instantiation of TreeModelAdapter for each request to the page containing the treeModel reference, potentially an expensive exercise. If the tree is duplicated across multiple screens a session scope may be appropriate.

Credit

To give credit the inspiration for the TreeModelAdapter in this solution is a modification of MenuTreeModelAdapter from Oracle's ADF Developer's Guide for Forms/4GL Developers 10.1.3 (page 19-8). Those with lateral thinking should be able to see the ability to create programmatic <af:page> and <af:panelPage> menus with this technique.

Final Caveat

The code above is not applicable for JDev 11g and its new Rich Faces components as the class structure for the components has changed. Once Oracle releases the JavaDocs for the components I'll look at revising this article on request. 

 

分享到:
评论

相关推荐

    pyqt treemodel使用checkbox例子代码

    然而,如果需要自定义更复杂的数据模型,如带有复选框的树结构,那么`QAbstractItemModel`和`QTreeView`的组合,即`TreeModel`,将是一个更好的选择。`TreeModel`允许我们灵活地控制数据的显示和交互方式,包括添加...

    Qt:在TreeModel+QTreeView中使用复选框(checkbox)

    QTreeView Checkboxes 需要实现一个功能:在QT的TreeView中,能够使用复选框,并且选中父节点的复选框可以全选或取消子节点的复选框。 参考链接: http://blog.csdn.net/ajaxhe/article/details/7518285

    Java FileSystem TreeModel-开源

    FileSystem TreeModel for Java 项目旨在提供一个简单易学的 TreeModel API,它允许 TreeModel 查看器显示文件系统而无需编写任何代码。

    tree model

    这段只能实现播放功能 我想要暂停和关闭功能 怎么做到?

    EXT 树形结构样例

    EXT Tree 是一个强大的JavaScript组件,它是EXT JS框架的一部分,用于构建可交互的树形结构界面。EXT Tree在Web应用中广泛使用,特别是在需要展示层级关系数据的场景下,如文件系统、组织架构或导航菜单。这个"EXT ...

    SATree:SQLAlchemy的TreeModel

    树的一个节点在存储为一条记录,表现为SQLALchemy一个混合了TreeMixin的Model实例。安装通过pip进行安装pip install satree直接下载源代码,导入就可以使用from satree imoport TreeMixin,TreeManager快速使用SAtree...

    QTreeView树形视图使用自定义模型model

    在Qt库中,`QTreeView`是一个非常重要的组件,它用于显示数据的树形结构。在实际开发中,我们可能需要根据具体需求定制数据模型,这时就需要使用到自定义模型(model)。本教程将深入讲解如何在`QTreeView`中使用...

    实现Qtreeview 重写model 实现model中添加按钮的功能

    在Qt框架中,`QTreeView`是一个非常重要的组件,它用于显示和操作数据模型的层次结构。本教程将深入探讨如何实现一个自定义的`QTreeView`,通过重写`QAbstractItemModel`来添加按钮功能,使得每个树节点都可以关联一...

    java使用jtree动态实现二叉树

    在Java编程中,`JTree`是Swing库中的一个组件,用于展示树形数据结构。这个组件在GUI(图形用户界面)应用中非常常见,因为它可以清晰地展示层次关系的数据,比如文件系统目录结构。在Java中动态实现二叉树,即在...

    动态Tree

    4. **TreeModel实现**:创建一个实现TreeModel接口的类,将数据模型与JTree组件关联起来。你需要实现的方法可能包括`getChildCount()`、`getChildAt()`、`isLeaf()`等,以便JTree可以正确地渲染和操作节点。 5. **...

    QTreeView+自定义Model实现示例

    在Qt框架中,`QTreeView`是一个非常重要的组件,它用于显示树形结构的数据,例如文件系统目录、项目任务层次或者任何其他具有层级关系的信息。`QTreeView`通常与`QAbstractItemModel`或其子类(如`...

    netbeans-Jtree

    在Java编程领域,`JTree`是Swing库中的一个重要组件,用于展示层次结构的数据,如文件系统目录、组织架构等。在这个项目“netbeans-Jtree”中,开发者使用NetBeans 8.0 IDE创建了一个包含三级结构的树形视图。...

    TreeDemo13 自定义model示例.rar

    【标题】"TreeDemo13 自定义model示例"是一个关于使用Qt库创建自定义图形树视图的应用程序。这个示例着重展示了如何利用Qt的模型视图框架(Model/View Framework)来构建一个可拖动节点的树形结构。 在Qt中,模型...

    c#windowform实现treeview多层绑定

    在C# Windows Forms开发中,`TreeView`控件是一个常用且功能强大的组件,它能够以树形结构展示数据,非常适合用于表示层次结构的信息。本文将深入探讨如何实现`TreeView`控件的多层动态绑定,以帮助开发者更好地理解...

    Swing-JTree.rar_jtree_jtree Demo_swing 树

    Swing中的JTree组件是Java GUI(图形用户界面)开发中的一个重要组成部分,它允许程序员创建和展示层次结构数据。在Java Swing库中,JTree是一个用于显示和操作树形数据结构的视图组件。这个“Swing-JTree.rar”文件...

    JAVA做的TreeView(仿C#TreeView)

    TreeView是一种图形用户界面(GUI)组件,它以树形结构展示数据,允许用户通过展开和折叠节点来浏览层次化的信息。本篇文章将深入探讨如何在Java中实现一个仿C#样式的TreeView。 首先,Java的标准库Swing提供了...

    java 树 tree

    在Java编程语言中,"树"(Tree)是一种非线性的数据结构,它模拟了自然界中的树状层次关系。在计算机科学中,树被广泛应用于各种算法和数据存储,如文件系统、数据库索引、图形表示等。Java提供了多种方式来实现和...

    swing jtree

    2. **构建TreeModel**:通过将DefaultMutableTreeNode对象组装成树形结构,你可以创建一个TreeModel,它是JTree的数据源。最常见的实现是DefaultTreeModel。 3. **实例化JTree**:使用构建好的TreeModel创建JTree...

    java swing tree树的懒加载

    Java Swing 是一个用于构建桌面应用程序的图形用户界面(GUI)工具包,它是Java Foundation Classes (JFC)的一部分。在Swing中,`JTree`组件是用于显示和操作树形数据结构的控件。当我们处理大量数据时,一次性加载...

Global site tag (gtag.js) - Google Analytics