Componentes JSF

Galera, venho recorrer a vós novamente,
estou com a seguinte dificuldade:
A ideia:
Criar um componente para paginação, que receberia basicamente 3 parãmetros, o total da pesquisa (o count() do db), um atributo que receberia a pagina atual. e um método a ser executado ao trocar de página.

O problema:
Ainda não encontrei uma forma de alterar o atributo no bean que use o componente.

Evolui a ideia e melhorando-á acredito que os 3 parâmetros não seriam suficientes, o mais eficiente é receber o start e o offset da pesquisa ex:

estou na pagina 1 então start = 0 e o offset = 10;
estou na pagina 3 então start seria 20 e o offset 30;

bom vamos aos códigos:

componente

[code]

<?xml version='1.0' encoding='UTF-8' ?>
<!-- INTERFACE -->
<cc:interface componentType="pagination">
    <cc:attribute name="total" required="true" type="java.lang.Integer" />
    <cc:attribute name="start" required="true"  type="java.lang.Integer" />
    <cc:attribute name="offset" required="true"  type="java.lang.Integer" />
    <cc:attribute name="numvisiblesitems" type="java.lang.Integer" />
    <cc:attribute name="styleClass" default="" />
    <cc:attribute name="numvisiblespages" default="5" type="java.lang.Integer" />
    <cc:attribute name="style" default="" />
    <cc:attribute name="update" default="@form" />
    <cc:attribute name="process" default="@form" />
    <!--renderiza acima do result table -->
    <cc:attribute name="renderTop" default="true" />
    
    <!--renderiza abaixo do result table -->
    <cc:attribute name="renderBottom" default="false" />
    <cc:attribute name="action" required="true"
                  method-signature="void action()" />
</cc:interface>

<!-- IMPLEMENTATION -->
<cc:implementation>
    <!-- chama o bean do componente para os devidos cálculos -->
    #{cc.calculate()}
    <c:set var="numpages" value="#{cc.getPages()}" />
    <h:outputStylesheet library="css" value="components.css" name="components.css"/>
    
    <h:panelGroup layout="block" id="i#{cc.attrs.id}" 
                  class="pagination #{cc.attrs.styleClass}"
                  style="#{cc.attrs.style}"
                  rendered="#{cc.attrs.renderTop}">
        <ul>
            <ui:repeat value="#{cc.listPages}" var="p" >
                <li>
                    <h:commandButton 
                        value="#{p.toString()}" >
                        <pou:ajax 
                        listener="#{cc.setNewPage(p)}"
                        update="#{cc.attrs.update}"
                        process="#{cc.attrs.process}"  />
                    </h:commandButton>
                </li>
            </ui:repeat>
            <span><h:outputText value="Número de páginas:#{numpages}"></h:outputText></span>
        </ul>
    </h:panelGroup>
    <cc:insertChildren />

</cc:implementation>
[/code] e o bean do componente [code] @FacesComponent("pagination") public class Pagination extends UINamingContainer {
private Integer total;
private Integer numvisiblesitems;
private Integer pages;
private Integer firstPage;
private Integer lastPage;
private Integer start;
private Integer end;
private Integer actual = 1;
private Integer numvisiblespages;
private List<Integer> listPages;

/**
 * chamado no pagination.xhtml para execução dos cálculos.
 */
public void calculate() {

    numvisiblesitems = (Integer) this.getAttributes().get("numvisiblesitems");
    total = (Integer) this.getAttributes().get("total");
    numvisiblespages = (Integer) this.getAttributes().get("numvisiblespages");

    //trata o default para o número de items visualizáveis
    if (numvisiblesitems == null) {
        numvisiblesitems = 10;
    }

    if (total == null) {
        throw new IllegalArgumentException("Number of total must be defined!");
    }

    pages = (total / numvisiblesitems);

    if (pages * numvisiblesitems < total) {
        pages++;
    }

    updatePages();
}

private void updatePages() {
    updatePages(true);
}

private void updatePages(boolean starting) {

    //se for a primeira chamada a pagina é 1
    actual = starting ? 1 : actual;

    //inicio da paginação
    start = (actual * numvisiblesitems) - numvisiblesitems;

    if (start < 0) {
        start = 0;
    }

    //final da paginação
    end = start + numvisiblesitems;

    if (end > total) {
        end = total;
    }
    
    if (actual > numvisiblespages / 2) {
        firstPage = actual - numvisiblespages / 2;
    } else if (actual < numvisiblespages / 2) {
        firstPage = 1;
    } else {
        firstPage = actual - numvisiblespages / 2;
    }

    lastPage = firstPage + numvisiblespages;
    if (actual == total) {
        lastPage = total;
    }

    listPages = new ArrayList<Integer>();

    for (int i = firstPage; i <= lastPage; i++) {
        listPages.add(i);
    }

}

public void setNewPage(Integer p) {
    actual = p;
    updatePages(false);
}

//getter and setters

}
[/code]

uma das dúvidas é, setar o atributo do bean que use este componente, a outra é, na tentativa de alterar a págima alguns cálculos devem ser realizados novamente, porém, aparentemente sem nenhuma exceção não consigo executar um método na class Pagination, na verdade apenas , um o que inicia a classe, o calculate(), os outros não são executados a partir do click do h:commandButton, há alguma coisa de errada no código? passei a usar o h:commandButton, pois com o p:commandButton, porém tanto um quanto o outro sem sucesso.

Qualquer ajuda é bem vinda.

Encontrei o problema, basicamente estava tentando executar uma ação em um bean que não tem escopo, então alterei o componente , em vez de ele ter um Tipo, ele recebe como parâmetro o Pagination, assim ele calcula ao construir o componente, e o resto é alterado de acordo com a navegação, para utilizar basta o bean ter um atributo instanciado do Paginatio, e implementar o PaginationListener, que tem apenas um método, semelhante ao Runnable,
bom vou deixar as classes aqui, caso alguem queira utilizar.

public interface PaginationListener {
    void doAction();
}

[code]/*

  • To change this template, choose Tools | Templates

  • and open the template in the editor.
    */
    @FacesComponent(“pagination”)
    public class Pagination implements Serializable{

    private Integer total;
    private Integer numvisiblesitems;
    private Integer pages;
    private Integer firstPage;
    private Integer lastPage;
    private Integer start;
    private Integer end;
    private Integer current = 1;
    private Integer numvisiblespages;
    private List listPages;
    private PaginationListener listener;

    public Pagination(Integer total, Integer numvisiblesitems,
    Integer numvisiblespages, PaginationListener listener) {
    this.total = total;
    this.numvisiblesitems = numvisiblesitems;
    this.numvisiblespages = numvisiblespages;
    this.listener = listener;
    calculate();
    }

    public Pagination(Integer total,PaginationListener listener) {
    this.total = total;
    this.numvisiblesitems = 10;
    this.numvisiblespages = 5;
    this.listener = listener;
    calculate();
    }
    /**

    • chamado no pagination.xhtml para execução dos cálculos.
      */
      private void calculate() {

      //trata o default para o número de items visualizáveis
      if (numvisiblesitems == null) {
      numvisiblesitems = 10;
      }
      if(numvisiblespages == null){
      numvisiblespages = 5;
      }

      if (total == null) {
      throw new IllegalArgumentException(“Number of total must be defined!”);
      }

      pages = (total / numvisiblesitems);

      if (pages * numvisiblesitems < total) {
      pages++;
      }

      updatePages();
      }

    private void updatePages() {
    updatePages(true);
    }

    private void updatePages(boolean starting) {

     //se for a primeira chamada a pagina é 1
     current = starting ? 1 : current;
    
     //inicio da paginação
     start = (current * numvisiblesitems) - numvisiblesitems;
    
     if (start < 0) {
         start = 0;
     }
    
     //final da paginação
     end = start + numvisiblesitems;
    
     if (end > total) {
         end = total;
     }
     
     if (current > numvisiblespages / 2) {
         firstPage = current - numvisiblespages / 2;
     } else if (current < numvisiblespages / 2) {
         firstPage = 1;
     } else {
         firstPage = current - numvisiblespages / 2;
     }
    
     lastPage = firstPage + numvisiblespages;
     if (lastPage > pages) {
         lastPage = pages;
         firstPage = lastPage - numvisiblespages;
     }
     if(firstPage < 1){
         firstPage = 1;
     }
    
     listPages = new ArrayList<Integer>();
    
     for (int i = firstPage; i <= lastPage; i++) {
         listPages.add(i);
     }
     
     if(!starting){
         listener.doAction();
     }
    

    }

    public void setNewPage(Integer p) {
    current = p;
    updatePages(false);

    }

    public Integer getEnd() {
    return end;
    }

    public void setEnd(Integer end) {
    this.end = end;
    }

    public Integer getNumvisiblesitems() {
    return numvisiblesitems;
    }

    public void setNumvisiblesitems(Integer numvisiblesitems) {
    this.numvisiblesitems = numvisiblesitems;
    }

    public Integer getPages() {
    return pages;
    }

    public void setPages(Integer pages) {
    this.pages = pages;
    }

    public Integer getStart() {
    return start;
    }

    public void setStart(Integer start) {
    this.start = start;
    }

    public Integer getTotal() {
    return total;
    }

    public void setTotal(Integer total) {
    this.total = total;
    }

    public Integer getFirstPage() {
    return firstPage;
    }

    public void setFirstPage(Integer firstPage) {
    this.firstPage = firstPage;
    }

    public Integer getLastPage() {
    return lastPage;
    }

    public void setLastPage(Integer lastPage) {
    this.lastPage = lastPage;
    }

    public Integer getNumVisiblesPages() {
    return numvisiblespages;
    }

    public void setNumVisiblesPages(Integer numVisiblesPages) {
    this.numvisiblespages = numVisiblesPages;
    }

    public List getListPages() {
    return listPages;
    }

    public void setListPages(List listPages) {
    this.listPages = listPages;
    }

    public Integer getCurrent() {
    return current;
    }

    public void setCurrent(Integer current) {
    this.current = current;
    }
    }
    [/code][code]<?xml version='1.0' encoding='UTF-8' ?>

<!-- INTERFACE -->
<cc:interface>
    <cc:attribute name="styleClass" default="" />
    <cc:attribute name="style" default="" />
    <cc:attribute name="update" default="@form" />
    <cc:attribute name="process" default="@form" />
    <!--renderiza acima do result table -->
    <cc:attribute name="renderTop" default="true" />

    <!--renderiza abaixo do result table -->
    <cc:attribute name="renderBottom" default="false" />
    <cc:attribute name="pagination" required="true"
                  type="com.busker.web.components.Pagination" />
    <cc:attribute name="action" required="true"
                  method-signature="void action()" />
</cc:interface>

<!-- IMPLEMENTATION -->
<cc:implementation>
    <!--call to componentType to calculate vars-->
    <c:set var="numpages" value="#{cc.attrs.pagination.setAction(cc.attrs.action)}" />
    <c:set var="numpages" value="#{cc.attrs.pagination.getPages()}" />
    <h:outputStylesheet library="css" value="components.css" name="components.css"/>
    <h:panelGroup layout="block" id="#{cc.attrs.id}t" 
                  class="pagination #{cc.attrs.styleClass}"
                  style="#{cc.attrs.style}"
                  rendered="#{cc.attrs.renderTop}">
        <ul>
            <ui:repeat value="#{cc.attrs.pagination.listPages}" var="p" >
                <li class="#{cc.attrs.pagination.current == p?'selected':''}" >
                    <pou:commandButton  
                        value="#{p.toString()}"
                        action="#{cc.attrs.pagination.setNewPage(p)}"
                        update="#{cc.attrs.update}"
                        process="#{cc.attrs.process}"
                        />
                </li>
            </ui:repeat>
            <span><h:outputText value="Número de páginas:#{numpages}"></h:outputText></span>
        </ul>
    </h:panelGroup>
    <cc:insertChildren />
    <h:panelGroup layout="block" id="#{cc.attrs.id}b" 
                  class="pagination #{cc.attrs.styleClass}"
                  style="#{cc.attrs.style}"
                  rendered="#{cc.attrs.renderBottom}">
        <ul>
            <ui:repeat value="#{cc.attrs.pagination.listPages}" var="p" >
                <li class="#{cc.attrs.pagination.current == p?'selected':''}" >
                    <pou:commandButton  
                        value="#{p.toString()}"
                        action="#{cc.attrs.pagination.setNewPage(p)}"
                        update="#{cc.attrs.update}"
                        process="#{cc.attrs.process}"
                        />
                </li>
            </ui:repeat>
            <span><h:outputText value="Número de páginas:#{numpages}"></h:outputText></span>
        </ul>
    </h:panelGroup>
</cc:implementation>
[/code]

Abraços.