对Primefaces中的树节点进行排序



我正在使用JSF 2.1和Primefaces 3.3。我正在使用素数面树组件从数据库中装箱树。我想按字母顺序对所有级别的树节点进行排序。请帮我一下。

我们在通过Comparator进行排序时遇到了问题,发现有一个方便的PrimeFaces TreeUtils.sortNode(TreeNode,Comparator)class已经提供了,它的工作原理就像一个符咒:)

您必须使用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);

我们之所以将所有内容设置为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();
    }
  }
}

现在,您只需构建TreeNode,然后调用root.sort(),它就会按字母顺序递归地对每个级别的所有子级进行排序。

您也可以使用一种通用的类似TreeNode的方法,例如:

Base取自素数面DefaultTreeNode,未修改的更改在下面的代码中被省略

如果不应将child's限制在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;
    }
}

相关内容

  • 没有找到相关文章

最新更新