Search this blog

Wednesday, 10 February 2016

ADF Basics: Creating Bounded Task Flow Train using af:train component

This post is about using bounded task flow as train
A train presents a whole cycle and it's every stop presents a particular step of cycle
From the docs -

The train component presents a user with a series of stops, each stop representing a step in a multi-step process. The train walks the user through these steps, in a suggested order (the order being dictated by the underlying model). Each step is rendered as a train stop consisting of an image and a textual link indicating if they are in visited, current, unvisited and disabled states. Train can also be rendered in a vertical layout - the default being a horizontal layout. Trains are not rendered on printable pages. 

We can design bounded task flow as train flow , see how to configure this
  • Create a Fusion Web Application and a Bounded TaskFlow in view controller project
    File--->New---> From Gallery-->Web Tier--->JSF/Facelets-->ADF Taskflow

    Check Create Train checkbox-

  • Now drop two or more pages in BTF , i have dropped three view activities from component palette, these fragments will behave as train stops

  • Select a view and go to structure window , expand view node and right click on train stop select Insert Inside Train Stop --> Display Name

  • Put a name for that stop and follow same steps for all view activities, this name will appear on that stop when we run this

  • Next is to create fragment , double click on first view activity and create a jsp xml fragment , now drop af:train and af:trainButtonBar on page from component palette

  • Click on OK with default value

    Drop an output text on page and it's value is - First Stop, Now repeat these steps for each view activity and each fragment looks like this

  • Now drop this bounded task flow in a jspx page as region and run that page

  • On clicking Next button

All done :)
Now if we want to change train's default look then we can use af:navigationPane component , this component supports Apache Trinidad MenuModel ,that extends TreeModel and implemented by Train Model so we can directly use navigationPagewithout much efforts

af:navigationPane has af:commandNavigationItem as it's child component and it supports multiple UI hints as list, bar ,buttons, choice and tabs
See xml code to use af:navigationPane-

<af:navigationPane hint="list" id="np1" value="#{controllerContext.currentViewPort.taskFlowContext.trainModel}"
            <f:facet name="nodeStamp">
                <af:commandNavigationItem text="#{train.textAndAccessKey}" id="cni1" visited="#{train.visited}"
                                          disabled="#{train.disabled}" action="#{train.action}"/>

And see how it looks on page -
Select navigationPane on page and see in property inspector and change it's hints to see different looks of train

 Bar -
Cheers :) Happy Learning


  1. Is there a way I can know in which step of the train am I? I need to know -inside some bean method- in which step I am so I can take decisions to do other stuff

    1. Luis

      Check ADF Train TaskFlow
      There is a method used to determine whether rendered is current stop or not using navigation pane
      I think you can use this method to know train stop name (See complete article in the link)

      public boolean isCurrentTab() {
      //get access to the JSF context classes
      FacesContext fctx = FacesContext.getCurrentInstance();
      ELContext elctx = fctx.getELContext();
      Application app = fctx.getApplication();
      ExpressionFactory expressionFactory = app.getExpressionFactory();
      //train is the name of the variable attribute defined in //af:navigationPane
      ValueExpression ve = expressionFactory.createValueExpression(elctx, "#{train}", Object.class);
      //get the rendered stop's viewActivity
      TaskFlowTrainStopModel renderedTrainNode = (TaskFlowTrainStopModel) ve.getValue(elctx);
      //get current train stop to compare it with the current "rendered"
      //train stop
      ControllerContext controllerContext = ControllerContext.getInstance();
      ViewPortContext currentViewPortCtx = controllerContext.getCurrentViewPort();
      TaskFlowContext taskFlowCtx = currentViewPortCtx.getTaskFlowContext();
      TaskFlowTrainModel taskFlowTrainModel = taskFlowCtx.getTaskFlowTrainModel();
      //the train stop that is rendered in the train bar
      String renderedActivityId = renderedTrainNode.getLocalActivityId();
      //the train's current stop: the state
      TaskFlowTrainStopModel currentStop = taskFlowTrainModel.getCurrentStop();
      if (renderedActivityId.equalsIgnoreCase(currentStop.getLocalActivityId())) {
      return true;
      return false;


  2. is there way to display long texts in the display label in multiple lines?

    1. Yes, You can set label width in labelStyle property of components and it'll appear in multiple lines

  3. Hi Ashish, I have a requirement as below. There will be 10 processes(Db migration happening in background) displayed as a trian component. The 10 different processes are each tied to respective tables and based on the status column of the tables the train node has to be either green or red. Can this be acheived using ADF train component as i came to know tht only pagefragments can be used as train nodes in a train. Appreciate any help in this regard.

    Thank u,

    Santhi Manthena

    1. Hi Santhi

      For this requirement you can use any other component like image inside af:iterator or af:forEach and put condition to show green and red image
      It'll not be possible to implement it using train component


    2. Thanks a lot Ashish.. will try af:iterator