[RESOLVIDO] Problema ao construir p:tree com PrimeFaces

Olá pessoal! Estou seguindo o livro “Programação Java para Web” e estou tendo problemas para construir uma tree com o PrimeFaces.

Está dando erro quando eu passo o evento NodeSelectEvent para meu método selecionar(NodeSelectEvent event) no meu bean. Acusa:

/restrito/categoria.xhtml: The class ‘financeiro.web.CategoriaBean’ does not have the property ‘selecionar’.

O meu bean está assim:

package financeiro.web;

import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.model.SelectItem;

import org.primefaces.event.NodeSelectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;

import financeiro.categoria.Categoria;
import financeiro.categoria.CategoriaRN;
import financeiro.web.util.ContextoUtil;

@ManagedBean(name = "categoriaBean")
@RequestScoped
public class CategoriaBean {

	private TreeNode categoriasTree;
	private Categoria editada = new Categoria();
	private List<SelectItem> categoriasSelect;
	private boolean mostraEdicao = false;

	public void novo() {
		Categoria pai = null;
		if (this.editada.getCodigo() != null) {
			CategoriaRN rn = new CategoriaRN();
			pai = rn.carregar(this.editada.getCodigo());
		}
		this.editada = new Categoria();
		this.editada.setPai(pai);
		this.mostraEdicao = true;
	}

	public void selecionar(NodeSelectEvent event) {
		this.editada = (Categoria) event.getTreeNode().getData();
		Categoria pai = this.editada.getPai();
		this.mostraEdicao = (this.editada != null && pai != null && pai
				.getCodigo() != null);
	}

	public void salvar() {
		ContextoBean contextoBean = ContextoUtil.getContextoBean();
		CategoriaRN rn = new CategoriaRN();
		this.editada.setUsuario(contextoBean.getUsuarioLogado());
		rn.salvar(this.editada);
		reinicia();
	}

	public void excluir() {
		CategoriaRN rn = new CategoriaRN();
		rn.excluir(this.editada);
		reinicia();
	}

	public TreeNode getCategoriasTree() {
		if(this.categoriasTree == null){
			ContextoBean ctx = ContextoUtil.getContextoBean();
			CategoriaRN rn = new CategoriaRN();
			List<Categoria> categs = rn.listar(ctx.getUsuarioLogado());
			this.categoriasTree = new DefaultTreeNode(null,null);
			this.montaDadosTree(this.categoriasTree, categs);
		}
		return this.categoriasTree;
	}
	
	private void montaDadosTree(TreeNode pai, List<Categoria> lista){
		if(lista != null && lista.size() > 0){
			TreeNode filho = null;
			for (Categoria c : lista) {
				filho = new DefaultTreeNode(c, pai);
				this.montaDadosTree(filho, c.getFilhos());
			}
		}
	}
	
	public List<SelectItem> getCategoriasSelect() {
		if(this.categoriasSelect == null){
			this.categoriasSelect = new ArrayList<SelectItem>();
			ContextoBean ctx = ContextoUtil.getContextoBean();
			CategoriaRN rn = new CategoriaRN();
			List<Categoria> categs = rn.listar(ctx.getUsuarioLogado());
			this.montaDadosSelect(this.categoriasSelect, categs, "");
		}
		return this.categoriasSelect;
	} 
	
	private void montaDadosSelect(List<SelectItem> select, List<Categoria> categorias, String prefixo){
		SelectItem item = null;
		if(categorias != null){
			for (Categoria c : categorias) {
				item = new SelectItem(c, prefixo+c.getDescricao());
				item.setEscape(false);
				select.add(item);
				this.montaDadosSelect(select, c.getFilhos(), prefixo + "&nbsp;&nbsp;");
			}
		}
	}
	
	private void reinicia() {
		this.editada = null;
		this.mostraEdicao = false;
		this.categoriasTree = null;
		this.categoriasSelect = null;
	}

	public Categoria getEditada() {
		return editada;
	}

	public void setEditada(Categoria editada) {
		this.editada = editada;
	}

	public boolean isMostraEdicao() {
		return mostraEdicao;
	}

	public void setMostraEdicao(boolean mostraEdicao) {
		this.mostraEdicao = mostraEdicao;
	}

	public void setCategoriasTree(TreeNode categoriasTree) {
		this.categoriasTree = categoriasTree;
	}

	public void setCategoriasSelect(List<SelectItem> categoriasSelect) {
		this.categoriasSelect = categoriasSelect;
	}
	
}

A minha pagina /restrito/categoria.xhtml está assim:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:p="http://primefaces.prime.com.tr/ui">
	<ui:composition template="/templates/interna.xhtml">
		<ui:define name="titulo">Categorias</ui:define>
		<ui:define name="corpo">
			<f:view contentType="text/html">
				<h:panelGrid columns="2" cellpadding="5">
					<h:panelGroup>
						<h:form>
							<p:commandButton value="Novo" action="#{categoriaBean.novo()}" update="edicao"/>
						</h:form>
						<br/>
						<h:form id="arvore">
							<p:tree value="#{categoriaBean.categoriasTree}" var="node" dynamic="false" selectionMode="single" nodeSelectListener="#{categoriaBean.selecionar}" update="edicao" expandAnim="FADE_IN" collapseAnim="FADE_OUT">
								<p:treeNode>
									<h:outputText value="#{node.descricao}"/>
								</p:treeNode>
							</p:tree>
						</h:form>
					</h:panelGroup>
					<h:panelGroup id="edicao">
						<h:messages/>
						<h:form rendered="#{categoriaBean.mostraEdicao}">
							<h:inputHidden value="#{categoriaBean.editada.codigo}"/>
							<h:inputHidden value="#{categoriaBean.editada.fator}"/>
							<h:panelGrid coluns="2">
								<h:outputLabel value="Pai"/>
								<h:selectOneMenu value="#{categoriaBean.editada.pai}">
									<f:selectItems value="#{categoriaBean.categoriasSelect}"/>
								</h:selectOneMenu>
								<h:outputLabel value="Descrição"/>
								<h:outputText/>
								<h:panelGroup>
									<p:commandButton value="Salvar" action="#{categoriaBean.salvar}" update="edicao, arvore"/>
									<p:commandButton value="Excluir" action="#{categoriaBean.excluir}" update="edicao, arvore"/>
								</h:panelGroup>
								<h:outputText/>
								<p:commandButton value="Nova subcategoria" action="#{categoriaBean.novo()}" update="edicao"/>
							</h:panelGrid>
						</h:form>
					</h:panelGroup>
				</h:panelGrid>
			</f:view>
		</ui:define>
	</ui:composition>
</html>

O que pode estar ocorrendo? Me ajudem por favor! Obrigado!

Por alguma razão sombria, a chamada ao método selecionar, nesta linha

<p:tree value="#{categoriaBean.categoriasTree}" var="node" dynamic="false" selectionMode="single" nodeSelectListener="#{categoriaBean.selecionar}" update="edicao" expandAnim="FADE_IN" collapseAnim="FADE_OUT">
Está sendo interpretada como se você tentasse acessar um atributo com este nome (talvez pela não existência dos parênteses, que, até onde sabemos, podem ser suprimidos).

Um detalhe que me chama a atenção é que o argumento passado no teu método selecionar é do tipo NodeSelectEvent, enquanto que, no showcase, temos um ActionEvent.
Será que não é isto? (É uma suposição).

Então, eu vi no showcase do PrimeFaces http://www.primefaces.org/showcase/ui/treeEvents.jsf que no bean ele usa NodeSelectEvent, igual ao meu método

Eu tentei fazer usando a tag ajax também, mas deu o mesmo erro

Tem alguma coisa que eu possa estar esquecendo de colocar?

Obrigado!

Pessoal, consegui resolver!

No site do livro http://www.javaparaweb.com.br/blog/ tinha um problema semelhante, eu troquei a versão do PrimeFaces para 2.1 (estava usando 3.5) e funcionou!

Obrigado!