How to create a "composite" flow

Steps required to create a flow:


Create your own class by sub-classing one of the IFlow raw implementations provided by IFW2 such as ABndsFlow or BndsFlow.

Sometimes, if required, you can subclass more complex ifw2 flows such as CardFlow or TabbedFlow.

public class MainFlow extends CardFlow {

  private static final long serialVersionUID = 1L;

  ...
}

In your CTOR call the super-ctor passing the IRenderer you want to use.

Commonly used implementations are:

  • JSPRenderer: rendering is delegated to a JSP which has to use ifw2 tags.
  • AECSRenderer: rendering is delegated to java code that has to use apache ecs classes and special ECSAdapter classes builded using static methods of net.infordata.ifw2.web.ecs.Bnds and/or net.infordata.ifw2.web.ecs.Base.
  • ECSRenderer: same as AECSRenderer but in a more "static" way, ie the ecs objects tree is builded at ctor time and not at rendering time.
  ...
  public GroupFlow() {
    super(new JSPRenderer("/WEB-INF/jsp/group/Group.jsp"));
    ...
<%@ page language="java"%>

<%@ taglib uri="http://www.infordata.net/taglibs/ifw2" prefix="ifw2"%>

...

<ifw2:bnd-form bind="actions">
<table width="100%">
  <tr>
    <td style="color:red;font-weight:bold;">
      <%= flow.isFiltered() ? "FILTER&nbsp;ACTIVE" : "" %>
    </td>
    <td width="100%">
    </td>
    <td align="right" width="200px">
      <ifw2:action-group id="ag1">
        <ifw2:bnd-submit bind="reload"/>
      </ifw2:action-group>
    </td>
  </tr>
</table>
</ifw2:bnd-form>

<ifw2:component componentId="table"/>

...


Create and register any other flow used as component or as sub-flow by your flow.

Other flows are normally flows builded for your application or ready to be used ifw2 provided flows such as DataGridFlow, MessageAreaFlow, ...

    ...
    
    ivDataGrid = new DataGridFlow(ivDs.getGroupsModel(), true, true);
    ivDataGrid.setVertResizer(ProportionalGridResizers.getVertResizer(8, 15, 568, 824))
       .setLayoutable(false);
    // Now the DataGridFlow becomes a component registered with the id "table",
    // the id is used in the rendering jsp in the "ifw2:component" tag  
    ivDataGrid.asComponent(this, "table");
    
    ...


If your flow should act as a finite state-machine, register any required additional state.

  
    ...
  
    registerFlowState(new FlowState("main"), true);
    registerFlowState(new FlowEndState("logout"));
  
    ...
  

Create and register any used form.

Add to them fields and actions, more on this in How to create a form and validate it.

    ...
  
    ivActions = new ActionsForm();
    registerForm("actions", ivActions); 
    ivActions.registerAction("toggleMenu", new IFormAction() {
      private static final long serialVersionUID = 1L;
      @Override
      public IFlowState execute(IBndsFlow flow, HttpServletRequest request,
                                String formName, ActionInfo action,
                                Map<String, UploadedFile> files) {
        ivCollapseMenu = !ivCollapseMenu;
        return null;
      }
      @Override
      public String getLabel() {
        return "Toggle menu";
      }
      @Override
      public boolean isEnabled() {
        return true;
      }
    });
  
    ...
    
     
      ...

      <ifw2:bnd-form bind="actions">
      
            ...
       
            <ifw2:bnd-a bind="toggleMenu" style="color:white"><b>MenĂ¹</b></ifw2:bnd-a>
            
            ...
            
      </ifw2:bnd-form>

      ...
      

Possibly override parent class methods as needed.

Most commonly overridden methods are:

  • on*: method prefixed with "on", refer to javadoc for more info.
  • getResource: to serve flow "locally" scoped resources to the browser.

    URL to flow "locally" scoped resources are builded with the RendererContext.getScopedResourceUri(String) method.