Show live progress of a long running task using af:progressIndicator in Oracle ADF

Sharing is Caring

This post is about using af:progressIndicator to show live status of a particular task
af:progressIndicator state is tracked and maintained by it’s value property that supports org.apache.myfaces.trinidad.model.BoundedRangeModel
This class has two methods

public abstract long getMaximum() { }

returns Maximum value for Model

public abstract long getValue() { }

returns value for Model (current state)

Now to see live progress on page we have to refresh progressIndicator component periodically and this can be achieved using af:poll component , poll component delivers poll events to server periodically and we can ppr (refresh) progress indicator after a particular interval


So I have created a page and dropped these ADF Faces components
af:button– to start processing (start a thread that loop up to 100 and sleeps for 100 milliseconds to make it long)
af:progressIndicator– to show live progress
af:outputText– to show text percentage completed
af:poll– to refresh progressIndicator after a fixed time interval


Next i have created a bean class that extends BoundedRangeModel and implements Runnable (For thread purpose)
See Managed Bean –

import javax.faces.event.ActionEvent;

import oracle.adf.view.rich.context.AdfFacesContext;

import org.apache.myfaces.trinidad.event.PollEvent;
import org.apache.myfaces.trinidad.model.BoundedRangeModel;

public class ProgressIndicatorBean extends BoundedRangeModel implements Runnable {

public ProgressIndicatorBean() {
}
// An Integer value that presents current state of progress
int procVal = 0;
//To set poll interval, on start button click it will start polling
private int pollInterval = 1;

//Variable accessors to be used by ADF Faces Components on page
public void setPollInterval(int pollInterval) {
this.pollInterval = pollInterval;
}

public int getPollInterval() {
return pollInterval;
}

public int getProcVal() {
return procVal;
}

public void setProcVal(int procVal) {
this.procVal = procVal;
}

@Override
public long getMaximum() {
return 100;
}

@Override
public long getValue() {
return procVal;
}

@Override
public void run() {
// Loop up to Maximum value of Progress Model
while (procVal < getMaximum()) {
try {
//Sleeps for 100ms to make it long
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Increase current status of progress model
procVal++;
}
}

/**Method to process Action Event, starts polling and a thread that makes processing long
* @param actionEvent
*/
public void processValueAction(ActionEvent actionEvent) {
//Set poll interval to postive value to start polling
pollInterval = 100;
//Set initial progrss to zero
procVal = 0;
//Start a thread
Thread t = new Thread(this);
t.start();
}

/**Poll Listener to stop poll (set poll interval to -1) once task is done
* @param pollEvent
*/
public void pollListnerEvt(PollEvent pollEvent) {
//Check if processing is complete
if (procVal == getMaximum()) {
//Setting poll interval to negative value to stop polling
pollInterval = 1;
//Refresh poll component
AdfFacesContext.getCurrentInstance().addPartialTarget(pollEvent.getComponent());
}
}
}

Now see page XML source – (How this bean is mapped on page)

<af:panelGroupLayout id="pgl1" layout="vertical" halign="center">
                    <af:button text="Start" id="b1"
                               actionListener="#{viewScope.ProgressIndicatorBean.processValueAction}"/>
                    <af:spacer width="10" height="10" id="s1"/>
                    <af:poll id="p1" interval="#{viewScope.ProgressIndicatorBean.pollInterval}" partialTriggers="b1"
                             clientComponent="true" timeout="10000"
                             pollListener="#{viewScope.ProgressIndicatorBean.pollListnerEvt}"/>
                    <af:progressIndicator id="pi1" value="#{viewScope.ProgressIndicatorBean}" partialTriggers="p1"/>
                    <af:outputText value="Proceesing.. #{viewScope.ProgressIndicatorBean.procVal}% Done" id="ot1"
                                   partialTriggers="p1" inlineStyle="color:blue;font-weight:bold;"/>
                </af:panelGroupLayout>

All done 🙂 Page looks like this

Run and check application, Click on start button

Sample ADF Application (Jdeveloper 12.1.3) –Download
Cheers 🙂 Happy Learning

Related Posts

I’m an Oracle ACE, Blogger, Reviewer,
Technical Lead working on Oracle ADF

7 thoughts on “Show live progress of a long running task using af:progressIndicator in Oracle ADF”

  1. Hi , On clicking on start if I am calling some operation binding poll interval is not getting executed . why its not triggering the progress indicator. Do you have any idea about this or how to overcome this issue.

  2. Hi Ashish,

    If we add below piece of code inside while loop then this application breaks.

    BindingContext bctx = BindingContext.getCurrent();
    BindingContainer bindings = bctx.getCurrentBindingsEntry();

    Itseems UI thread can't be run inside this thread. If this is the case then how to execute operation binding inside thread enviroment.

Leave a Reply

Your email address will not be published. Required fields are marked *