2013-02-15 43 views
3

我正在使用JSF 2.1和Primefaces 3.3。我正在使用primefaces树组件来从数据库中创建树。我想在所有级别按字母顺序排列树节点。请帮助我。排序Primefaces中的树节点

回答

6

您必须使用Collections.sort和Comparator类对ManagedBean中的Primefaces DefaultTreeNode对象进行排序。

public TreeNodeComparator() implements Comparator<TreeNode> { 
    public int compare(TreeNode n1, TreeNode n2) { 
    // This assumes the tree node data is a string 
    return n1.getData().compareTo(n2.getData()); 
    } 
} 

在你的托管bean中,你将需要组装你的子列表而不添加他们的父母。那可以晚一点。现在,为每个级别建立你的子列表并将parent设置为null;

TreeNode node1 = new DefaultTreeNode("node1", null); 
TreeNode node2 = new DefaultTreeNode("node2", null); 
TreeNode child1node1 = new DefaultTreeNode("zgnagn", null); 
TreeNode child2node1 = new DefaultTreeNode("vvnieeianag", null); 
TreeNode child1node2 = new DefaultTreeNode("cajkgnagair", null); 
TreeNode child2node2 = new DefaultTreeNode("ajaavnagwokd", null); 
rootNodeChildren.add(node1); 
rootNodeChildren.add(node2); 
node1Children.add(child1node1); 
node1Children.add(child2node1); 
node2Children.add(child1node2); 
node2Children.add(child2node2); 

为什么我们的一切设置为空的原因是因为当父被设置在DefaultTreeNode它被添加到父母的孩子名单。您设置父节点的顺序决定了它们将出现在Tree组件中的顺序。

知道我们可以使用我们的比较器来单独排序每个列表。

Collections.sort(rootNodeChildren, new TreeNodeComparator()); 
Collections.sort(node1Children, new TreeNodeComparator()); 
Collections.sort(node2Children, new TreeNodeComparator()); 

现在所有的列表进行排序,所以我们可以通过循环及相应的父母一次一个。您可以编写一个算法来确定这一点,或者您可以保留一个单独的数据结构来构建树层次结构,而无需添加到列表中。

另一种方式,并可能更容易整体,是只覆盖DefaultTreeNode类,并给它一个排序方法:

public SortableDefaultTreeNode extends DefaultTreeNode { 

    public void sort() { 
    TreeNodeComparator comparator = new TreeNodeComparator(); 
    Collections.sort(this.children, comparator); 
    for (TreeNode child : children) { 
     child.sort(); 
    } 
    } 
} 

现在,你可以建立自己的树节点出来,然后调用root.sort(),它会递归排序按字母顺序排列每个级别的所有孩子。

+0

谢谢maple_shaft。它拯救了我的一天。 – neni 2013-02-18 04:43:52

+0

@neni您的欢迎:) – 2013-02-18 11:55:27

0

你也可以使用一个通用的可比的树节点的形式给出,如:

基地从primefaces DefaultTreeNode采取未修改的变化在下面的代码冷落。

如果孩子不应该对T一个限制可以使用TreeNodeComparable<T extends Comparable<?>>compareTo()方法转换为Comparable

public class TreeNodeComparable<T extends Comparable<T>> implements TreeNode, Serializable, 
    Comparable<TreeNodeComparable<T>> 
{ 
    private static final long serialVersionUID = ...; 

    private T data; 

    private List<TreeNodeComparable<T>> children; 


    public TreeNodeComparable(final String type, final T data, final TreeNodeComparable<T> parent) 
    { 
     this.type = type; 
     this.data = data; 
     this.children = (List) new TreeNodeChildren(this); 
     if (parent != null) 
      parent.getChildren().add(this); 
    } 

    /** 
    * Comparison only depends on the underlying data 
    * 
    * @see ObjectUtils#compare(Comparable, Comparable) 
    */ 
    @Override 
    public int compareTo(final TreeNodeComparable<T> node) 
    { 
     if (node == null) 
      throw new NullPointerException("node"); 

     return ObjectUtils.compare((T) this.getData(), (T) node.getData()); 
    } 

    /** 
    * Recursively sorts the complete tree. 
    */ 
    public void sort() 
    { 
     Collections.sort(this.children); 
     for (final TreeNodeComparable<T> child : this.children) 
     { 
      child.sort(); 

      // must reset parent due to PF problems 
      // http://forum.primefaces.org/posting.php?mode=reply&f=3&t=39752 
      child.setParent(this); 
     } 
    } 

    @SuppressWarnings("unchecked") 
    @Override 
    public boolean equals(final Object obj) 
    { 
     if (this == obj) 
      return true; 
     if (obj == null || this.getClass() != obj.getClass()) 
      return false; 

     final TreeNodeComparable<T> other = (TreeNodeComparable<T>) obj; 

     return ObjectUtils.equals(this.data, other.data); 
    } 

    @Override 
    public int hashCode() 
    { 
     return new HashCodeBuilder().append(this.data).toHashCode(); 
    } 

    public void setData(final Object data) 
    { 
     if (data != null && !(data instanceof Comparable)) 
      throw new IllegalArgumentException(); 
     this.data = (T) data; 
    } 

    @SuppressWarnings(
    { 
     "unchecked", "rawtypes" 
    }) 
    public List<TreeNode> getChildren() 
    { 
     return (List) this.children; 
    } 
}