Primefaces 树通过 commandButtons 动态添加兄弟姐妹/children

Primefaces tree dynamically add siblings / children through commandButtons

我正在尝试在 primefaces 中实现动态树结构,其中从 root node 开始的用户将能够通过两个 [= 添加 siblingschildren 到每个节点 commandButtons.

示例如下:

根目录

按下添加兄弟之后

添加child后按下(2次)

this之后,我实现了以下结构:

tree.xhtml

<p:tree id="tree" value="#{treeController.root}" 
    var="node" dynamic="true" cache="false">
    <p:ajax event="expand" listener="#{treeController.onNodeExpand}" />
    <p:treeNode>
       <h:outputText value="#{node}" />
       <p:commandButton style="width:50%; margin: 10px;" value="Add Sibling">
           <p:ajax event="click" listener="#{treeController.addSibling(node)}" update="@this"> 
           </p:ajax>
       </p:commandButton>
       <p:commandButton style="width:50%; margin: 10px;" value="Add Child">
           <p:ajax event="click" listener="#{treeController.addChild(node)}" update="@this"> 
           </p:ajax>
       </p:commandButton>
    </p:treeNode>
</p:tree>

树控制器

     @ManagedBean(name = "treeController")
     @ViewScoped
     public class TreeController implements Serializable {

        private TreeNode root; //getters && setters ommitted

        @PostConstruct
        public void buildTree() {
            this.root = new DefaultTreeNode("Root", null);
            createNode("ROOT", this.root);
        }

        public void onNodeExpand(NodeExpandEvent event) {
            DefaultTreeNode parent = (DefaultTreeNode) event.getTreeNode();
            if (parent.getChildCount() == 1 && parent.getChildren().get(0).getData().toString().equals("ROOT")) {
                parent.getChildren().remove(0);
                createNode(parent.getData().toString()+ "'s Child " + (parent.getChildren().size() + 1), parent);
                createNode(parent.getData().toString()+ "'s Child " + (parent.getChildren().size() + 1), parent);
            }
        }

        public void addSibling(TreeNode node){
            // I need here the corresponding TreeNode element to add to it's parent a new TreeNode
        }

        public void addChild(TreeNode node){
            // I need here the corresponding TreeNode element to add into it a new child
        }

        private void createNode(String tag, TreeNode parent) {
            TreeNode node = new DefaultTreeNode(tag, parent);
            // Create Dummy node, just to make the parent node expandable
            new DefaultTreeNode("ROOT", node);
        }
}

但是,单击按钮我得到 SEVERE [org.primefaces.application.exceptionhandler.PrimeExceptionHandler] (default task-6) Method not found: TreeController.addSibling(java.lang.String) 这是由于函数期望接收字符串参数(节点)造成的。

有什么方法可以检索按钮侦听器上的 TreeNode 引用吗?

也许像 NodeExpandEvent 这样的任何 NodeEvent?

PS: 我正在使用 Primefaces 7.0JSF 2.1

根据 documentation of p:tree var 属性:

Name of the request-scoped variable that'll be used to refer each treenode data.

这是您传递给节点构造函数的第一个参数:

org.primefaces.model.DefaultTreeNode.DefaultTreeNode(Object data, TreeNode parent)

从您的代码中可以看出,异常类型为 String

如果要引用实际节点,请使用 nodeVar 属性代替 var 属性旁边的 /:

nodeVar: Name of the request-scoped variable that'll be used to refer current treenode using EL.

在您的情况下,您可以像这样修改示例:

<p:tree id="tree" value="#{treeController.root}" 
    var="node" nodeVar="theNode" dynamic="true" cache="false">
    <p:ajax event="expand" listener="#{treeController.onNodeExpand}" />
    <p:treeNode>
       <h:outputText value="#{node}" />
       <p:commandButton style="width:50%; margin: 10px;" value="Add Sibling" 
        action="#{treeController.addSibling(theNode)}" update="@this" />
       <p:commandButton style="width:50%; margin: 10px;" value="Add Child"  
        action="#{treeController.addChild(theNode)}" update="@this" />
    </p:treeNode>
</p:tree>