4

I have a fileUpload button and when user upload a file the process in ManagedBean start. This proccess can be very slow and i need to show a progress to user. So i have the following code:

<p:fileUpload id="commandButtonIniciarImportacao"
            disabled="#{importacaoArMB.produtoSelecionado == null}"
            fileUploadListener="#{importacaoArMB.uploadArquivoImportacao}"
            mode="advanced" auto="true" cancelLabel="Cancelar"
            update=":formManterArquivoImportacao:tabViewManterArquivoImportacao:dataTableArs,
            :formManterArquivoImportacao:tabViewManterArquivoImportacao:dataTableArsIgnorados"
            label="Iniciar Importação..."
            onstart="pbImportacao.start()" />

        <p:progressBar widgetVar="pbImportacao" ajax="true" value="#{importacaoArMB.progresso}" 
        labelTemplate="#{value}%">
        </p:progressBar>

In my managedBean i have a getter and setter to progress attribute, and i'm doing the following:

public void uploadArquivoImportacao(FileUploadEvent fileUploadedEvent) {

        if (produtoSelecionado == null) {
            addErrorMessage("Selecione o Produto antes de iniciar a importação");
            FacesContext.getCurrentInstance().validationFailed();
            return;
        }

        try {

            addInfoMessage("Iniciando importação ...");

            uploadedFile = fileUploadedEvent.getFile();

            // Inicializando atributos do bean (ArquivoImportacao)
            byte[] conteudoAsBytes = uploadedFile.getContents();
            bean.setConteudo(new String(conteudoAsBytes));
            bean.setDataHoraImportacao(new Date());
            bean.setNome(uploadedFile.getFileName());
            bean.setLayoutImportacao(produtoSelecionado.getLayoutImportacao());

            arsIgnorados = getBoPadrao().gerarArsFromImportacao(bean, progresso);

            addInfoMessage("Importação finalizada");

        } catch (BOException bo) {
            addErrorMessage(bo.getMessage());
            FacesContext.getCurrentInstance().validationFailed();
        } catch (Exception e) {
            e.printStackTrace();
            addErrorMessage(e.getMessage());
            FacesContext.getCurrentInstance().validationFailed();
        }

    }   

I pass the "progress" attribute to my BO (Bussiness Object) and there the value of this attribute is incremented in each iterator of FOR.

The problem is: Nothing happens with progressBar, continue in ZERO.

Shelly
  • 1,035
  • 5
  • 27
  • 51
  • 1
    in advanced mode already includes a progressbar for each uploaded file. I don't see how you uplate the *progresso* variable. Did you set the filter and filtermapping as described [here](http://stackoverflow.com/questions/8875818/how-to-use-primefaces-pfileupload-listener-method-is-never-invoked) ? – Stephane Lallemagne Dec 26 '13 at 22:10
  • 1
    I will explain: The progressbar from – Shelly Dec 26 '13 at 22:44
  • Well, i discored that "progressbar" is been called after all process in BO ends, but i don't know why – Shelly Dec 26 '13 at 23:13
  • 1
    Ok I see, the problem is you must not launch your second process onfileuploaded, because it is too early (progressbar not yet started at this moment...). Just another remark : Label template is not an EL expression, so `labelTemplate="{value}%"` (no # needed here). – Stephane Lallemagne Dec 27 '13 at 16:54
  • But how can i solve this problem ? I need start my another process after file is uploaded. – Shelly Dec 27 '13 at 18:54

1 Answers1

1

Look at this example built from your code.

It is only a demo, but it's working the way you want ! Hope you can adapt it to your real code.

<h:form id="form1">
<p:growl id="growl" showDetail="true"/>  
<p:fileUpload id="fileup1"
        fileUploadListener="#{uploadBean.uploadArquivoImportacao}"
        mode="advanced" 
        auto="true" 
        cancelLabel="Cancelar"
        update="growl"
        label="Iniciar Importação..."
        onstart="pbImportacao.start()" />
 <p:progressBar 
    id="progress1" 
    widgetVar="pbImportacao" 
    ajax="true" 
    value="#{uploadBean.progresso}" 
    labelTemplate="{value}%">
    <p:ajax event="complete" listener="#{uploadBean.onComplete}" update="growl" />
 </p:progressBar>
</h:form>       

And in the UploadBean class:

public void uploadArquivoImportacao(FileUploadEvent fileUploadedEvent) {

    System.out.println("File uploaded...");

    //collects information about uloaded file here...

    //then do what you have to do (can take time)
    doYourStuff();
}

public void doYourStuff() {
    //fake job that takes 10 seconds (100 x 100 millis)
    System.out.println("Job starts...");
    for (int i = 0; i < 100; i++) {
        setProgresso(i);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
        }
    }
    setProgresso(0);
    System.out.println("Job done.");
}

private long progresso = 0;

public long getProgresso() {
    return progresso;
}

public void setProgresso(long progresso) {
    this.progresso = progresso;
}

public void onComplete() {
    System.out.println("oncomplete !");
}

Remarks

  • ProgressBar updates everery 2 or 3 seconds (not so high refresh rate)
  • onComplete is not called (I don't see why)
Stephane Lallemagne
  • 1,246
  • 11
  • 21