I want to show progress.
I have progressBar on page:
<?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.org/ui">
<h:body>
<h:form>
<p:growl id="growl" life="2000" />
<p:outputPanel id="statusPanel" widgetVar="statusPanel">
<div class="ui-g">
<div class="ui-g-12">
<p:progressBar widgetVar="pbAjax" ajax="true" value="#{myView.progress}" labelTemplate="{value}%" styleClass="animated" global="false">
<p:ajax event="complete" listener="#{myView.onComplete}" update="growl"/>
</p:progressBar>
</div>
</div>
</p:outputPanel>
<p:commandButton id="refresh" value="Refresh" action="#{myView.refresh}" update="@form, statusPanel" />
</h:form>
</h:body>
</html>
MyView looks like:
package app;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Named;
@Named
public class MyView {
Integer progress;
int actualCount;
int overallCount = 4;
public void refresh() {
try {
for (int i = 0; i < overallCount; i++) {
Thread.sleep(1000); // just to make it slower
++actualCount;
progress = 100 * actualCount / overallCount;
System.out.println("progress: " + progress);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public Integer getProgress() {
System.out.println("getProgress(): " + progress + "%");
return progress;
}
public void setProgress(Integer progress) {
this.progress = progress;
}
public void onComplete() {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Refresh completed"));
}
}
but progress bar is updated only whe refresh() call ends.
I'd like to update in between...
I tried to call update
RequestContext.getCurrentInstance().update("pbAjax");
but that does not work.
edit:
I checked Progress bar primefaces on backend processing but it is just an description to showcase sample (not very helpful in my case)
Also I looked at Primefaces progressbar not updating? which looks closer to what I want to achieve, but it is not working for me:
package app;
import javax.faces.bean.ViewScoped;
import javax.inject.Named;
import java.util.Date;
@Named
@ViewScoped
public class BatchModel {
Integer progress;
public Integer getProgress() {
System.out.println(new Date() + " get progress");
return progress;
}
public void setProgress(Integer progress) {
System.out.println(new Date() + " set progress: " + progress);
this.progress = progress;
}
}
I modified the view to:
package app;
import org.primefaces.context.RequestContext;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
@Named
@ViewScoped
public class MyView {
@Inject
BatchModel batchModel;
int actualCount;
int overallCount = 4;
public void refresh() {
try {
for (int i = 0; i < overallCount; i++) {
Thread.sleep(1000);
++actualCount;
batchModel.setProgress( 100 * actualCount / overallCount );
RequestContext.getCurrentInstance().update("pbAjax");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void onComplete() {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Refresh completed"));
}
}
...added batchModel + @ViewScope
in xhtml I call the refresh() as actionListener
:
<?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.org/ui">
<h:body>
<h:form>
<p:growl id="growl" life="2000" />
<p:outputPanel>
<div class="ui-g">
<div class="ui-g-12">
<p:progressBar widgetVar="pbAjax" ajax="true" value="#{batchModel.progress}" labelTemplate="{value}%" styleClass="animated" global="false">
<p:ajax event="complete" listener="#{myView.onComplete}" update="growl"/>
</p:progressBar>
</div>
</div>
</p:outputPanel>
<p:commandButton id="refreshBt" value="Refresh" actionListener="#{myView.refresh}" onclick="PF('pbAjax').start()" />
</h:form>
</h:body>
</html>
but log describes it the best:
Mon Dec 23 18:45:58 CET 2019 get progress
Mon Dec 23 18:45:58 CET 2019 get progress
Mon Dec 23 18:46:00 CET 2019 set progress: 25
Mon Dec 23 18:46:01 CET 2019 set progress: 50
Mon Dec 23 18:46:02 CET 2019 set progress: 75
Mon Dec 23 18:46:03 CET 2019 set progress: 100
Mon Dec 23 18:46:03 CET 2019 get progress
Mon Dec 23 18:46:03 CET 2019 get progress
so the get progress was called at the beginning and then at the end only...