とりあえずメモメモ。
xhtmlでのポイントは、ajaxでやりたいからselectionTypeをajaxにしているところと、選択結果をレンダリングするためのrenderをoutpanelにしているところです。
outpanelは、ただのoutputTextです。
その他の、toggleTypeをajaxにしたりtreeModelRecursiveAdapterは、ここの本質的な内容じゃないです。
<h:form> <h:panelGrid columns="2" columnClasses="col1,col2"> <rich:tree var="item" toggleType="ajax" selectionType="ajax" render="outpanel" selectionChangeListener="#{indexPage.selectionChange}"> <rich:treeNode> <h:outputText value="#{item.name}" /> </rich:treeNode> <rich:treeModelRecursiveAdaptor roots="#{indexPage.roots}" nodes="#{item.items}" leaf="#{item.leaf}" /> </rich:tree> <rich:panel> <h:outputText id="outpanel" value="#{indexPage.selectedItem.name}" /> </rich:panel> </h:panelGrid> </h:form>
Javaのほうは、Treeに表示するためのデータのItemクラス。延々と子要素を持つツリー構造のデータです。
package sample.mavenproject2; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.UUID; public class Item implements Serializable { private static Random RANDOM = new Random(); private List<Item> items; private UUID id; private String name; private boolean leaf; public Item() { this.id = UUID.randomUUID(); this.items = new ArrayList<>(); leaf = RANDOM.nextBoolean(); } public Item(String name) { this(); this.name = name; } public List<Item> getItems() { if (this.isLeaf()) { return items; } if (this.items.isEmpty()) { for (int i = 0; i < 10; i++) { this.items.add(new Item(this.getName() + "-" + i)); } } return items; } public UUID getId() { return id; } public void setId(UUID id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isLeaf() { return leaf; } }
initで、適当なデータを作るメソッドはおいといて、ポイントはselectionChangeメソッドです。このメソッドがrich:treeタグでselectionChangeListenerに設定したメソッドです。
引数に、TreeSelectionChangeEventを持つ点がUIコンポーネントに依存しそうなのが個人的に嫌な感じです。
あとは、rowkeyを一時的に差し替えてgetRowDataメソッドで選択中のデータを取得しています。ここらへんハック的な感じがするので個人的に嫌ですね・・・。
ここらへんは、UITreeUtilsクラスにあるように何処かにかくしてしまいたいですね。
package sample.mavenproject2; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.annotation.PostConstruct; import javax.faces.bean.ManagedBean; import javax.faces.bean.ViewScoped; import org.richfaces.component.UITree; import org.richfaces.event.TreeSelectionChangeEvent; @ManagedBean @ViewScoped public class IndexPage implements Serializable { private static final long serialVersionUID = 1L; private List<Item> roots; private Item selectedItem; @PostConstruct public void init() { this.roots = new ArrayList<>(); for (int i = 0; i < 10; i++) { this.roots.add(new Item("Item-" + i)); } } public void selectionChange(TreeSelectionChangeEvent event) { this.setSelectedItem(UITreeUtils.getSelectedData(Item.class, event)); } public List<Item> getRoots() { return roots; } public void setRoots(List<Item> roots) { this.roots = roots; } public Item getSelectedItem() { return selectedItem; } public void setSelectedItem(Item selectedItem) { this.selectedItem = selectedItem; } } class UITreeUtils { public static <T> T getSelectedData(Class<T> clazz, TreeSelectionChangeEvent event) { UITree tree = (UITree) event.getComponent(); List<Object> selection = new ArrayList<>(event.getNewSelection()); if (selection.isEmpty()) { return null; } Object rowKey = tree.getRowKey(); tree.setRowKey(selection.get(0)); Object result = tree.getRowData(); tree.setRowKey(rowKey); return clazz.cast(result); } }