毎回調べるのもあれなので個人的なメモ。
pom.xmlにrichfacesを追加
<dependency> <groupId>org.richfaces.ui</groupId> <artifactId>richfaces-components-ui</artifactId> <version>${richfaces.version}</version> </dependency> <dependency> <groupId>org.richfaces.core</groupId> <artifactId>richfaces-core-impl</artifactId> <version>${richfaces.version}</version> </dependency>
${richfaces.version}はpropertiesタグのところで定義してる。ここでは現時点で最新の4.2.3.Final。
<properties> ...省略... <richfaces.version>4.2.3.Final</richfaces.version> </properties>
ツリーに紐づけるオブジェクトの作成
ここは何でもいい。とりあえず、以下のようなツリー構造をもつItemというクラスを作りました。
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package okazuki.mavenproject4; import java.util.Arrays; import java.util.List; public class Item { private String text; private List<Item> items; public Item() { } public Item(String text, Item... items) { this.text = text; this.items = Arrays.asList(items); } public String getText() { return text; } public void setText(String text) { this.text = text; } public List<Item> getItems() { return items; } public void setItems(List<Item> items) { this.items = items; } }
treeコントロールのノードのクラスを作成
さっきのItemクラスをさくっと再利用できればいいのですが、どうもTreeNodeインターフェース実装してないとダメそうなので…。TreeNodeImpleという実装済みクラスがあるので、これを継承してItemクラスを内部に持つItemTreeNodeクラスを作ります。
class ItemTreeNode extends TreeNodeImpl { private Item item; // ItemからTreeNodeを組み立てる public ItemTreeNode(Item item) { this.item = item; if (item.getItems() == null) { return; } if (!item.getItems().isEmpty()) { int index = 0; for (Item i : item.getItems()) { // addChildの第一引数は、要素を一意に識別できるものであればいい this.addChild(index++, new ItemTreeNode(i)); } } } // とりあえず簡易的にtoStringの結果を表示するように @Override public String toString() { return item.getText(); } // 子要素を持ってなかったら葉 @Override public boolean isLeaf() { if (item.getItems() == null) { return true; } return item.getItems().isEmpty(); } }
ManagedBeanでTreeNodeのプロパティを公開
適当にManagedBeanを作ってtreeコントロールに紐づけるためのTreeNode型のプロパティを作ります。ここではIndexPageというManagedBeanにrootという名前でプロパティを作りました。
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package okazuki.mavenproject4; import java.util.Arrays; import java.util.List; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import org.richfaces.model.TreeNode; import org.richfaces.model.TreeNodeImpl; /** * * @author Kazuki */ @ManagedBean @RequestScoped public class IndexPage { private TreeNode root; ...省略... public TreeNode getRoot() { return root; } public void setRoot(TreeNode root) { this.root = root; } }
あとは、要件に応じて適切なタイミングでrootプロパティにTreeNodeをセットします。とりあえず、今回はコンストラクタでさくっと作りました。気を付けないといけないのは、TreeNodeのルートは、画面に表示されないっぽい?というところです。
public IndexPage() { // Itemクラスを適当に組み立てる List<Item> items = Arrays.asList( new Item("item1", new Item("item1-1"), new Item("item1-2"), new Item("item1-3", new Item("item1-3-1"), new Item("item1-3-2"))), new Item("item2", new Item("item2-1"), new Item("item2-2")), new Item("item3", new Item("item3-1"), new Item("item3-2")), new Item("item4", new Item("item4-1")), new Item("item5")); // rootは表示されないっぽい? this.root = new TreeNodeImpl(false); // rootの下に子をぶら下げていく int index = 0; for (Item item : items) { this.root.addChild(index++, new ItemTreeNode(item)); } }
画面のマークアップ
あとは、画面にtreeコントロール置いてやるだけです。treeコントロールを置いてtreeNodeを中に置いて、どうやって表示するか定義します。
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:rich="http://richfaces.org/rich"> <h:head> <title>Facelet Title</title> </h:head> <h:body> <rich:tree value="#{indexPage.root}" var="item" toggleType="client"> <rich:treeNode> <!-- itemはItemTreeNodeクラス --> <h:outputText value="#{item}" /> </rich:treeNode> </rich:tree> </h:body> </html>
treeNodeは、もうちょっと色々カスタマイズできるみたいだけど、とりあえず基本はこんな感じで。toggleType="client"でクライアントサイドでツリーの展開とかやるってことみたいですわ。