2 Replies Latest reply on Mar 3, 2009 3:11 PM by cm.tcomp

    scrollabledatatable selection problem cast error

    cm.tcomp

      Hi, I have a question, and I'm not sure if I have something wrong in my environment or if it is a bug...

      I have some code similar to the scrollabledatatable demo code, using SimpleSelection, to find the user selected rows.

      Using the richfaces-ui-3.2.2.GA-bin, the code i have, and the demo code, works.

      I tried to upgrade to the richefaces-ui-3.3.0.GA-bin, and the code broke, with

      java.lang.ClassCastException: java.lang.Integer cannot be cast to org.richfaces.model.ScrollableTableDataModel$SimpleRowKey
      javax.faces.el.EvaluationException: java.lang.ClassCastException: java.lang.Integer cannot be cast to org.richfaces.model.ScrollableTableDataModel$SimpleRowKey
      at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:91)
      at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:91)
      at javax.faces.component.UICommand.broadcast(UICommand.java:383)



      The casting error is occuring in the assignment of
      SimpleRowKey key = (SimpleRowKey) iterator.next();

      When I get the class of iterator.next() with

      public String takeSelection() {
       getSelectedCars().clear();
       Iterator<Object> iterator = getSelection().getKeys();
       while (iterator.hasNext()){
      
      /*
       SimpleRowKey key = (SimpleRowKey) iterator.next();
       getSelectedCars().add(getAllCars().get(key.intValue()));
      */
       Object temp = iterator.next();
       System.out.println( "****takeSelection() called, object type is "
       + temp.getClass() );
       SimpleRowKey key = (SimpleRowKey) temp;
       getSelectedCars().add(getAllCars().get(key.intValue()));
      
       }
       return null;
       }
      


      with the 3.2.2 libraries, I get the correct class, org.richfaces.model.ScrollableTableDataModel$SimpleRowKey.

      with the 3.3.0 libraries, I get
      takeSelection() called, object type is class java.lang.Integer

      any possible ideas? thanks in advance....



      Environment -
      netbeans6.1
      Java 1.6.0_06

      Code - using code from the scrollabledatatable demo on the community page slightly modified - http://www.jboss.org/community/docs/DOC-11857, will reproduce the error.

      For the calling code, I used the the demo xhtml, and put it into a jsp file

      <%@taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
      <%@taglib uri="http://richfaces.org/rich" prefix="rich"%>
      
      <%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
      <%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
      
      <%@page contentType="text/html" pageEncoding="UTF-8"%>
      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
      "http://www.w3.org/TR/html4/loose.dtd">
      
      <html>
       <head>
       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
       <title>JSP Page</title>
       </head>
       <body>
       <h2>Hello World!</h2>
       </body>
       <f:view>
      
       <h:form>
       <%--
       --%>
       <rich:spacer height="30" ></rich:spacer>
       <rich:scrollableDataTable rowKeyVar="rkv" frozenColCount="1" height="400px"
       width="700px" id="carList" rows="40" columnClasses="col"
       value="#{dataTableScrollerBean.allCars}" var="category" sortMode="single"
       selection="#{dataTableScrollerBean.selection}">
       <rich:column id="make">
       <f:facet name="header"><h:outputText styleClass="headerText" value="Make" ></h:outputText></f:facet>
       <h:outputText value="#{category.make}" ></h:outputText>
       </rich:column>
       <rich:column id="model">
       <f:facet name="header"><h:outputText styleClass="headerText" value="Model" ></h:outputText></f:facet>
       <h:outputText value="#{category.model}" ></h:outputText>
       </rich:column>
       <rich:column id="price">
       <f:facet name="header"><h:outputText styleClass="headerText" value="Price" ></h:outputText></f:facet>
       <h:outputText value="#{category.price}" ></h:outputText>
       </rich:column>
       <rich:column id="mileage">
       <f:facet name="header"><h:outputText styleClass="headerText" value="Mileage" ></h:outputText></f:facet>
       <h:outputText value="#{category.mileage}" ></h:outputText>
       </rich:column>
       <rich:column width="200px" id="vin">
       <f:facet name="header"><h:outputText styleClass="headerText" value="VIN" ></h:outputText></f:facet>
       <h:outputText value="#{category.vin}" ></h:outputText>
       </rich:column>
       <rich:column id="stock">
       <f:facet name="header"><h:outputText styleClass="headerText" value="Stock" ></h:outputText></f:facet>
       <h:outputText value="#{category.stock}" ></h:outputText>
       </rich:column>
       </rich:scrollableDataTable>
       <rich:spacer height="20px"></rich:spacer>
      
       <%--
       --%>
       <a4j:commandButton value="Show Current Selection" reRender="table"
       action="#{dataTableScrollerBean.takeSelection}"
       oncomplete="javascript:Richfaces.showModalPanel('panel');"></a4j:commandButton>
       </h:form>
      
       <rich:modalPanel id="panel" autosized="true">
       <f:facet name="header">
       <h:outputText value="Selected Rows"></h:outputText>
       </f:facet>
       <f:facet name="controls">
       <span style="cursor:pointer" onclick="javascript:Richfaces.hideModalPanel('panel')">X</span>
       </f:facet>
       <rich:dataTable value="#{dataTableScrollerBean.selectedCars}" var="sel" id="table">
       <rich:column>
       <f:facet name="header"><h:outputText value="Make" ></h:outputText></f:facet>
       <h:outputText value="#{sel.make}" ></h:outputText>
       </rich:column>
       <rich:column id="model">
       <f:facet name="header"><h:outputText value="Model" ></h:outputText></f:facet>
       <h:outputText value="#{sel.model}" ></h:outputText>
       </rich:column>
       <rich:column id="price">
       <f:facet name="header"><h:outputText value="Price" ></h:outputText></f:facet>
       <h:outputText value="#{sel.price}" ></h:outputText>
       </rich:column>
       <rich:column id="mileage">
       <f:facet name="header"><h:outputText value="Mileage" ></h:outputText></f:facet>
       <h:outputText value="#{sel.mileage}" ></h:outputText>
       </rich:column>
       <rich:column id="stock">
       <f:facet name="header"><h:outputText value="Stock" ></h:outputText></f:facet>
       <h:outputText value="#{sel.stock}" ></h:outputText>
       </rich:column>
       </rich:dataTable>
       </rich:modalPanel>
      
       </f:view>
      </html>
      


      For the backing bean, I used the demo bean, slightly modified in the takeselection routine to return the class of the interator.next() object.




      package org.richfaces.datatablescroller;
      
      import java.math.BigDecimal;
      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.Iterator;
      import java.util.List;
      import java.util.Random;
      
      import org.richfaces.demo.datafilterslider.DemoInventoryItem;
      import org.richfaces.model.ScrollableTableDataModel.SimpleRowKey;
      import org.richfaces.model.selection.SimpleSelection;
      
      /**
       * @author Nick Belaevski - nbelaevski@exadel.com
       * created 02.03.2007
       *
       */
      public class DataTableScrollerBean {
       private SimpleSelection selection = new SimpleSelection();
       private ArrayList<DemoInventoryItem> selectedCars = new ArrayList<DemoInventoryItem>();
       private static int DECIMALS = 1;
       private static int ROUNDING_MODE = BigDecimal.ROUND_HALF_UP;
      
       private List <DemoInventoryItem> allCars = null;
      
       public List <DemoInventoryItem> getAllCars() {
       synchronized (this) {
       if (allCars == null) {
       allCars = new ArrayList<DemoInventoryItem>();
       for (int k = 0; k <= 5; k++) {
       try{
       switch (k) {
       case 0:
       allCars.addAll(createCar("Chevrolet","Corvette", 5));
       allCars.addAll(createCar("Chevrolet","Malibu", 8));
       allCars.addAll(createCar("Chevrolet","S-10", 10));
       allCars.addAll(createCar("Chevrolet","Tahoe", 6));
       break;
      
       case 1:
       allCars.addAll(createCar("Ford","Taurus", 12));
       allCars.addAll(createCar("Ford","Explorer", 11));
       break;
       case 2:
       allCars.addAll(createCar("Nissan","Maxima", 9));
       break;
       case 3:
       allCars.addAll(createCar("Toyota","4-Runner", 7));
       allCars.addAll(createCar("Toyota","Camry", 15));
       allCars.addAll(createCar("Toyota","Avalon", 13));
       break;
       case 4:
       allCars.addAll(createCar("GMC","Sierra", 8));
       allCars.addAll(createCar("GMC","Yukon", 10));
       break;
       case 5:
       allCars.addAll(createCar("Infiniti","G35", 6));
       break;
       /*case 6:
       allCars.addAll(createCar("UAZ","469", 6));
       break;*/
       default:
       break;
       }
       }catch(Exception e){
       System.out.println("!!!!!!loadAllCars Error: " + e.getMessage());
       e.printStackTrace();
       }
       }
       }
       }
      
       return allCars;
       }
      
       public int genRand() {
       return rand(1,10000);
       }
      
       public List <DemoInventoryItem> createCar(String make, String model, int count){
      
       ArrayList <DemoInventoryItem> iiList = null;
      
       try{
       int arrayCount = count;
      
       DemoInventoryItem[] demoInventoryItemArrays = new DemoInventoryItem[arrayCount];
      
       for (int j = 0; j < demoInventoryItemArrays.length; j++){
       DemoInventoryItem ii = new DemoInventoryItem();
      
       ii.setMake(make);
       ii.setModel(model);
       ii.setStock(randomstring(6,7));
       ii.setVin(randomstring(14,15));
       ii.setMileage(new BigDecimal(rand(5000,80000)).setScale(DECIMALS, ROUNDING_MODE));
       ii.setMileageMarket(new BigDecimal(rand(25000,45000)).setScale(DECIMALS, ROUNDING_MODE));
       ii.setPrice(new Integer(rand(15000,55000)));
       ii.setPriceMarket(new BigDecimal(rand(15000,55000)).setScale(DECIMALS, ROUNDING_MODE));
       ii.setDaysLive(rand(1,90));
       ii.setChangeSearches(new BigDecimal(rand(0,5)).setScale(DECIMALS, ROUNDING_MODE));
       ii.setChangePrice(new BigDecimal(rand(0,5)).setScale(DECIMALS, ROUNDING_MODE));
       ii.setExposure(new BigDecimal(rand(0,5)).setScale(DECIMALS, ROUNDING_MODE));
       ii.setActivity(new BigDecimal(rand(0,5)).setScale(DECIMALS, ROUNDING_MODE));
       ii.setPrinted(new BigDecimal(rand(0,5)).setScale(DECIMALS, ROUNDING_MODE));
       ii.setInquiries(new BigDecimal(rand(0,5)).setScale(DECIMALS, ROUNDING_MODE));
       demoInventoryItemArrays[j] = ii;
      
       }
      
       iiList = new ArrayList<DemoInventoryItem>(Arrays.asList(demoInventoryItemArrays));
      
       }catch(Exception e){
       System.out.println("!!!!!!createCategory Error: " + e.getMessage());
       e.printStackTrace();
       }
       return iiList;
       }
      
       public static int rand(int lo, int hi)
       {
       Random rn2 = new Random();
       //System.out.println("**" + lo);
       //System.out.println("**" + hi);
       int n = hi - lo + 1;
       int i = rn2.nextInt() % n;
       if (i < 0)
       i = -i;
       return lo + i;
       }
      
       public static String randomstring(int lo, int hi)
       {
       int n = rand(lo, hi);
       byte b[] = new byte[n];
       for (int i = 0; i < n; i++)
      /* b+ = (byte)rand('A','Z' ); */
       b = (byte) rand('A', 'Z');
       return new String(b);
       }
      
       public SimpleSelection getSelection() {
       return selection;
       }
      
       public void setSelection(SimpleSelection selection) {
       System.out.println("Setting Started");
       this.selection = selection;
       System.out.println("Setting Complete");
       }
      
       public String takeSelection() {
       getSelectedCars().clear();
       Iterator<Object> iterator = getSelection().getKeys();
       while (iterator.hasNext()){
      
       /*
       SimpleRowKey key = (SimpleRowKey) iterator.next();
       getSelectedCars().add(getAllCars().get(key.intValue()));
       */
       Object temp = iterator.next();
       System.out.println( "****takeSelection() called, object type is "
       + temp.getClass() );
       SimpleRowKey key = (SimpleRowKey) temp;
       getSelectedCars().add(getAllCars().get(key.intValue()));
      
       }
       return null;
       }
      
       public ArrayList<DemoInventoryItem> getSelectedCars() {
       return selectedCars;
       }
      
       public void setSelectedCars(ArrayList<DemoInventoryItem> selectedCars) {
       this.selectedCars = selectedCars;
       }
       }


      all other files are from the current live demo source, and packages were construted as listed in the package definitions..

        • 1. Re: scrollabledatatable selection problem cast error
          konstantin.mishin

          Since version 3.3.0 scrollabledatatable use by default less problematic org.richfaces.model.ModifiableModel instead of org.richfaces.model.ScrollableTableDataModel. This model use java.lang.Integer as rowKey. So you might do something like this:

           getSelectedCars().add(getAllCars().get(iterator.next()));
          

          instead of
           Object temp = iterator.next();
           SimpleRowKey key = (SimpleRowKey) temp;
           getSelectedCars().add(getAllCars().get(key.intValue()));
          


          • 2. Re: scrollabledatatable selection problem cast error
            cm.tcomp

            Thank you for your reply.... I wasn't sure what had happened....

            For additional questions, where would I find information in the documentation on this, and where is the documentation on org.richfaces.model.ModifiableModel located? I looked in the 3.3.0 framework and component api docs, and didn't find it..... thank you again in advance.