ContextMenu has special integration with Tree. Even different menus can be assigned to different node types by matching node types.
<div class="card">
    <h:form>
        <p:growl id="messages" showDetail="true"/>
        <p:tree id="docs" value="#{treeContextMenuView.root}" var="doc" selectionMode="single"
                selection="#{treeContextMenuView.selectedNode}" dynamic="true">
            <p:treeNode expandedIcon="pi pi-folder-open" collapsedIcon="pi pi-folder">
                <h:outputText value="#{doc.name}"/>
            </p:treeNode>
            <p:treeNode type="app" icon="pi pi-save">
                <h:outputText value="#{doc.name}"/>
            </p:treeNode>
            <p:treeNode type="document" icon="pi pi-file">
                <h:outputText value="#{doc.name}"/>
            </p:treeNode>
            <p:treeNode type="excel" icon="pi pi-file-excel">
                <h:outputText value="#{doc.name}"/>
            </p:treeNode>
            <p:treeNode type="travel" icon="pi pi-file-pdf">
                <h:outputText value="#{doc.name}"/>
            </p:treeNode>
            <p:treeNode type="picture" icon="pi pi-image">
                <h:outputText value="#{doc.name}"/>
            </p:treeNode>
            <p:treeNode type="video" icon="pi pi-video">
                <h:outputText value="#{doc.name}"/>
            </p:treeNode>
        </p:tree>
        <p:contextMenu for="docs">
            <p:menuitem value="View" update="messages" action="#{treeContextMenuView.displaySelectedSingle}"
                        icon="pi pi-search"/>
            <p:menuitem value="Delete" update="docs" action="#{treeContextMenuView.deleteNode}"
                        icon="pi pi-times"/>
        </p:contextMenu>
    </h:form>
</div>
package org.primefaces.showcase.view.data.tree;
import org.primefaces.model.TreeNode;
import org.primefaces.showcase.service.DocumentService;
import java.io.Serializable;
import jakarta.annotation.PostConstruct;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
@Named("treeContextMenuView")
@ViewScoped
public class ContextMenuView implements Serializable {
    private TreeNode root;
    private TreeNode selectedNode;
    @Inject
    private DocumentService service;
    @PostConstruct
    public void init() {
        root = service.createDocuments();
    }
    public TreeNode getRoot() {
        return root;
    }
    public TreeNode getSelectedNode() {
        return selectedNode;
    }
    public void setSelectedNode(TreeNode selectedNode) {
        this.selectedNode = selectedNode;
    }
    public void setService(DocumentService service) {
        this.service = service;
    }
    public void displaySelectedSingle() {
        if (selectedNode != null) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Selected", selectedNode.getData().toString());
            FacesContext.getCurrentInstance().addMessage(null, message);
        }
    }
    public void deleteNode() {
        selectedNode.getChildren().clear();
        selectedNode.getParent().getChildren().remove(selectedNode);
        selectedNode.setParent(null);
        selectedNode = null;
    }
}
package org.primefaces.showcase.service;
import org.primefaces.model.CheckboxTreeNode;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import org.primefaces.showcase.domain.Document;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Named;
@Named
@ApplicationScoped
public class DocumentService {
    public TreeNode<Document> createDocuments() {
        TreeNode<Document> root = new DefaultTreeNode(new Document("Files", "-", "Folder"), null);
        TreeNode applications = new DefaultTreeNode(new Document("Applications", "100kb", "Folder"), root);
        TreeNode cloud = new DefaultTreeNode(new Document("Cloud", "20kb", "Folder"), root);
        TreeNode desktop = new DefaultTreeNode(new Document("Desktop", "150kb", "Folder"), root);
        TreeNode documents = new DefaultTreeNode(new Document("Documents", "75kb", "Folder"), root);
        TreeNode downloads = new DefaultTreeNode(new Document("Downloads", "25kb", "Folder"), root);
        TreeNode main = new DefaultTreeNode(new Document("Main", "50kb", "Folder"), root);
        TreeNode other = new DefaultTreeNode(new Document("Other", "5kb", "Folder"), root);
        TreeNode pictures = new DefaultTreeNode(new Document("Pictures", "150kb", "Folder"), root);
        TreeNode videos = new DefaultTreeNode(new Document("Videos", "1500kb", "Folder"), root);
        //Applications
        TreeNode primeface = new DefaultTreeNode(new Document("Primefaces", "25kb", "Folder"), applications);
        TreeNode primefacesapp = new DefaultTreeNode("app", new Document("primefaces.app", "10kb", "Application"), primeface);
        TreeNode nativeapp = new DefaultTreeNode("app", new Document("native.app", "10kb", "Application"), primeface);
        TreeNode mobileapp = new DefaultTreeNode("app", new Document("mobile.app", "5kb", "Application"), primeface);
        TreeNode editorapp = new DefaultTreeNode("app", new Document("editor.app", "25kb", "Application"), applications);
        TreeNode settingsapp = new DefaultTreeNode("app", new Document("settings.app", "50kb", "Application"), applications);
        //Cloud
        TreeNode backup1 = new DefaultTreeNode("document", new Document("backup-1.zip", "10kb", "Zip"), cloud);
        TreeNode backup2 = new DefaultTreeNode("document", new Document("backup-2.zip", "10kb", "Zip"), cloud);
        //Desktop
        TreeNode note1 = new DefaultTreeNode("document", new Document("note-meeting.txt", "50kb", "Text"), desktop);
        TreeNode note2 = new DefaultTreeNode("document", new Document("note-todo.txt", "100kb", "Text"), desktop);
        //Documents
        TreeNode work = new DefaultTreeNode(new Document("Work", "55kb", "Folder"), documents);
        TreeNode expenses = new DefaultTreeNode("document", new Document("Expenses.doc", "30kb", "Document"), work);
        TreeNode resume = new DefaultTreeNode("document", new Document("Resume.doc", "25kb", "Resume"), work);
        TreeNode home = new DefaultTreeNode(new Document("Home", "20kb", "Folder"), documents);
        TreeNode invoices = new DefaultTreeNode("excel", new Document("Invoice.xsl", "20kb", "Excel"), home);
        //Downloads
        TreeNode spanish = new DefaultTreeNode(new Document("Spanish", "10kb", "Folder"), downloads);
        TreeNode tutorial1 = new DefaultTreeNode("document", new Document("tutorial-a1.txt", "5kb", "Text"), spanish);
        TreeNode tutorial2 = new DefaultTreeNode("document", new Document("tutorial-a2.txt", "5kb", "Text"), spanish);
        TreeNode travel = new DefaultTreeNode(new Document("Travel", "15kb", "Folder"), downloads);
        TreeNode hotelpdf = new DefaultTreeNode("travel", new Document("Hotel.pdf", "10kb", "PDF"), travel);
        TreeNode flightpdf = new DefaultTreeNode("travel", new Document("Flight.pdf", "5kb", "PDF"), travel);
        //Main
        TreeNode bin = new DefaultTreeNode("document", new Document("bin", "50kb", "Link"), main);
        TreeNode etc = new DefaultTreeNode("document", new Document("etc", "100kb", "Link"), main);
        TreeNode var = new DefaultTreeNode("document", new Document("var", "100kb", "Link"), main);
        //Other
        TreeNode todotxt = new DefaultTreeNode("document", new Document("todo.txt", "3kb", "Text"), other);
        TreeNode logopng = new DefaultTreeNode("picture", new Document("logo.png", "2kb", "Picture"), other);
        //Pictures
        TreeNode barcelona = new DefaultTreeNode("picture", new Document("barcelona.jpg", "90kb", "Picture"), pictures);
        TreeNode primeng = new DefaultTreeNode("picture", new Document("primefaces.png", "30kb", "Picture"), pictures);
        TreeNode prime = new DefaultTreeNode("picture", new Document("prime.jpg", "30kb", "Picture"), pictures);
        //Videos
        TreeNode primefacesmkv = new DefaultTreeNode("video", new Document("primefaces.mkv", "1000kb", "Video"), videos);
        TreeNode introavi = new DefaultTreeNode("video", new Document("intro.avi", "500kb", "Video"), videos);
        return root;
    }
    public TreeNode<Document> createCheckboxDocuments() {
        TreeNode<Document> root = new CheckboxTreeNode(new Document("Files", "-", "Folder"), null);
        TreeNode applications = new CheckboxTreeNode(new Document("Applications", "100kb", "Folder"), root);
        TreeNode cloud = new CheckboxTreeNode(new Document("Cloud", "20kb", "Folder"), root);
        TreeNode desktop = new CheckboxTreeNode(new Document("Desktop", "150kb", "Folder"), root);
        TreeNode documents = new CheckboxTreeNode(new Document("Documents", "75kb", "Folder"), root);
        TreeNode downloads = new CheckboxTreeNode(new Document("Downloads", "25kb", "Folder"), root);
        TreeNode main = new CheckboxTreeNode(new Document("Main", "50kb", "Folder"), root);
        TreeNode other = new CheckboxTreeNode(new Document("Other", "5kb", "Folder"), root);
        TreeNode pictures = new CheckboxTreeNode(new Document("Pictures", "150kb", "Folder"), root);
        TreeNode videos = new CheckboxTreeNode(new Document("Videos", "1500kb", "Folder"), root);
        //Applications
        TreeNode primeface = new CheckboxTreeNode(new Document("Primefaces", "25kb", "Folder"), applications);
        TreeNode primefacesapp = new CheckboxTreeNode("app", new Document("primefaces.app", "10kb", "Application"), primeface);
        TreeNode nativeapp = new CheckboxTreeNode("app", new Document("native.app", "10kb", "Application"), primeface);
        TreeNode mobileapp = new CheckboxTreeNode("app", new Document("mobile.app", "5kb", "Application"), primeface);
        TreeNode editorapp = new CheckboxTreeNode("app", new Document("editor.app", "25kb", "Application"), applications);
        TreeNode settingsapp = new CheckboxTreeNode("app", new Document("settings.app", "50kb", "Application"), applications);
        //Cloud
        TreeNode backup1 = new CheckboxTreeNode("document", new Document("backup-1.zip", "10kb", "Zip"), cloud);
        TreeNode backup2 = new CheckboxTreeNode("document", new Document("backup-2.zip", "10kb", "Zip"), cloud);
        //Desktop
        TreeNode note1 = new CheckboxTreeNode("document", new Document("note-meeting.txt", "50kb", "Text"), desktop);
        TreeNode note2 = new CheckboxTreeNode("document", new Document("note-todo.txt", "100kb", "Text"), desktop);
        //Documents
        TreeNode work = new CheckboxTreeNode(new Document("Work", "55kb", "Folder"), documents);
        TreeNode expenses = new CheckboxTreeNode("document", new Document("Expenses.doc", "30kb", "Document"), work);
        TreeNode resume = new CheckboxTreeNode("document", new Document("Resume.doc", "25kb", "Resume"), work);
        TreeNode home = new CheckboxTreeNode(new Document("Home", "20kb", "Folder"), documents);
        TreeNode invoices = new CheckboxTreeNode("excel", new Document("Invoice.xsl", "20kb", "Excel"), home);
        //Downloads
        TreeNode spanish = new CheckboxTreeNode(new Document("Spanish", "10kb", "Folder"), downloads);
        TreeNode tutorial1 = new CheckboxTreeNode("document", new Document("tutorial-a1.txt", "5kb", "Text"), spanish);
        TreeNode tutorial2 = new CheckboxTreeNode("document", new Document("tutorial-a2.txt", "5kb", "Text"), spanish);
        TreeNode travel = new CheckboxTreeNode(new Document("Travel", "15kb", "Folder"), downloads);
        TreeNode hotelpdf = new CheckboxTreeNode("travel", new Document("Hotel.pdf", "10kb", "PDF"), travel);
        TreeNode flightpdf = new CheckboxTreeNode("travel", new Document("Flight.pdf", "5kb", "PDF"), travel);
        //Main
        TreeNode bin = new CheckboxTreeNode("document", new Document("bin", "50kb", "Link"), main);
        TreeNode etc = new CheckboxTreeNode("document", new Document("etc", "100kb", "Link"), main);
        TreeNode var = new CheckboxTreeNode("document", new Document("var", "100kb", "Link"), main);
        //Other
        TreeNode todotxt = new CheckboxTreeNode("document", new Document("todo.txt", "3kb", "Text"), other);
        TreeNode logopng = new CheckboxTreeNode("picture", new Document("logo.png", "2kb", "Picture"), other);
        //Pictures
        TreeNode barcelona = new CheckboxTreeNode("picture", new Document("barcelona.jpg", "90kb", "Picture"), pictures);
        TreeNode primeng = new CheckboxTreeNode("picture", new Document("primefaces.png", "30kb", "Picture"), pictures);
        TreeNode prime = new CheckboxTreeNode("picture", new Document("prime.jpg", "30kb", "Picture"), pictures);
        //Videos
        TreeNode primefacesmkv = new CheckboxTreeNode("video", new Document("primefaces.mkv", "1000kb", "Video"), videos);
        TreeNode introavi = new CheckboxTreeNode("video", new Document("intro.avi", "500kb", "Video"), videos);
        return root;
    }
}
package org.primefaces.showcase.domain;
import java.io.Serializable;
public class Document implements Serializable, Comparable<Document> {
    private String name;
    private String size;
    private String type;
    public Document(String name, String size, String type) {
        this.name = name;
        this.size = size;
        this.type = type;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSize() {
        return size;
    }
    public void setSize(String size) {
        this.size = size;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    //Eclipse Generated hashCode and equals
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + ((size == null) ? 0 : size.hashCode());
        result = prime * result + ((type == null) ? 0 : type.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Document other = (Document) obj;
        if (name == null) {
            if (other.name != null) {
                return false;
            }
        }
        else if (!name.equals(other.name)) {
            return false;
        }
        if (size == null) {
            if (other.size != null) {
                return false;
            }
        }
        else if (!size.equals(other.size)) {
            return false;
        }
        if (type == null) {
            if (other.type != null) {
                return false;
            }
        }
        else if (!type.equals(other.type)) {
            return false;
        }
        return true;
    }
    @Override
    public String toString() {
        return name;
    }
    public int compareTo(Document document) {
        return this.getName().compareTo(document.getName());
    }
}