9 Replies Latest reply on May 26, 2009 5:03 AM by Nicolas Gaudin

    ExtendedDataTable NOT in Region => columns resize exception

    Nicolas Gaudin Newbie

      Hi,

      Env:
      FR 3.3.1.GA
      Glassfish V2UR2
      JDK 1.6.0_06

       <a4j:region renderRegionOnly="true">
       <rich:extendedDataTable var="row" rowKeyVar="rowKey"
       id="gformationTable"
      
       style="top:0px;left:0px;position:relative;"
       cellpadding="0" cellspacing="0" lang="#{SessionBean.lng}"
       width="500%" activeClass="active" rowClasses="roweven,rowodd" selectedClass="rowselected"
       value="#{ItcFicheBean.itcFormationDataModel}"
       selection = "#{ItcFormationListeBean.selection}"
       tableState="#{ItcFormationListeBean.tableState}"
       binding="#{ItcFormationListeBean.richTable}"
       >
      
       <a4j:support event="onselectionchange" oncomplete="#{rich:element('gformationRerender')}.click();"/>
      
       </rich:extendedDataTable>
       </a4j:region>
      
      



      When ExtendedDataTable is not put inside an a4j:region, the following exception is generated:

      Caused by: java.lang.ArrayIndexOutOfBoundsException: 8
       at org.richfaces.component.ColumnsSizeState.changeColumnSize(ExtendedDataTableState.java:337)
       at org.richfaces.component.ExtendedDataTableState.changeColumnSize(ExtendedDataTableState.java:173)
       at org.richfaces.component.UIExtendedDataTable.processColumnResize(UIExtendedDataTable.java:186)
       at org.richfaces.component.UIExtendedDataTable.broadcast(UIExtendedDataTable.java:101)
       at org.ajax4jsf.component.UIInclude.broadcast(UIInclude.java:170)
       at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:321)
       at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:296)
       at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:253)
       at org.ajax4jsf.component.AjaxViewRoot.processDecodes(AjaxViewRoot.java:409)
       at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
       at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
       at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
       at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
       ... 37 more
      
      


      When surrounding EDT with a4j:region all works fine.
      Is that requirement that EDT must me inside Regions?


      I am suspecting the a4j:support on event onselectionchange to mess with EDT. Indeed, the event is triggered even on column resize???

      Thanks for your anser


        • 2. Re: ExtendedDataTable NOT in Region => columns resize except
          Nicolas Gaudin Newbie

          Hi,

          dynamically build by code.

          All my tables are build this way and all works great..

          EDT that where not in a4J: region generated mentioned issue.

          Detailed Example

           private HtmlExtendedDataTable richTable;
          
           // Get Table component.
           public HtmlExtendedDataTable getRichTable() {
           LogUtil.log(this.getClass(), richTable);
           if (richTable == null) {
           richTable = new HtmlExtendedDataTable();
           richTable.setSortMode("single");
           richTable.setSelectionMode("multi");
           richTable.setNoDataLabel(MessageUtil.getMessage("liste_empty"));
           richTable.getChildren().addAll(this.getTableRichColumns());
           }
           return richTable;
           }
          
           public void setRichTable(HtmlExtendedDataTable richTable) {
           this.richTable = richTable;
           }
          
          


          and

           @Override
           protected List<HtmlColumn> getTableRichColumns() {
           // Get columns.
          
           //Loop through all visible headers
           headers = GridUtil.getHeaders(groupName, gridName, this.getObjectClass());
           GridColumn gridColumn = null;
           HtmlColumn column = null;
           String header = null;
           Field fld = null;
           String fldName = null;
           UIComponent content = null;
           List<HtmlColumn> columns = new ArrayList<HtmlColumn>(headers.size());
          
           //TableState
           LinkedHashMap<String,String> tableStateVisiblity = new LinkedHashMap<String, String>(headers.size()+1);
           LinkedHashMap<String,String> tableStateSize = new LinkedHashMap<String, String>(headers.size()+1);
           LinkedHashMap<String,String> tableStateOrder = new LinkedHashMap<String, String>(headers.size()+1);
          
          
           //Add Style col : necessary due to Currency Management
           if (styled){
           column = ComponentUtil.getRichColumn(gridName + "StyleCol", "style","#{row.lineStyle};padding:1px 2px;","30");
           content = ComponentUtil.getOutputText(gridName + "Style", true, "#{msgs.grid_style}");
           column.getChildren().add(content);
           columns.add(column);
          
           //TableState
           tableStateVisiblity.put(gridName + "StyleCol", "1");
           tableStateSize.put(gridName + "StyleCol", "30");
           tableStateOrder.put(gridName + "StyleCol", null);
           }
          
          
           Iterator<String> iter = headers.keySet().iterator();
           String genesysName = null;
           String genesysNameXXX = null;
           for (int i = 0; i < headers.size(); i++) {
           content = null;
           try {
           genesysName = iter.next();
           gridColumn = (GridColumn) headers.get(genesysName);
           genesysNameXXX = gridColumn.getGenesysNameXXX();
          
          
           //Fld = @Column field if GridColumn.isJoin()=false
           //OR Fld = @JoinColumn field GridColumn.isJoin()=true
           fld = gridColumn.getEntityField();
           LogUtil.log(this.getClass(), "VISIBLE Field = " + fld.getName() + " with Header = " + gridColumn.getHeader());
           header = gridColumn.getHeader();
           fldName = fld.getName();
          
          
           String reRender = gridColumn.getReRender();
          
          
           String colStyle = "padding:2px 2px;margin:0px;";
          
           column = ComponentUtil.getRichColumn(genesysNameXXX + "Col", header, fldName, true, null, null, "#{row." + fldName + "}");
           boolean numeric = ClassUtil.isNumeric(fld);
           content = ComponentUtil.getInputText(fldName, "#{row." + fldName + "}", null, gridColumn.getNbCar(), lockedOrValidatedDependent,numeric, gridColumn.isReRenderCol(),gridColumn.getReRender());
          
           if (numeric) {
           colStyle += "text-align:right;";
           }
          
          
          
           if (content != null) {
           column.getChildren().add(content);
           }
          
           column.setWidth(Integer.toString(gridColumn.getWidth() + 15) );
           column.setStyle(colStyle);
           column.setVisible(gridColumn.isVisible());
           columns.add(column);
          
           //TableState
           String visibleStr = gridColumn.isVisible()?"1":"0";
           tableStateVisiblity.put(genesysNameXXX + "Col", visibleStr);
           tableStateSize.put(genesysNameXXX + "Col", Integer.toString(gridColumn.getWidth() + 15));
           tableStateOrder.put(genesysNameXXX + "Col", null);
          
          
           } catch (Exception ex) {
           LogUtil.error(this.getClass(), "=====>!!!!!!!!!!!!! ERROR ON COLUMN" + genesysName);
           }
           }
          
          
           return columns;
           }
          
          


          and

           public static HtmlColumn getRichColumn(String id,
           String header,
           String fieldName,
           boolean sortable,
           String sortBy,
           String sortOrder,
           String filterBy) {
           // Get table column.
           HtmlColumn col = new HtmlColumn();
           col.setId(id); // Set id.
          
           String headerLabel = header == null ? " " : header;
           col.setLabel(headerLabel);
          // if (header != null) {
           HtmlOutputText headerFacet = new HtmlOutputText();
           headerFacet.setValue(headerLabel);
           col.getFacets().put("header", headerFacet);
          // }
          
          
           col.setSortable(sortable);
          
           if (sortable) {
           if (sortBy != null) {
           ComponentUtil.setValueExpression(col, "sortBy", sortBy);
           } else {
           ComponentUtil.setValueExpression(col, "sortBy", "#{row." + fieldName + "}");
           }
           if (sortOrder != null) {
           col.setSortOrder(Ordering.valueOf(sortOrder));
           }
           }
          
           if (filterBy != null) {
           ComponentUtil.setValueExpression(col, "filterBy", filterBy);
           col.setFilterEvent("onchange");
           }
          
           return col;
           }
          





          • 4. Re: ExtendedDataTable NOT in Region => columns resize except
            Nick Belaevski Master

            Looks like number of columns is incorrect:

            Caused by: java.lang.ArrayIndexOutOfBoundsException: 8
            so that 9th column cannot be found.

            • 5. Re: ExtendedDataTable NOT in Region => columns resize except
              Nicolas Gaudin Newbie

              HI, thanks for your answer

              I checked this considering the error message and I verified the genrated Table State by the compoenet (not by my code).
              This is correct

              As I said, this is fully working when I surround table by a4j:region!
              As soon As I remove it, this error occurs....

              Other idea???
              Thanks

              • 6. Re: ExtendedDataTable NOT in Region => columns resize except
                Ilya Shaikovsky Master

                which scope ItcFormationListeBean has?

                • 8. Re: ExtendedDataTable NOT in Region => columns resize except
                  Ilya Shaikovsky Master

                  1) binding objects should live not longer that request. And this is limitation not from RF but from JSF. google the session scoped binding and you will see how many problems arise with session scoped binding. I'm not sure about JSF 1.2 specification but JSF 2.0 specification declares this limitation in spec.

                  2) even worse that session binding is keep alived binding. Your object restored by keep alive after the component created. So the component restored from just created bean property and then this property restored from ViewRoot by keep alive.

                  • 9. Re: ExtendedDataTable NOT in Region => columns resize except
                    Nicolas Gaudin Newbie

                    Ok but then what is the solution if we want the rich:column's to be created only once

                    If I bind my EDT to request bean, they are build each time (going into getTableRichColumns) as richTable is always null at bean init

                    Great performance bottleneck.

                    FYI, This meets performance issues due to datatables already mentioned in this forum.
                    http://www.jboss.org/index.html?module=bb&op=viewtopic&t=153308
                    the diffrent workaround (prticularly limitToList=true starting at 3.3.1) do not work

                    Any expert solution?