I have some questions about a <tr:table> with an org.apache.myfaces.trinidad.model.CollectionModel.

If I attach a CollectionModel to a <tr:table> as defined in the tag specification, I see some things
happening that I don't understand. Could anybody help me out?

I use the following simple JSP file to create the table (with all irrelevant statements removed):

<?xml version="1.0" encoding="UTF-8" ?>
<jsp:root version="2.0"
  xmlns:jsp="http://java.sun.com/JSP/Page";
  xmlns:f="http://java.sun.com/jsf/core";
  xmlns:h="http://java.sun.com/jsf/html";
  xmlns:tr="http://myfaces.apache.org/trinidad";>
<jsp:directive.page contentType="text/html; charset=utf-8"/>
  <f:view>
     <tr:document title="tr:table test">
        <tr:form>
           <tr:table value="#{blocks.all}" var="row">
              <tr:column>
<f:facet name="header"><tr:outputText value="ID"/></f:facet>
                 <tr:outputText value="#{row.id}"/>
              </tr:column>
           </tr:table>
        </tr:form>
        <h:messages layout="table" globalOnly="true"/>
     </tr:document>
  </f:view>
</jsp:root>

The table is connected to the following bean:

package nl.timeware.vrtsim.beans;
import java.util.*;
import org.apache.myfaces.trinidad.model.*;
public class BlockBean
{ private TableModel tableModel;
  public BlockBean()
  {   tableModel = new TableModel();
  }
  public TableModel getAll()
  {   return tableModel;
  }
  private class TableModel extends CollectionModel
{ private List<BlockRow> blockList;
     private int selectedRow = -1;
     public TableModel()
     {   blockList = new ArrayList<BlockRow>();
        for (int id = 0; id < 5; id++)
           blockList.add(new BlockRow(id));
        setWrappedData(blockList);
     }
     public void setWrappedData(Object data)
     {   blockList = (List<BlockRow>)data;
        selectedRow = blockList.size() > 0 ? 0 : -1;
     }
      public Object getWrappedData()
      {   return blockList;
      }
      public int getRowIndex()
      {   System.out.println("getRowIndex(): " + selectedRow);
         return selectedRow;
      }
      public void setRowIndex(int rowIndex)
      {   System.out.println("setRowIndex(" + rowIndex + ")");
         if (rowIndex < -1)
{ System.out.println("setRowIndex(" + rowIndex + "): throws IllegalArgumentException()");
            throw new IllegalArgumentException("invalid row");
         }
         selectedRow = rowIndex;
      }
      public boolean isRowAvailable()
{ boolean available = selectedRow >= 0 && selectedRow < blockList.size();
         System.out.println("isRowAvailable(): " + available);
         return available;
      }
      public boolean isRowAvailable(int rowIndex)
      {   boolean available = rowIndex >= 0 && rowIndex < blockList.size();
System.out.println("isRowAvailable(" + rowIndex + "): " + available);
         return available;
      }
      public int getRowCount()
      {   System.out.println("getRowCount(): " + blockList.size());
         return blockList.size();
      }
      public Object getRowData()
      {   if (blockList == null)
         {   System.out.println("getRowData(): no list");
            return null;
         }
         else if (selectedRow < 0)
         {   System.out.println("getRowData(): no selected row");
            throw new IllegalArgumentException("invalid row");
         }
         else
{ System.out.println("getRowData(): row = " + blockList.get(selectedRow).getId());
            return blockList.get(selectedRow);
         }
      }
      public Object getRowData(int rowIndex)
      {   if (blockList == null)
         {   System.out.println("getRowData(" + rowIndex + "): no list");
            return null;
         }
         else if (selectedRow < 0)
{ System.out.println("getRowData(" + rowIndex + "): no selected row");
            throw new IllegalArgumentException("invalid row");
         }
         else
{ System.out.println("getRowData(" + rowIndex + "): row = " + blockList.get(selectedRow).getId());
            return blockList.get(selectedRow);
         }
      }
     public Object getRowKey()
     {   if (blockList == null)
        {   System.out.println("getRowKey(): no list");
           return null;
        }
         else if (selectedRow < 0)
        {   System.out.println("getRowKey(): no selection");
return null; // actually should throw new IllegalArgumentException("invalid row");
        }
         else
{ System.out.println("getRowKey(): row = " + selectedRow + "; key = " + blockList.get(selectedRow).getId());
            return blockList.get(selectedRow).getId();
         }
     }
     public void setRowKey(Object key)
     {   System.out.println("setRowKey(" + key + ")");
        if (blockList == null)
        {   System.out.println("setRowKey(" + key + "): no list");
           return;
        }
        else if (key == null)   // not supposed to be called like this
        {   System.out.println("setRowKey(" + key + ")");
           selectedRow = -1;
        }
         else if (selectedRow < 0 && selectedRow >= blockList.size())
{ System.out.println("setRowKey(" + key + "): invalid row " + selectedRow);
            throw new IllegalArgumentException("invalid row");
         }
         else
            for (int index = 0; index < blockList.size(); index++)
               if (blockList.get(index).getId() == (Integer)key)
               {   selectedRow = index;
System.out.println("setRowKey(" + key + "): selected row = " + index);
                  break;
               }
     }
     private class BlockRow
{ private int originalID;
        public BlockRow(int id)
        {   originalID = id;
        }
         public int getId()
         {   return originalID;
         }
     }
  }
}

Now during rendering I get the following output from my printf's:
setRowIndex(-1)
getRowKey(): no selection
getRowKey(): no selection
setRowIndex(-1)
isRowAvailable(): false
getRowKey(): no selection
getRowCount(): 5
isRowAvailable(4): true
getRowCount(): 5
getRowCount(): 5
isRowAvailable(4): true
setRowIndex(0)
isRowAvailable(): true
getRowData(): row = 0
getRowKey(): row = 0; key = 0
getRowIndex(): 0
getRowIndex(): 0
setRowKey(null)
setRowKey(null)
isRowAvailable(): false
getRowKey(): no selection

Question 1: Why is the row index set twice to -1, while plenty of rows are available? (and all the other repetitions...) Question 2: What should I return on getRowKey() when no row is selected? I would like to throw an exception but that stops the whole show... Question 3: Why does it insist on making that non-existent row current by setRowKey(null)? Question 4: Why does it finally throw an org.apache.jasper.el.JspPropertyNotFoundException: /jsp/tr-table.jsp(15,41) '#{row.id}' Property 'id' not readable on type int? public int getId() is a correct signature, isn't it?

Any help would of course very much be appreciated!
Regards, Paul.

Reply via email to