私はJSF2.1とPrimefaces3.3を使用しています。データベースからツリーを作成するためにprimefacesツリーコンポーネントを使用しています。すべてのレベルでツリーノードをアルファベット順に並べ替えたいと思いました。これについて私を助けてください。
3 に答える
経由での並べ替えに問題があり、チャームのように機能Comparator
する便利なPrimeFaces TreeUtils.sortNode(TreeNode、Comparator)クラスがすでに提供されていることがわかりました:)
とComparatorクラスを使用してManagedBeanでPrimefacesDefaultTreeNode
オブジェクトを並べ替える必要があります。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());
これで、すべてのリストが並べ替えられ、ループして適切な親を1つずつ実行できるようになりました。これを決定するアルゴリズムを作成するか、リストに追加せずにツリー階層を構築する別のデータ構造を保持することができます。
もう1つの方法、そしておそらく全体的に簡単な方法は、DefaultTreeNodeクラスをオーバーライドして、それにsortメソッドを与えることです。
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アプローチを使用することもできます。
ベースはprimefacesから取得され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;
}
}