tree2

actionListener(jsp側)とList children = event.getComponent().getChildren();(Bean側:ActionEvent)の連携部分、
で何を渡しているのかを理解するのにえらい時間かかった…。
http://myfaces.apache.org/tomahawk/apidocs/org/apache/myfaces/custom/tree2/TreeNodeBase.html
非常にカンタンにしか書かれていないけどドキュメント。
Constructor Summary
TreeNodeBase(java.lang.String type, java.lang.String description, java.lang.String identifier, boolean leaf)
つーのが重要でdescriptionとidentifier(こっち省略可)が渡されていたわけですね…。
String型のみでオブジェクト不可なあたりもなんとかならんものか。
以下ソース抜粋。

.jsp
<t:tree2 id="clientTree" showRootNode="false"
			value="#{communityBean.treeData}" var="node" varNodeToggler="t" >
	<f:facet name="KK">
		<h:panelGroup>
			<f:facet name="expand">
				<t:graphicImage value="images/yellow-folder-open.png"
							rendered="#{t.nodeExpanded}" border="0" />
			</f:facet>
			<f:facet name="collapse">
				<t:graphicImage value="images/yellow-folder-closed.png"
							rendered="#{!t.nodeExpanded}" border="0" />
			</f:facet>
				<h:outputText value="#{node.description}" styleClass="nodeFolder" />
				<h:outputText value=" (#{node.childCount})" styleClass="childCount" />
		</h:panelGroup>
	</f:facet>
	<f:facet name="section">
		<h:panelGroup>
			<f:facet name="expand">
				<t:graphicImage value="images/yellow-folder-open.png"
							rendered="#{t.nodeExpanded}" border="0" />
			</f:facet>
			<f:facet name="collapse">
				<t:graphicImage value="images/yellow-folder-closed.png"
							rendered="#{!t.nodeExpanded}" border="0" />
			</f:facet>
			<h:outputText value="#{node.description}" styleClass="nodeFolder" />
			<h:outputText value=" (#{node.childCount})" styleClass="childCount" />
		</h:panelGroup>
	</f:facet>
	<f:facet name="person">
		<h:panelGroup>
			<h:commandLink immediate="true" actionListener="#{topBean.getUserAndEntryByTreeUserId}" action="return">
				<f:param name="userName" value="#{node.identifier}"></f:param>
				<h:graphicImage style="border: 0px" value="/images/document.png" />
				<h:outputText value="#{node.description}" />
			</h:commandLink>
		</h:panelGroup>
	</f:facet>
</t:tree2>

communityBean.treeDataでは表示用のdescriptionとは別にIDをidentifierに仕込んでます。
いったんStringにしてますが。

TopBean.java
public void getUserAndEntryByTreeUserId(ActionEvent event) {
        List children = event.getComponent().getChildren();
        String stringUserId = null ;
        for (Iterator iter = children.iterator(); iter.hasNext();) {
            Object next = iter.next();
            if (next instanceof UIParameter) {
                UIParameter param = (UIParameter) next;
                stringUserId = (String)param.getValue();
            }
        }
	int id = Integer.parseInt(stringUserId);
	ent = entries.getEntriesByUserId(id);	
}

まだvarNodeTogglerの意味やactionListenerとactionの使い分けなんぞ理解しきれてません。

研修覚え書き

やっとTree2から必要な要素の抽出に成功しましたよ。
ほぼ正解なことを書いてあるページを発見していたのに
それを実践していた時、Beanのscopeなんぞを下手にいじっていて
あうとおぶめもりぃえくせぷしょん出して「コレまわんね」と判断していたのが痛い…。
そのへんを師匠に指摘されてscope直したらデキマシタ。
まだまだだなあとちょっと凹む。

tomahawk拡張 Tree2

TreeNodeから要素の引渡しがデキマセン!
ツリー表示をして各要素にリンクを設定し該当項目へ遷移したいわけです。
が、jspにはTreeNode型で渡しているのでそれをBeanへ渡すための設定がどーやるのやら。
リスト型なら処理の仕方わかるんだけどなあ。
日本語のドキュメント少なすぎです。

で、色々調べているうちに見つけた「現在は使わないけど今後使うかもしれない機能」をメモメモ。

画面内に複数のボタン(リンク)があり、そのボタンに応じてアクションが違う場合。
test.jsp

<h:commandButton id="mikura" actionListener="#{testBean.go}" action="御蔵深山"></h:commandButton>
<h:commandButton id="amami" actionListener="#{testBean.go}" action="奄美深山"></h:commandButton>
<h:commandButton id="okinawa" actionListener="#{testBean.go}" action="琉球鋸"></h:commandButton>

TestBean.java

public void go(ActionEvent event){
String island = event.getComponent().getId();

(以下略)
}

これでislandにはcommandButtonの各id値("mikura","amami","okinawa")がそのまま引き渡される。
あー。島行きたい。

tomahawk拡張タグ dataScroller

編。
まず注意。
部分と部分をで包括するように書かないと
遷移したときにページャが消えるとゆー面白い状況に。
(最初の1ページ目だけは表示されてます)
某本のサンプルソースではがなかったりするんですが大丈夫なんだろうか。
そして、部分でデータを参照しているのは
for="のid"だけらしい。
ほんとにこんなんで動くのか不安になるくらいにシンプル。
一番必須そうなこの要素の説明、日本語のドキュメント見当たらないんですがー。
内の
fastStep要素、デフォルト値は10な気がする。

>>JSP部分ソース(datascrollertest.jsp)
<%@ page contentType="text/html; charset=Shift_JIS"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS" />
<title></title>
</head>
<body>
<f:view>
<h:panelGroup>
	<t:dataTable id="data" var="album" value="#{scrollerList.list}"
		preserveDataModel="false" rows="10" border="1">
		<h:column>
			<f:facet name="header"><h:outputText value="id" />
			</f:facet>
			<h:outputText value="#{album.albumId}" />
		</h:column>
		<h:column>
			<f:facet name="header">
				<h:outputText value="アーティスト" />
			</f:facet>
			<h:outputText value="#{album.artist.name}" />
		</h:column>
		<h:column>
			<f:facet name="header">
				<h:outputText value="タイトル" />
			</f:facet>
			<h:outputText value="#{album.title}" />
		</h:column>
	</t:dataTable>

	<h:panelGrid columns="1">
		<t:dataScroller id="scroll_1" 
			for="data" 
			fastStep="10"
			pageCountVar="pageCount" 
			pageIndexVar="pageIndex"
			paginator="true" 
			paginatorMaxPages="9"
			immediate="true">
			<f:facet name="first">
				<t:graphicImage url="images/arrow-first.gif" border="1" />
			</f:facet>
			<f:facet name="last">
				<t:graphicImage url="images/arrow-last.gif" border="1" />
			</f:facet>
			<f:facet name="previous">
				<t:graphicImage url="images/arrow-previous.gif" border="1" />
			</f:facet>
			<f:facet name="next">
				<t:graphicImage url="images/arrow-next.gif" border="1" />
			</f:facet>
			<f:facet name="fastforward">
				<t:graphicImage url="images/arrow-ff.gif" border="1" />
			</f:facet>
			<f:facet name="fastrewind">
				<t:graphicImage url="images/arrow-fr.gif" border="1" />
			</f:facet>
		</t:dataScroller>
	</h:panelGrid>
</h:panelGroup>
</f:view>
</body>
</html>
>>バッキングビーン(ScrollerList.java)またもやほぼサンプルコピペ。
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.apache.myfaces.custom.datascroller.ScrollerActionEvent;
import xxx.xxxxx.kensyu3.AlbumManager;

public class ScrollerList {
	private List _list = new ArrayList();
	
	public ScrollerList() throws SQLException
    {
		_list=new  AlbumManager().tableProduct();	
    }

    public List getList()
    {
        return _list;
    }
}


こんな感じになった。
AlbumManagerは以前作ったデータベースへのinsertやupdateをするクラス。
そのうちの全体をリスト化する部分を流用。
paginatorMaxPages="9"と指定しているのにページャが3までしかないのは
元データが23件しかないからです。
中身もサンプル用にてけとーに入れたデータなので気にしないでください…。

tomahawk拡張タグ tree2

を試してみよう編。
まずfaces-config.xml内のバッキングビーン設定を忘れないこと!
タグ内 :
showNav="false"でナビアイコンなしに。
binding="#{treeBacker.tree}"+入力フォーム設置でファイル直接指定。
showRootNode="false"で最上位フォルダ非表示(?)。

>>JSP部分ソース(tree.jsp)
<%@ page contentType="text/html; charset=Shift_JIS"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS" />
<title></title>
</head>
<body>
<f:view><h:form>
<t:tree2 id="clientTree" value="#{treeBacker.treeData}" var="node"
			varNodeToggler="t">
<f:facet name="section">
	<h:panelGroup>
		<f:facet name="expand">
			<t:graphicImage value="images/yellow-folder-open.png" rendered="#{t.nodeExpanded}" border="0" /> 
		</f:facet>
		<f:facet name="collapse">
			<t:graphicImage value="images/yellow-folder-closed.png" rendered="#{!t.nodeExpanded}" border="0" />						 
		</f:facet>
		<h:outputText value="#{node.description}" styleClass="nodeFolder" />
	</h:panelGroup>
</f:facet>
<f:facet name="person">
	<h:panelGroup>
		<f:facet name="expand">
			<t:graphicImage value="images/yellow-folder-open.png" rendered="#{t.nodeExpanded}" border="0" />							
		</f:facet>
		<f:facet name="collapse">
			<t:graphicImage value="images/yellow-folder-closed.png" rendered="#{!t.nodeExpanded}" border="0" />							
		</f:facet>
		<h:outputText value="#{node.description}" styleClass="nodeFolder" />
		<h:outputText value=" (#{node.childCount})" styleClass="childCount" />
	</h:panelGroup>
</f:facet>
</t:tree2>
</h:form></f:view>
</body>
</html>
>>バッキングビーン(TreeBacker.java)ほぼサンプルコピペ。
import org.apache.myfaces.custom.tree2.HtmlTree;
import org.apache.myfaces.custom.tree2.TreeNode;
import org.apache.myfaces.custom.tree2.TreeNodeBase;
import org.apache.myfaces.custom.tree2.TreeModel;
import org.apache.myfaces.custom.tree2.TreeModelBase;

import javax.faces.context.FacesContext;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.validator.ValidatorException;
import javax.faces.event.ActionEvent;
import java.io.Serializable;

public class TreeBacker implements Serializable
{
	private static final long serialVersionUID = 1L;
    private TreeModelBase     _treeModel;
    private HtmlTree          _tree;

    public TreeNode getTreeData()
    {
    	TreeNode treeData = new TreeNodeBase("section", "会社", false);
    	
    	TreeNodeBase personNode = new TreeNodeBase("section", "部", false);
        
        TreeNodeBase folderNode = new TreeNodeBase("section", "メンバー", false);
        folderNode.getChildren().add(new TreeNodeBase("person", "ひとりめ", true));
        folderNode.getChildren().add(new TreeNodeBase("person", "ふたりめ", true));
        folderNode.getChildren().add(new TreeNodeBase("person", "さんにんめ", true));
        personNode.getChildren().add(folderNode);
        treeData.getChildren().add(personNode);
        
    	return treeData;
    	
    }
	
    public TreeModel getExpandedTreeData()
    {
        return new TreeModelBase(getTreeData());
    }

    public void setTree(HtmlTree tree)
    {
        _tree = tree;
    }

    public HtmlTree getTree()
    {
        return _tree;
    }

    public String expandAll()
    {
        _tree.expandAll();
        return null;
    }

    private String _nodePath;

    public void setNodePath(String nodePath)
    {
        _nodePath = nodePath;
    }

    public String getNodePath()
    {
        return _nodePath;
    }

    public void checkPath(FacesContext context, UIComponent component, java.lang.Object value)
    {
        // make sure path is valid (leaves cannot be expanded or renderer will complain)
        FacesMessage message = null;

        String[] path = _tree.getPathInformation(value.toString());

        for (int i = 0; i < path.length; i++)
        {
            String nodeId = path[i];
            try
            {
                _tree.setNodeId(nodeId);
            }
            catch (Exception e)
            {
                throw new ValidatorException(message, e);
            }

            if (_tree.getNode().isLeaf())
            {
                message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid node path (cannot expand a leaf): "
                        + nodeId, "Invalid node path (cannot expand a leaf): " + nodeId);
                throw new ValidatorException(message);
            }
        }
    }

    public void expandPath(ActionEvent event)
    {
        _tree.expandPath(_tree.getPathInformation(_nodePath));
    }
	
}

こんな感じになった。
tree.jsp内の"#{node.description}"あたりがエラー判定になっているが、
実際にはブラウザ上でちゃんと表示されていてなぞぃ。
なぜか#{node.childCount}はエラーと言われてないあたりも不思議。