8 Replies Latest reply on May 8, 2009 3:28 AM by Ruben Jorge

    Using subTable to display data from Vector<Vector>

    Ruben Jorge Newbie

      Hello everyone,

      I'm new to JSF and RichFaces and I'm trying to create a table (rich:dataTable) from data structures in my backing bean. I've already managed to create the headers using rich:columnGroup and now I want to display the actual data using rich:subTable.

      My subTable is defined as follows:

      <rich:subTable value="#{TaskListBean.main}" var="data">
       <!-- first 3 values -->
       <rich:columns value="#{data.rowList}" var="singleCellData">
       <h:outputText value="#{singleCellData.headerName}" />
       </rich:columns>
       </rich:subTable>


      I have 3 Java files, TaskListBean is the backing bean:

      public class TaskListBean {
      
       private Vector<RowData> main;
      
       public Vector<RowData> getMain() {
       main = new Vector<RowData>();
      
       RowData data1 = new RowData();
      
       main.add(data1);
       main.add(data1);
       main.add(data1);
       main.add(data1);
      
       return main;
       }
      }
      



      RowData is:

      public class RowData {
       private Vector<HeadersData> rowList;
      
       public RowData() {
       this.rowList = new Vector<HeadersData>();
      
       HeadersData data3 = new HeadersData();
       data3.setHeaderName("Data s1");
      
       HeadersData data4 = new HeadersData();
       data4.setHeaderName("Data s2");
      
       HeadersData data5 = new HeadersData();
       data5.setHeaderName("Data s3");
      
       this.rowList.add(data3);
       this.rowList.add(data4);
       this.rowList.add(data5);
       this.rowList.add(data3);
       this.rowList.add(data4);
       this.rowList.add(data5);
       }
      
       public Vector<HeadersData> getRowList() {
       return rowList;
       }
      }



      And finally HeadersData which has the property I want to display in each of the table cells:

      public class HeadersData {
       private String headerName;
      
       public String getHeaderName() {
       return headerName;
      }
      



      If I try to run my JSP file I get the following error:

      Error 500--Internal Server Error
      
      javax.servlet.jsp.JspTagException: FOREACH_BAD_ITEMS
       at org.richfaces.iterator.SimpleForEachIterator.toForEachIterator(SimpleForEachIterator.java:135)
       at org.richfaces.iterator.SimpleForEachIterator.supportedTypeForEachIterator(SimpleForEachIterator.java:98)
       at org.richfaces.taglib.ColumnsTag.prepare(ColumnsTag.java:539)
       at org.richfaces.taglib.ColumnsTag.doStartTag(ColumnsTag.java:299)
       at jsp_servlet.__table3._jsp__tag33(__table3.java:1731)
       at jsp_servlet.__table3._jsp__tag32(__table3.java:1691)
       at jsp_servlet.__table3._jsp__tag22(__table3.java:1220)
       at jsp_servlet.__table3._jsp__tag21(__table3.java:1161)
       at jsp_servlet.__table3._jspService(__table3.java:350)
       at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
       at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
       at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
       at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
       at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
       at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(RequestDispatcherImpl.java:502)
       at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:251)
       at com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:415)
       at com.sun.faces.application.ViewHandlerImpl.executePageToBuildView(ViewHandlerImpl.java:475)
       at com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:143)
       at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100)
       at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176)
       at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)
       at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
       at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
       at javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)
       at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
       at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
       at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
       at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
       at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
       at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
       at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
       at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:368)
       at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:495)
       at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
       at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
       at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
       at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3496)
       at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
       at weblogic.security.service.SecurityManager.runAs(Unknown Source)
       at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2180)
       at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2086)
       at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1406)
       at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
       at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
      


      Any ideas on why this is happening or any workarounds to display the information?

      Thanks in advance,
      ~Ruben

        • 1. Re: Using subTable to display data from Vector<Vector>
          Ilya Shaikovsky Master

          priovide full page code. which RF version used?

          • 2. Re: Using subTable to display data from Vector<Vector>
            Ruben Jorge Newbie

            Thank you for your reply ilya_shaikovsky.

            I'm using RichFaces 3.3.1.CR1

            The full page code is:

            <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
            "http://www.w3.org/TR/html4/loose.dtd">
            <%@ page contentType="text/html;charset=windows-1252"%>
            <%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
            <%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
            <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
            <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
            <f:view>
             <html>
             <head>
             <meta http-equiv="Content-Type"
             content="text/html; charset=windows-1252"/>
             <title>table3</title>
             </head>
             <body>
            
             <h:form>
            
             <rich:dataTable id="taskList2" width="400" rendered="true" value="#{0}">
             <f:facet name="header">
             <rich:columnGroup>
             <!-- first line of headers -->
             <rich:columns value="#{TaskListBean.headerList}" var="columns" index="ind" colspan="2">
             <h:outputText value="#{columns.headerName}" />
             </rich:columns>
             <!-- second line of headers -->
             <rich:column breakBefore="true" rendered="false">
             </rich:column>
             <rich:columns value="#{TaskListBean.headerList}" var="columns2" index="ind">
             <h:outputText value="#{columns2.headerName}" />
             </rich:columns>
             <rich:columns value="#{TaskListBean.headerList}" var="columns2" index="ind">
             <h:outputText value="#{columns2.headerName}" />
             </rich:columns>
             </rich:columnGroup>
             </f:facet>
             <!-- table data/body -->
             <rich:subTable value="#{TaskListBean.main}" var="data">
             <rich:columns value="#{data.rowList}" var="singleCellData">
             <h:outputText value="#{singleCellData.headerName}" />
             </rich:columns>
             </rich:subTable>
             </rich:dataTable>
             </h:form>
            
             </body>
             </html>
            </f:view>
            



            The headers are working fine if I omit the subTable component. What I need is a way to represent a Java Vector<Vector> inside this subTable. I don't know if there is an easier way to do this.

            • 3. Re: Using subTable to display data from Vector<Vector>
              Ruben Jorge Newbie

              Typo: I meant

              Vector<Vector<String>>


              • 4. Re: Using subTable to display data from Vector<Vector>
                Nick Belaevski Master

                Hello,

                That's not the valid case. rich:columns cannot be created basing on render-time variables (e.g. "data" declared in rich:subTable). You should use some static collection for this case.

                • 5. Re: Using subTable to display data from Vector<Vector>
                  Ruben Jorge Newbie

                  Thank you for your reply nbelaevski.

                  I made a simple example where I use the contents of a Vector inside the rich:columns element:

                  JSF (subTable only):

                  <rich:subTable value="#{0}" var="data">
                   <rich:columns value="#{DataBean.main}" var="singleCellData">
                   <h:outputText value="#{singleCellData}" />
                   </rich:columns>
                  </rich:subTable>
                  


                  My backing bean is:

                  public class DataBean {
                   private Vector<String> main;
                  
                   public Vector<String> getMain() {
                   main = new Vector<String>();
                  
                   main.add("data1");
                   main.add("data2");
                   main.add("data3");
                  
                   return main;
                   }
                  }
                  


                  The table renders as expected, 1 line with 3 columns.

                  What I need is to do the same, but for a dynamic number of lines, meaning I want to create one table line for each vector.

                  The backing bean would be this:

                  public class MatrixBean {
                   private Vector<Vector<String>> main;
                  
                   public Vector<Vector<String>> getMain() {
                   main = new Vector<Vector<String>>();
                  
                   Vector<String> aux1 = new Vector<String>();
                   aux1.add("data1");
                   aux1.add("data2");
                   aux1.add("data3");
                  
                   Vector<String> aux2 = new Vector<String>();
                   aux2.add("dataA");
                   aux2.add("dataB");
                   aux2.add("dataC");
                  
                   return main;
                   }
                  }
                  


                  But I don't know how to associate this structure with rich:subTable and rich:columns. Can you help me please?

                  • 6. Re: Using subTable to display data from Vector<Vector>
                    Ilya Shaikovsky Master

                    1) at first I still can't realize why you need subtable at all.
                    2) explore please our sample carefully for columns component.

                    • 7. Re: Using subTable to display data from Vector<Vector>
                      Ruben Jorge Newbie

                      I noticed I don't need subTable, thank you.

                      I still can't get the datatable to display the values though.

                      My datatable is defined as:

                      <rich:dataTable id="taskList2" width="400" rendered="true" value="#{MatrixBean.main}" var="mainData">
                       <f:facet name="header">
                       <rich:columnGroup>
                       <!-- first line of headers -->
                       <rich:columns value="#{TaskListBean.headerList}" var="columns" index="ind" colspan="2">
                       <h:outputText value="#{columns.headerName}" />
                       </rich:columns>
                       <!-- second line of headers -->
                       <rich:column breakBefore="true" rendered="false">
                       </rich:column>
                       <rich:columns value="#{TaskListBean.headerList}" var="columns2" index="ind">
                       <h:outputText value="#{columns2.headerName}" />
                       </rich:columns>
                       <rich:columns value="#{TaskListBean.headerList}" var="columns2" index="ind">
                       <h:outputText value="#{columns2.headerName}" />
                       </rich:columns>
                       </rich:columnGroup>
                       </f:facet>
                      
                       <!-- table data/body -->
                       <rich:columns value="#{TaskListBean.headerList}" var="singleCellData" index="ind">
                       <h:outputText value="#{mainData[ind]}" />
                       </rich:columns>
                      
                       </rich:dataTable>
                      


                      The headers render fine (#{TaskListBean.headerList}).

                      The actual data for the table is inside another backing bean (MatrixBean). This bean is described in my post above. Do you know how I can display those values in the table cells?

                      Thank you very much for your time.

                      • 8. Re: Using subTable to display data from Vector<Vector>
                        Ruben Jorge Newbie

                        If anyone needs to display values from a Vector of Vectors structure, check this:

                        http://www.jboss.org/index.html?module=bb&op=viewtopic&t=155117