2013-02-15 4 views
3

Я работаю с JSF 2.1 и Primefaces 3.3. Я использую компонент дерева поверхностей для разбиения дерева из базы данных. Я хотел сортировать узлы дерева в алфавитном порядке на всех уровнях. Пожалуйста помоги мне с этим.Сортировка узлов дерева в праймерах

ответ

6

Вам нужно будет отсортировать объекты Primefaces DefaultTreeNode у ManagedBean с помощью Collections.sort и класса Comparator.

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

Теперь вы можете создать свой TreeNodes, и затем вызвать root.sort() и он будет рекурсивно сортировать всех его детей на каждом уровне в алфавитном порядке.

+0

Спасибо вам maple_shaft. Это спасло мой день. – neni

+0

@neni Ваш прием :) –

0

Вы также можете использовать общий сравнимый TreeNode ПОДХОД, такие как:

база была взята из primefaces DefaultTreeNode, неизмененные изменения оставлены в приведенном ниже коде.

Если ребенка не должно быть ограничено на Т можно использовать 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; 
    } 
} 
1

у нас были проблемы с сортировкой по Comparator и выяснили, что есть удобный PrimeFaces TreeUtils.sortNode(TreeNode, Comparator) класс уже предоставленные, который работает как шарм :)

Смежные вопросы