[ x:treeでノードをクリックした時に動作する処理の作り方サンプル ]

■2005/10/4
 Hepon

■環境:JSF1.1
    MyFaces1.0.9
    WindowsXP
    ExadelStudioPro3.0.3

■今回のsampleは、「JSFタグサンプル」に掲載してある
 「x:tree」をベースにしているので、
 変更の無い箇所のソースはここでは掲載していません。
 必要であれば「x:tree」の方も見て下さい。
 
■さて今回は、x:treeのノードをクリックした時に、
 ノードごとに別に値をBeanに入れたり、
 ノードごとに別のJavaScriptを動かしたり、
 そんなようなことがしたいなぁ、と思って
 作成しました。
 
 でも実際「ノードごとに別の」という部分は
 このサンプルの中では作成していません。
 それは、このサンプルを元に簡単に作成できるから
 書くまでもないし、サンプルが見にくくなるので。
 
■時間があれば後で解説を記述します。
 ひとまず画面写真とソースをどうぞ。




★TreeBean.java
package demo;

import org.apache.myfaces.custom.tree.DefaultMutableTreeNode;
import org.apache.myfaces.custom.tree.model.DefaultTreeModel;

public class TreeBean {
    
    //test001がノードの情報を受け取り、保持する
    private String test001;
    //test002はダミーであって、この変数は実際には使用されない
    private String test002;
    
    //ツリー
    private DefaultTreeModel tree;
    
    //以下、ノード
    private DefaultMutableTreeNode treeRoot;
    
    private DefaultMutableTreeNode child01;
    private DefaultMutableTreeNode child02;
    private DefaultMutableTreeNode child03;
    
    private DefaultMutableTreeNode child01_01;
    private DefaultMutableTreeNode child01_02;
    
    private DefaultMutableTreeNode child02_01;
    private DefaultMutableTreeNode child02_01_node;
    
    //コンストラクタ
    public TreeBean(){
        
        test001 = "default";
        
        //root
        treeRoot = new DefaultMutableTreeNode("ROOT");
            child01 = new DefaultMutableTreeNode("分類01");
            child02 = new DefaultMutableTreeNode("分類02");
            child03 = new DefaultMutableTreeNode("分類03");
            treeRoot.insert(child01);
            treeRoot.insert(child02);
            treeRoot.insert(child03);
            
                //分類01
                child01_01 = new DefaultMutableTreeNode("うどん");
                child01_02 = new DefaultMutableTreeNode("そば");
                child01.insert(child01_01);
                child01.insert(child01_02);
                
                //分類02
                child02_01 = new DefaultMutableTreeNode("ラーメン");
                child02.insert(child02_01);
                
                    //ラーメン
                    child02_01_node = new DefaultMutableTreeNode("醤油ラーメン");
                    child02_01.insert(child02_01_node);
                    child02_01_node = new DefaultMutableTreeNode("味噌ラーメン");
                    child02_01.insert(child02_01_node);
                    child02_01_node = new DefaultMutableTreeNode("豚骨ラーメン");
                    child02_01.insert(child02_01_node);
                    
        //このtreeをx:treeに与える
        tree = new DefaultTreeModel(treeRoot);
        
    }

    public DefaultTreeModel getTree() {
        return tree;
    }

    public void setTree(DefaultTreeModel tree) {
        this.tree = tree;
    }

    public String getTest001() {
        return test001;
    }

    public void setTest001(String test001) {
        this.test001 = test001;
    }

    /*
     これはtest002のゲッターだが、test001を返している。
     
    これは、ツリーのあるJSP内にtest001をh:inputHiddenで持とうとすると、
    リスナーのTreeActionでtest001に値をセットしても、画面に戻った時に、
    以前の値に戻ってしまうからである。
    よって、このJSFの奇怪な行動を避ける為、ツリーのあるJSP内にはtest002を設置し、
    しかしそのtest002のゲッターではtest001を返す、ということを行っているのである。
    
    何か他にいい方法ありませんか・・・???
     */
    public String getTest002() {
        return test001;
    }

    public void setTest002(String test002) {
        this.test002 = test002;
    }
    
}

★tree.jsp
<%@ page contentType="text/html;charset=MS932" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://myfaces.sourceforge.net/tld/myfaces_ext_0_9.tld" prefix="x" %>

<!-- ********************* -->

<HTML>
    <HEAD>
        <!--HTMLのメタタグ-->
        <meta http-equiv="Content-Language" content="ja" />
        <meta http-equiv="Content-Type" content="Pragma: No-Cache" />
        <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS" />
        <script type="text/javascript">
        <!--
            function test(){
                if(document.form001[0].value=="default"){
                    ;
                }else{
                    alert("Beanに値がセットされました!");
                }
            }
        -->
        </script>
        <title>x:treeでノードをクリックした時に動作する処理の作り方サンプル</title>
    </HEAD>
    <body bgcolor="white" onload="test()">
    
    <f:view>
    <h:form id="form001">
    
    <!-- ********************* -->
    
        <h:inputHidden id="Hidden001" value="#{TreeBean.test002}" />
    
        <B><h:outputText value="x:treeでノードをクリックした時に動作する処理の作り方サンプル"/></B><br>
        <h:outputText value="2005/10/4/Tue/Hepon"/><br><br>
        
        <!-- ↓ツリー↓ -->
        <x:tree id="tree" value="#{TreeBean.tree}"
                nodeClass="treenode"
                selectedNodeClass="treenodeSelected"
                expandRoot="true">
                
                <x:treeSelectionListener type="demo.TreeAction" />
                
        </x:tree>
        
    <!-- ********************* -->
    
    </h:form>
    </f:view>
    
    </body>
</HTML>  

★TreeAction.java
package demo;

import javax.faces.context.FacesContext;

import org.apache.myfaces.custom.tree.DefaultMutableTreeNode;
import org.apache.myfaces.custom.tree.event.TreeSelectionEvent;
import org.apache.myfaces.custom.tree.event.TreeSelectionListener;


public class TreeAction implements TreeSelectionListener{

    
    public TreeAction(){
        super();
    }

    public void valueChanged(TreeSelectionEvent event) {
        
        //選択された行の情報を取得する
        DefaultMutableTreeNode selectNode = 
            (DefaultMutableTreeNode)event.getNewSelectionPath().getLastPathComponent();
        
        //SessionにあるBeanを取得する
        FacesContext context = FacesContext.getCurrentInstance();
        TreeBean bb = 
            (TreeBean)context.getApplication().getVariableResolver().resolveVariable(context, "TreeBean");
        
        //選択された行の情報をBeanにセット。
        bb.setTest001(selectNode.getUserObject().toString());
        
    }
    
}