在Primefaces中对树节点进行排序

时间:2013-02-15 09:36:01

标签: jsf jsf-2 primefaces

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

3 个答案:

答案 0 :(得分:6)

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

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);

我们将所有内容设置为null的原因是因为当在DefaultTreeNode上设置父项时,它将被添加到父项子列表中。设置节点父节点的顺序决定了它们在树组件中的显示顺序。

知道我们可以使用比较器分别对每个列表进行排序。

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();
    }
  }
}

现在你可以构建你的TreeNodes,然后调用root.sort(),它将按字母顺序递归地对每个级别的所有子节目进行排序。

答案 1 :(得分:5)

我们通过Comparator排序时遇到问题,并发现有一个方便的 PrimeFaces TreeUtils.sortNode( TreeNode, Comparator ) 已经提供魅力:)

答案 2 :(得分:0)

您还可以使用通用的可比较TreeNode方法,例如:

Base取自primeface DefaultTreeNode,未修改的更改将在下面的代码中省略。

如果儿童的T不受限制,可以使用TreeNodeComparable<T extends Comparable<?>>并使用Comparable方式转换为compareTo()

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;
    }
}