Como colocar link no <p:Tree> (primeFaces)?

55 respostas
D

pessoal tenho uma tela q possui um frame e uma Tree fora dele, eu quero q os nós da minha Tree atualizem meu frame, estou usando primeFaces mas nao sei como vou fzr isso!!!

55 Respostas

F

dentro do teu <p:column> você faz isso direto não?

D

nao eu nem uso table, ele é construido assim:

<p:tree value="#{indexBean.root}" var="node"> <p:treeNode> <h:outputText value="#{node}"/> </p:treeNode> </p:tree>

D

Isso não funciona?

<h:form>
  <p:tree value="#{indexBean.root}" var="node">
    <p:treeNode>
      <h:commandLink value="#{node}" action="#{indexBean.doSth}" />
    </p:treeNode>
  </p:tree>
</h:form>
F

dijava:
nao eu nem uso table, ele é construido assim:

<p:tree value="#{indexBean.root}" var="node"> <p:treeNode> <h:outputText value="#{node}"/> </p:treeNode> </p:tree>

Eu tinha entendido que era treeTable,
mas o código do dev.rafael deve funcionar corretamente

D

eu ate pensei no commandLink, mas minha duvida estava nesse ponto imagenine a estrutura:

+no.1
–+no1.1
–+no1.2
+no.2
–+no2.1
–+no2.2

ai se eu colocar o action, ele vai para todos, o q quero é q setar para o meu frame somente os nos filhos, no caso o no1.1,no1.2,no2.1,no2.2 e tb como vou colocar o target para o meu frame?

D
<h:form>
  <p:tree value="#{indexBean.root}" var="node">
    <p:treeNode>
      <h:commandLink value="#{node}" action="#{indexBean.doSth(node)}" />
    </p:treeNode>
  </p:tree>
</h:form>

Ai no servidor vc atualiza o form com os nós filho de node.

D

eu entendi, mas nao sei como fazer isso no metodo doSth(node), como eu vou alterar o form no servidor, colocando a acao e “setando” o target ?

D

Os campos do seu form não estão vinculados à atributos de algum ManagedBean? Então é o método doSth(node) usar o objeto recebito p/ alterar os atributos. Quando a página for atualizada os campos do form vão conter as informações q vc colocou nesse atributos.

D

sim, o objeto que vou receber é um TreeNode, mas ele nao da opcao para eu mandar a url e nem target

D

Não o objeto q vc vai receber é do tipo declarado em “var” no seu p:tree. Ou seja, o tipo dos items armazenados em “#{indexBean.root}”.

D

entao esse root é um TreeNode !

@ManagedBean
public class IndexBean {
	private TreeNode root;
   
	  
    public IndexBean() {
        root = new DefaultTreeNode("Root", null);
        TreeNode node0 = new DefaultTreeNode("Node 0", root);  
        TreeNode node1 = new DefaultTreeNode("Node 1", root);
          
        TreeNode node00 = new DefaultTreeNode("Node 0.0", node0);        
        TreeNode node01 = new DefaultTreeNode("Node 0.1", node0);  
          
        TreeNode node010 = new DefaultTreeNode("Node 1.0", node1);  
        TreeNode node011 = new DefaultTreeNode("Node 1.1", node1);  

    }  
  
    public TreeNode getRoot() {
        return root;
    }
D
public void doSth(TreeNode node) {
  Object data = node.getData();
  // .. ai é só fazer a "mágica".
}
D

dev.Rafael me desculpa, mas realmente eu nao sei como eu vou setar a url e o target tem como vc colocar um exemplo ai para eu ver !

D

Faz o seguinte, posta o código q vc está usando ai

D

ManagedBean

import javax.faces.bean.ManagedBean;

import org.primefaces.model.TreeNode;
import org.primefaces.model.DefaultTreeNode;
@ManagedBean
public class IndexBean {
	private TreeNode root;
   
	  
    public IndexBean() {
        root = new DefaultTreeNode("Root", null);
        TreeNode node0 = new DefaultTreeNode("Node 0", root);  
        TreeNode node1 = new DefaultTreeNode("Node 1", root);      
        TreeNode node00 = new DefaultTreeNode("Node 0.0", node0);        
        TreeNode node01 = new DefaultTreeNode("Node 0.1", node0);  
          
        TreeNode node010 = new DefaultTreeNode("Node 1.0", node1);  
        TreeNode node011 = new DefaultTreeNode("Node 1.1", node1);
          
        TreeNode node000 = new DefaultTreeNode("Node 0.0.0", node00);  
        TreeNode node001 = new DefaultTreeNode("Node 0.0.1", node00);  
        TreeNode node0010 = new DefaultTreeNode("Node 0.1.0", node01);
    }  

    public TreeNode getRoot() {
        return root;
    }
    
}

xhtml

<h:body>
	 <h:form>
	 		<div id="divArvoredos">
				<p:tree value="#{indexBean.root}" var="node">
     		   		<p:treeNode>         				
         				<h:link value="#{node}">
     		   		</p:treeNode>
		   		</p:tree>
		    </div>

		   <iframe src="" name="miolo" class="coisa" width="730" marginwidth="0" height="518" marginheight="0" align="top" scrolling="no" frameborder="0">
   		   </iframe>
    </h:form>
	</h:body>
D
<h:body>  
     <h:form>  
            <div id="divArvoredos">  
                <p:tree value="#{indexBean.root}" var="node">  
                    <p:treeNode>                        
                        <h:link value="#{node}" target="miolo" outcome="/a_pagina_q_vai_no_frame?id=#{node.data}">  
                    </p:treeNode>  
                </p:tree>  
            </div>  
  
           <iframe src="" name="miolo" class="coisa" width="730" marginwidth="0" height="518" marginheight="0" align="top" scrolling="no" frameborder="0">  
           </iframe>  
    </h:form>  
</h:body>

A página q vai no frame fica mais ou menos assim:

<h:body>
  <f:metadata>
    <f:viewParam name="id" value="#{bean.id}" />
  </f:metadata>

  <!-- Aqui ficam os componentes q vão mostrar os dados -->
</h:body>

Ai vc só precisa de um bean p/ expor essas informações.

@Named
@RequestScoped
public class Bean {
  private Pessoa pessoaSelecionada;

  public Pessoa getPessoaSelecionada() {
    return pessoaSelecionada;
  }

  public String getId() {
    return pessoaSelecionada.getId();
  }

  public void setId(String id) {
    pessoaSelecionada = em.find(Pessoa.class, id);
  }
}
D

po obrigado eu consegui setar para o frame, mas ainda nao consegui pegar quem esta mandando a requisicao, nao entendi muito esse passo como eu posso fazer isso e a anotacao @Named q vc colocou é de que pacote e para q server, pq eu nao achei nas minhas bibliotecas ?

D

Essa anotação @Named tem a mesma função de @ManagedBean, mas vc deve usar @Named se estiver usando CDI. Eu, particularmente, não me vejo mais desenvolvendo em JSF sem CDI. A anotação @Named estará presente em qualquer servidor JEE6 (como Glassfish). Se vc não estiver usando um servidor JEE6 vc ainda pode adicionar CDI adicionando as bibliotecas do WELD ao seu projeto.

O q é isso de “quem está mandando a requisição”? Vc quer saber o usuário q o está fazendo ou a página de origem?

D

blz agora acho q entendi, vou simplificar ainda estou aprendendo jsf, e injecao de dependencia aina nao vi, mas dei uma olhada rapida aqui e aprendi um pouco, tive que importar a bilbioteca weld-servlet, configurar o listener no meu web.xml, para poder coloca a anotacao @named, ai blz so q quando eu vou ver minha aplicacao ela da

javax.servlet.ServletException: Servlet execution threw an exception
	com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:542)
	com.sun.faces.application.view.JspViewHandlingStrategy.executePageToBuildView(JspViewHandlingStrategy.java:355)
	com.sun.faces.application.view.JspViewHandlingStrategy.buildView(JspViewHandlingStrategy.java:130)
	com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:106)
root cause

java.lang.StackOverflowError
	javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
	javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
D

Que server vc está usando?

D

tomcat 6.0.20

D

http://docs.jboss.org/weld/reference/1.0.0/en-US/html/environments.html

D

so nao entendi o META-INF/context.xml in the web root, é para o <Context> <Resource name="BeanManager" auth="Container" type="javax.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory"/> </Context>
aonde ?

D

Q IDE vc está utilizando?

D

eclipse

D

então deve haver algo como:

+ MyApp
- + WebContent
- - + META-INF
- - - + context.xml
- - + WEB-INF
D

tb achei, fiz o passo a passo eu ainda nao rolou mesmo erro !

D

so dar para fzr isso com injecao ?

D

NP, vc vaz de qualquer jeito.

D

NP ? nao entendi ?

D

O CDI é apenas mais um framework q vai te ajudar. Mas ele não é obrigatório. Vc pode desenvolver JSF2 sem o CDI sem problemas.

D

sim mas ai voltamos para aquele problema como eu vou pegar o objeto selecionada dentro do frame ?

D

Problema nenhum. Basta substituir o @Named por @ManagedBean e está tudo resolvido.

D

tentei ja fazer com isso, mas nao sei o q esta havendo com request nao esta pegando o objeto !

D

q versão do JSF vc está usando?

D

2.0

D

no seu método public void doSth(TreeNode nt) o q está chegando p/ parametro?

D

eu nao criei esse metodo eu seto a pagina no outcome=“teste.xhtml?id=#{node}”

D

Nesse caso, vc está passando parâmetros através de uma requisição get. Esses parametros não podem ser de outro tipo q não String (até podem mais ai vc iria precisar de um Converter p/ lidar com isso). Vc vai fazer outcome=“teste?id=#{node.data}”. A extensão .xhtml não é necessária, o próprio JSF pode resolver isso p/ vc. Além disso
a página q será apresentada deve ter uma sessão f:metadata onde vc vai declarar os f:viewParams e associa-los à atributos de algum bean gerenciado. Exatamente como no ultimo código q postei.

D

entao eu criei uma pagina de teste e ficou assim

teste.xhtml // pagina dentro do frame
<h:body>
			<f:metadata>   
    			<f:viewParam id="id" value="#{testeBean.id}" />   
  			</f:metadata>
		<h:form>		   
			<h:outputText value="#{testeBean.id}"/>
			<br/>
			<h:outputText value="to aki"/>
		</h:form>
	</h:body>
@RequestScoped
@ManagedBean
public class TesteBean {

	@ManagedProperty(name="id",value="#{requestScope.id}")
	private TreeNode id;

	public TreeNode getId(){
		return id;
	}
	public void setId(TreeNode id){
		this.id = id;
	}

eu ate coloquei o ManagedProperty para ver ser pega o parametro id mas da "java.lang.NullPointerException: Erro de argumento: O parâmetro key é nulo"

D

kra, é uma requisição GET. Vc não está recebendo um TreeNode vc está recebendo uma String. Se vc quer receber um TreeNode vai precisar criar um custom Converter p/ converter a string q vc está recebendo em um TreeNode.

D

como eu posso fazer para ele me mandar via post ?

D

Não pode!

D

entendi, mas por mas q seja uma string, nem ela eu estou recebendo se nao o erro seria ClassCastException e nao NullPotinterException, se eu quizer pegar a string como faco ? com o custom Converter ?

D

Cara, substitui o:

<h:link value="Editar" target="miolo" outcome="teste.xhtml?id=#{node}" />

por:

<h:commandLink value="Editar" action="#{testeBean.edit(node)}" />

e no ManagedBean:

@ManagedBean  
@RequestScoped  
public class TesteBean {  
 
  private TreeNode node;  
  
  public TreeNode getNode() {
    return node;
  }

  public String editNode(TreeNode node) {
    this.node = node;
    return "/teste";
  }
}
D

Cara, substitui o:
view plaincopy to clipboardprint?
<h:link value=“Editar” target=“miolo” outcome=“teste.xhtml?id=#{node}” />
<h:link value=“Editar” target=“miolo” outcome=“teste.xhtml?id=#{node}” />

por:
view plaincopy to clipboardprint?
<h:commandLink value=“Editar” action="#{testeBean.edit(node)}" />

nao posso o MangedBean responsavel por essa tela é o IndexBean, se eu colocar outro bean associado ele da pau, esse “testeBean.edit(node)}” teria que ser indexBean e ainda caio no mesmo ponto como faco para poder pegar do outro lado ?

D

Não existe isso de bean responsável pela tela. Em JSF n ManagedBeans podem ser associados aos diferentes componentes da sua view. Esse código funciona perfeitamente, eu garanto.

D
<p:tree value="#{indexBean.root}" var="node">
     		   		<p:treeNode>
         				<h:commandLink value="#{node}" target="miolo" action="#{testeBean.editar(node)}"/>
     		   		</p:treeNode>
		   		</p:tree>
javax.servlet.ServletException: /index.xhtml @18,96 action="#{testeBean.editar(node)}" Error Parsing: #{testeBean.editar(node)}
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:325)
	br.com.jsync.myjob.util.EntityManagerFiltro.doFilter(EntityManagerFiltro.java:45)

root cause

javax.faces.view.facelets.TagAttributeException: /index.xhtml @18,96 action="#{testeBean.editar(node)}" Error Parsing: #{testeBean.editar(node)}
	com.sun.faces.facelets.tag.TagAttributeImpl.getMethodExpression(TagAttributeImpl.java:225)
	com.sun.faces.facelets.tag.jsf.ActionSourceRule$ActionMapper2.applyMetadata(ActionSourceRul
D

Kra eu estou no final do meu expediente. Amanhã eu vejo isso p/ vc.

D

blz tb estou amanha se fala ate mais e obrigadao !!!

D

Ta ai kra.

A view:

<?xml version='1.0' encoding='UTF-8' ?>
<!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:p="http://primefaces.prime.com.tr/ui">
    <h:head>
        <title>Prime Tree</title>
    </h:head>
    <h:body>
        <h:form>
            <p:tree value="#{treeBean.root}" var="node"
                    nodeSelectListener="#{treeBean.nodeSelected}"
                    selectionMode="single"
                    update="detail">
                <p:treeNode>
                    <h:outputText value="#{node}" />
                </p:treeNode>
            </p:tree>
            <h:panelGroup id="detail">
                <iframe src="faces/detail.xhtml"></iframe>
            </h:panelGroup>
        </h:form>
    </h:body>
</html>

A view q aparece no iframe:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html">
<h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>PrimeTree - Detail</title>
</h:head>
<h:body>
    <h:outputText value="Hello #{treeBean.selected.data}!" />
</h:body>
</html>

E o ManagedBean:

@ManagedBean
public class TreeBean implements Serializable {

    private TreeNode root;
    private TreeNode selected;

    public TreeBean() {
        root = new DefaultTreeNode("Root", null);
        TreeNode node0 = new DefaultTreeNode("Node 0", root);
        TreeNode node1 = new DefaultTreeNode("Node 1", root);
        TreeNode node2 = new DefaultTreeNode("Node 2", root);

        TreeNode node00 = new DefaultTreeNode("Node 0.0", node0);
        TreeNode node01 = new DefaultTreeNode("Node 0.1", node0);

        TreeNode node10 = new DefaultTreeNode("Node 1.0", node1);
        TreeNode node11 = new DefaultTreeNode("Node 1.1", node1);

        TreeNode node000 = new DefaultTreeNode("Node 0.0.0", node00);
        TreeNode node001 = new DefaultTreeNode("Node 0.0.1", node00);
        TreeNode node010 = new DefaultTreeNode("Node 0.1.0", node01);

        TreeNode node100 = new DefaultTreeNode("Node 1.0.0", node10);
    }

    public TreeNode getRoot() {
        return root;
    }

    public void nodeSelected(NodeSelectEvent e) {
        System.out.println("nodeSelected");
        selected = e.getTreeNode();
    }

    public TreeNode[] getSelection() {
        return new TreeNode[0];
    }

    public void setSelection(TreeNode[] selection) {
        System.out.println("setSelection");
    }

    public TreeNode getSelected() {
        return selected;
    }

}

Vc pode fazer a mesma coisa sem iframe só com o h:panelGroup!

S

Rafael,
você pode dar uma olhada neste meu post aqui http://www.guj.com.br/posts/list/220025.java
não sei o que estou fazendo de errado, a tree não esta aparecendo.

Grato,
Filipe D.

D

po eu vi sua mensagem, mas nem cheguei a testar ainda, porque estava fissurado tentando fazer, acabei conseguindo e fiz aquilo que vc tinha dito usando o converter, mas vou fazer desse jeito que vc postou acho mais elegante, mas o meu ficou assim

index.xhtml

<h:form>
	 		<div id="divArvoredos">
				<p:tree value="#{indexBean.root}" var="node">
     		   		<p:treeNode>
     		   		      <h:link outcome="teste" target="miolo">
         				  	<h:outputText value="#{node}" />
         				  	<f:param name="no" value="#{node}"/>
         				  </h:link>
     		   		</p:treeNode>
		   		</p:tree>
		    </div>

		   <iframe src="" name="miolo" class="coisa" width="730" marginwidth="0" height="518" marginheight="0" align="top" scrolling="no" frameborder="0">
   		   </iframe>
    </h:form>

teste.xhtml

<f:view contentType="text/html">
	<f:metadata>
	    	<f:viewParam name="no" value="#{testeBean.node}" />
   	</f:metadata>
<h:head>
    <title>Ver Pessoa</title>
</h:head>
<h:body>
	<h:form>
		<h:outputText value="#{testeBean.node}"/>
	</h:form>
</h:body>
</f:view>

IndexBean

@ManagedBean
public class IndexBean {
	private TreeNode root;
	private TreeNode nodeEmUso;

	public IndexBean() {

		root = new DefaultTreeNode("Root", null);
		TreeNode node0 = new DefaultTreeNode("Node 0", root);
		TreeNode node1 = new DefaultTreeNode("Node 1", root);
		TreeNode node00 = new DefaultTreeNode("Node 0.0", node0);
		TreeNode node01 = new DefaultTreeNode("Node 0.1", node0);

		TreeNode node010 = new DefaultTreeNode("Node 1.0", node1);
		TreeNode node011 = new DefaultTreeNode("Node 1.1", node1);

		TreeNode node000 = new DefaultTreeNode("Node 0.0.0", node00);
		TreeNode node001 = new DefaultTreeNode("Node 0.0.1", node00);
		TreeNode node0010 = new DefaultTreeNode("Node 0.1.0", node01);		
	}

	public TreeNode getRoot() {
		return root;
	}

TesteBean

@RequestScoped
@ManagedBean
public class TesteBean {

	private TreeNode node;	

	public TreeNode getNode() {
		return node;
	}

	public void setNode(TreeNode node) {
		this.node = node;
	}
	
}

TreeNodeConverter

@FacesConverter(forClass=TreeNode.class)
public class TreeNodeConverter implements Converter{

	@Override
	public Object getAsObject(FacesContext ctx, UIComponent ui, String str) {
		TreeNode node = new DefaultTreeNode(str,null);
		return node;
	}

	@Override
	public String getAsString(FacesContext ctx, UIComponent ui, Object obj) {
		return  ((TreeNode)obj).getData().toString();
	}
	
}
D

entendi a ideia, mas vc chegiu a testar ´? pq estou vendo aqui por algum motivo o valor nao esta aparecendo no frame !

D

Sim, esse código foi testado e funciona. Contudo eu tive alguns problemas quando usando o p:tree q acabaram por se resolver “sozinhos” de modo q eu não sei dizer se são bugs.

Criado 28 de setembro de 2010
Ultima resposta 29 de set. de 2010
Respostas 55
Participantes 4