7 de junho de 2011

JSF 2.0: Componentes PrimeFaces 2.2.1 - Parte 5

Depois de vermos sobre menus do PrimeFaces, nessa postagem vamos ver alguns outros componentes. Vamos precisar de algumas umas imagens e algumas bibliotecas extras, baixe por aqui.

Estrutura do projeto
Caso não saiba como montar a estrutura do projeto veja aqui.
Depois de pronto o projeto fica com essa estrutura:


O primeiro componente que veremos hoje é o dataExporter que serve para exportar os dados para arquivos PDF, XLS, XML ou CSV de uma determinada dataTable, então para isso eu preciso de uma dataTable:


Código-fonte:
Para este exemplo vamos precisar de uma classe Carro (pojo), então dentro de pacote de códigos fonte crie um novo pacote com o nome de model, e dentro dele crie uma nova classe Java com o nome de Carro:
public class Carro {

    private String marca;
    private int ano;
    private String placa;
    private String cor;
    private String modelo;

    public Carro(String marca, int ano, String placa, String cor, String modelo) {
        this.marca = marca;
        this.ano = ano;
        this.placa = placa;
        this.cor = cor;
        this.modelo = modelo;
    }

   //GETTERS e SETTERS
}

Agora vamos criar o nosso bean que vai dar suporte à nossa dataTable, para isso crie um pacote com o nome de controle, dentro desse pacote crie  uma nova classe Java com o nome de CarroBean:
@Named
@RequestScoped
public class CarroBean {

    private List<Carro> carros;

    public CarroBean() {
        listarCarros();
    }

    private void listarCarros() {
        carros = new ArrayList<Carro>();
        carros.add(new Carro("Fiat", 2011, "DFV 3455", "Verde", "Novo Uno"));
        carros.add(new Carro("Toyota", 2009, "ADV 3245", "Prata", "Prado"));
        carros.add(new Carro("Volks", 2010, "AAC 2351", "Vermelho", "Gol"));
        carros.add(new Carro("Volks", 2011, "EGF 1245", "Preto", "Cross Fox"));
    }

    //Gerar GET e SET
}
Bom nem tem o que explicar o código acima... Para este exemplo vamos precisar das imagens (do link que disponibilizei lá no inicio), por enquanto só irei precisar de: xsl.png e pdf.png, dentro de páginas web, crie um novo diretório com o nome de imagens, e coloque as imagens dentro dela. Agora vamos para a página index:
<h:form>
    <p:dataTable id="tabelaCarros" value="#{carroBean.carros}" var="c">
        <p:column>
            <f:facet name="header">Marca</f:facet>
            <h:outputText value="#{c.marca}" />
        </p:column>
        <p:column>
            <f:facet name="header">Modelo</f:facet>
            <h:outputText value="#{c.modelo}" />
        </p:column>
        <p:column>
            <f:facet name="header">Ano</f:facet>
            <h:outputText value="#{c.ano}" />
        </p:column>
        <p:column>
            <f:facet name="header">Cor</f:facet>
            <h:outputText value="#{c.cor}" />
        </p:column>
        <p:column>
            <f:facet name="header">Placa</f:facet>
            <h:outputText value="#{c.placa}" />
        </p:column>
    </p:dataTable>

    <h:commandLink>
        <p:graphicImage value="/imagens/xls.png" />
        <p:dataExporter type="xls" target="tabelaCarros" fileName="carros" />
    </h:commandLink>
    <h:commandLink>
        <p:graphicImage value="/imagens/pdf.png" />
        <p:dataExporter type="pdf" target="tabelaCarros" fileName="carros"/>
    </h:commandLink>
</h:form>
No código acima eu tenho uma dataTable normal (vista em postagens anteriores) e logo abaixo dela eu tenho os dataExporter, o detalhe mais importante é quanto a propriedade target, veja que ela corresponde ao id da tabela.

Nosso segundo componente é o pickList:


Vamos direto ao código, então dentro do pacote controle (criado anteriormente) vamos criar uma classe com o nome de PicklistBean:
@Named
@RequestScoped
public class PicklistBean {

    private DualListModel<String> cores;

    public PicklistBean() {
        listarCores();
    }

    private void listarCores() {
        List<String> lista = new ArrayList<String>();
        List<String> selecionados = new ArrayList<String>();

        lista.add("Azul");
        lista.add("Amarelo");
        lista.add("Vermelho");
        lista.add("Verde");
        lista.add("Roxo");

        cores = new DualListModel<String>(lista, selecionados);
    }

    public void mostrarCoresSelecionadas() {
        for (String cor : cores.getTarget()) {
            System.out.println("Esta cor é: " + cor);
        }
    }

    //Gerar GET e SET
}
Veja que usamos um DualListModel (do próprio PrimeFaces), para inicializar ele eu preciso informar duas listas, uma é dos os objetos a serem selecionados (chamada de source) e a outra representará o objetos selecionados(target), o método mostrarCoresSelecionadas() percorre a lista de cores selecionadas, repare que ele dá um getTarget() ... para pegar a lista original é só dar um getSource().
<h:form>
    <p:pickList value="#{picklistBean.cores}" var="cor" iconOnly="true" itemLabel="#{cor}" itemValue="#{cor}">
        <f:facet name="sourceCaption">Lista</f:facet>
        <f:facet name="targetCaption">Selecionadas</f:facet>
    </p:pickList>
    <p:commandButton value="Ver cores selecionadas" actionListener="#{picklistBean.mostrarCoresSelecionadas}" />
</h:form>
Ao final do código eu coloquei um commandButton que chama o método para listar as cores selecionadas.

O nosso próximo componente é o printer, ele é um componente que chama a função de impressão do navegador, com a diferença que o programador define qual a parte da página será impressa, para usar ele eu vou precisar da imagem printer.png (no arquivo que eu passei), coloque-o dentro do diretório imagens. Vou mostra-lo junto com o próximo componente, mas antes segue o código:
<h:outputLink id="lnk" value="#">
    <p:printer target="quebraCabeca" />
    <p:graphicImage value="/imagens/print.png" />
</h:outputLink>
Repare que o target se refere a um elemento quebraCabeca, ele corresponde a uma parte da página que eu quero que seja impresso, nesse caso este quebraCabeca será o próximo elemento a ser feito.

Para finalizar vamos ver o componente dashboard, que em um sistema comercial eu não vi muita utilidade, então para este exemplo eu resolvi criar um quebra cabeça meio desengonçado com ele!


Quanto a impressora que aparece acima na imagem, esta corresponde ao componente printer. Vamos começar então com o nosso quebra-cabeça, primeiramente precisamos pegar as imagens que eu passei lá no inicio e coloca-las no projeto. Primeiro dentro do diretório imagens crie um novo diretório com o nome de jogo: dentro dele coloque as imagens a.jpg, b.jpg até a imagem i.jpg... Abaixo segue a classe Java QuebraCabecaBean que deve ser criado dentro do pacote controle:
@Named
@RequestScoped
public class QuebraCabecaBean {

    private DashboardModel pecas;

    public QuebraCabecaBean() {
        listarPecas();
    }

    private void listarPecas() {
        pecas = new DefaultDashboardModel();
        DashboardColumn coluna1 = new DefaultDashboardColumn();
        DashboardColumn coluna2 = new DefaultDashboardColumn();
        DashboardColumn coluna3 = new DefaultDashboardColumn();

        coluna1.addWidget("f");
        coluna1.addWidget("c");
        coluna1.addWidget("g");

        coluna2.addWidget("h");
        coluna2.addWidget("a");
        coluna2.addWidget("d");

        coluna3.addWidget("i");
        coluna3.addWidget("e");
        coluna3.addWidget("b");

        pecas.addColumn(coluna1);
        pecas.addColumn(coluna2);
        pecas.addColumn(coluna3);
    }

    //Gerar GET e SET
}
Veja que eu incluo as letras embaralhadas dentro do DashboardColumn, realmente para iniciarem embaralhadas, só temos um detalhe: para cada letra que eu coloquei nessa lista eu preciso de um componente com o id do mesmo nome dentro do componente dashboard, apenas colocar os painéis no xhtml com as imagens não é suficiente eu preciso ter esse espelho entre o bean e a página:
<h:form id="quebraCabeca">
    <p:dashboard model="#{quebraCabecaBean.pecas}">
        <p:panel id="f">
            <p:graphicImage url="/imagens/jogo/f.jpg" />
        </p:panel>
        <p:panel id="c">
            <p:graphicImage url="/imagens/jogo/c.jpg" />
        </p:panel>
        <p:panel id="g">
            <p:graphicImage url="/imagens/jogo/g.jpg" />
        </p:panel>

        <p:panel id="h">
            <p:graphicImage url="/imagens/jogo/h.jpg" />
        </p:panel>
        <p:panel id="a">
            <p:graphicImage url="/imagens/jogo/a.jpg" />
        </p:panel>
        <p:panel id="d">
            <p:graphicImage url="/imagens/jogo/d.jpg" />
        </p:panel>

        <p:panel id="i">
            <p:graphicImage url="/imagens/jogo/i.jpg" />
        </p:panel>
        <p:panel id="e">
            <p:graphicImage url="/imagens/jogo/e.jpg" />
        </p:panel>
        <p:panel id="b">
            <p:graphicImage url="/imagens/jogo/b.jpg" />
        </p:panel>
    </p:dashboard>
</h:form>

A solução do quebra cabeça é este:


OBS: Quanto ao quebra cabeça este foi improvisado, já que a postagem original era para ser falado sobre os gráficos do PrimeFaces, mas que infelizmente não consegui fazer funcionar.
Mas pensem comigo, antes isso do que nada né!? :P

20 comentários:

  1. Andii, adorei o quebra cabeça, muito bom, excelentes seus post.
    Valeu mesmo.

    ResponderExcluir
  2. Só não consegui pegar as imagens o link não esta funcionando.

    ResponderExcluir
  3. Silvio. Acabei de testar o link, está funcionando perfeitamente!

    ResponderExcluir
  4. Andiiizinhaaa o link com as libs e as imagens nao esta funcionando =(

    bjo

    ResponderExcluir
  5. Pronto! Agora sim está funcionando, tinha uma configuração bloqueando acesso sem estar conectado com a conta do Google.

    ResponderExcluir
  6. Olá Andii! Muito boas essas dicas! Sempre aprendo muito com seu blog! Como ainda sou iniciante, gostaria de saber se você poderia me explicar um pouco sobre RequestContext API, que é utilizado em alguns componentes no showcase do Primefaces... Googlei sobre o assunto, mas não tive nenhum exemplo mais prático que exemplificasse bem o assunto... Abraçoes!

    ResponderExcluir
  7. Olá Vanessa! Então, também não conheço a fundo os componentes, sei fazê-los funcionar, mas o que está atrás deles nunca arrumei tempo para ir atrás.

    ResponderExcluir
  8. Muito bom post. Excelente visual de seu site também. Parabéns.

    Blog: http://javanamente.blogspot.com

    ResponderExcluir
  9. Andii tudo bem? :D

    Então cara não consegue sequir com o exercicio na hora de buscar a expression language ela nao acha carroBean.carro tem ideia do que seja ?

    estou usando o NetBeans 7.0.1 + glassFish + MySQL

    BeijosS !

    ResponderExcluir
  10. Boa Tarde Gpz. Tenho ideia sim do que está acontecendo... se vc olhar bem no código, em nenhum momento ele está chamando carroBean.carro e sim carroBean.carros na dataTable. E também na classe CarroBean não tem nenhum carro declarado, apenas uma List o que acaba sendo carros.

    ResponderExcluir
  11. Estou tentando fazer funcionar com lista de objetos o componente pickList, mas estou apanhando, poderia me ajudar?

    ResponderExcluir
  12. Olá FuRaCaO! Pode me dizer exatamente o que está acontecendo?

    ResponderExcluir
  13. Oláa! otimo blog, só não consegui popular a dataTable com os dados da lista.. alguem pode me ajudar?

    ResponderExcluir
  14. Ola Andii, tudo bom?
    Andii, sera que pode me ajudar?
    Eu populei minha lista com um objeto Aulas que tenho id, descricao e valor.
    A lista carrega perfeitamente, porem utilizei na picklist uma ajax para assim que selecionar uma aula conseguir manipular o valor e mostrar em um text na tela().
    Porem a lista alvo sempre vem vazia.
    Vc tem alguma ideia do que pode estar acontecendo?
    Muito obrigado e parabens pelo post.

    ResponderExcluir
    Respostas
    1. Olá! já tentou tirar esse ajax? pra ver se ele funciona corretamente?

      Excluir
    2. Ola Andii, tudo bom?
      Havia tentado isso mas não deu certo, acabei encontrando uma saida.
      Criei um converter e consegui pegar os valores que preciso.
      Se for util para o post envio o que fiz.
      Obrigado pela ajuda.

      []s

      Excluir
    3. Então Denis, eu tenho um coverter.. eu até ia te passar ele, mas eu não lembrava se ele era realmente necessário, por isso perguntei se as vezes sem o ajax funcionaria

      Excluir
  15. Entendi =)
    Muito obrigado mesmo pela ajuda Andii.
    []s

    ResponderExcluir
  16. andii, tudo bem?

    Sabe se tem como colocar uma mensagem de "Aguarde..." Enquanto o dataexporter gera o XLS ? obrigado !

    ResponderExcluir

Deixe seu comentário... ;)