Hi,
I’m new to Vaadin, having come from ZK, and am struggling with the Container concept. I’ve read the Tutorials, searched the site, and looked at some addon source code, but still don’t understand some things.
My goal is to build a CSV Container that can read CSV data. I’ve already got a class [CSVReader]
that takes care of all the details. It returns each line of the CSV as an array of String. Not fancy but it works.
OK, what I understand about Containers so far:
- Containers provide the data model to a range of components, e.g. Table, Select, ComboBox, etc.
- The BeanItemContainer works fabulously with lists of beans.
- additem() - No parameters confuses the hell out of me.
- addItem(Object obj) - Adds an entire ROW of data OR creates an empty row with ‘obj’ as the ‘index’. Not sure which.
- Each Item which is returned by addItem(Object id) is the parent of a set of ‘Property’ objects that make up the individual columns of the table, for example.
My assumptions are as follows:
- Containers are like Models in ZK
- Containers need some form of Rendering code “attached” to represent the data model to the parent class
- addItem adds a whole row of data, or if it has a parameter, the parameter is the index/key value and the returned Item is the empty row, which needs data added. See Line #129 in the code
I get an exception trying to add properties to the returned Item, which does not make sense according to what I understand so far. If this is not the correct way, how to I tell the parent component to handle the String[] (in this case) data?
Here is my code so far:
package com.chm.upload;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import net.flowspace.utils.CSVReader;
import com.vaadin.data.Container.ItemSetChangeNotifier;
import com.vaadin.data.Container.PropertySetChangeNotifier;
import com.vaadin.data.Item;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.Label;
@SuppressWarnings("serial")
public class CSVContainer extends IndexedContainer
implements PropertySetChangeNotifier,
ItemSetChangeNotifier
{
private CSVReader reader = null ;
public CSVContainer(String csvFile) throws FileNotFoundException
{
if (null != csvFile)
{
reader = new CSVReader (csvFile) ;
processFile () ;
}
}
public CSVContainer(String csvFile, boolean hasHeader) throws FileNotFoundException
{
if (null != csvFile)
{
reader = new CSVReader (csvFile, hasHeader) ;
processFile () ;
}
}
public CSVContainer(File csvFile) throws FileNotFoundException
{
if (null != csvFile)
{
reader = new CSVReader (csvFile.getAbsolutePath()) ;
processFile () ;
}
}
public CSVContainer(File csvFile, boolean hasHeader) throws FileNotFoundException
{
if (null != csvFile)
{
reader = new CSVReader (csvFile.getAbsolutePath(), hasHeader) ;
processFile () ;
}
}
private void processFile ()
{
boolean headerPresent = reader.hasHeader() ;
if (null != reader)
{
int headerSize = 0 ;
if (headerPresent)
{
for (String hdr : reader.getHeader())
{
addContainerProperty (hdr, String.class, "") ;
headerSize++ ;
}
}
String[] row;
try
{
row = reader.readNext();
// SpecialOffer! One time Only! We'll build a custom header for you!
if (! headerPresent && null != row && row.length > 0)
for (int ctr = 1 ; ctr <= row.length ; ctr++ )
{
addContainerProperty ("col" + ctr, String.class, "") ;
headerSize++ ;
}
int ctr = 1 ;
while (null != row)
{
Item item = addItem (ctr) ;
for (int id = 0 ; id < headerSize ; id++)
{
item.addItemProperty(id, new Label(row[id]
) ) ; //BUG Generates an exception saying cannot add properties to an IndexedContainer!!???
System.out.print(row[id]
+ " | ") ;
}
System.out.println ();
row = reader.readNext() ;
ctr++ ;
}
reader.close() ;
}
catch (IOException e)
{
e.printStackTrace();
}
} // null != reader
showContents () ;
} // eof: processFile
private void showContents()
{
System.out.println (this.size() + " items in container\n") ;
for (Object id : getAllItemIds())
{
System.out.println ("Item: " + id + " = " + getItem(id) + " [" + getItem(id).getClass().getCanonicalName() + "]
") ;
}
}
} //eof: CSVContainer class
The
showContents
method is there for testing purposes to see if the data is stored correctly.
What I am getting right now, is the columns correctly set, if the list has headers, it reads the correct values into the table, or if none present it correctly adds col1…colN depending on the length of the first row. Which also works fine.
However, for the rows, I’m getting a series of lines in the table, one for each row, but no data showing.
I can’t seem to find a rendering process, like I’ve used in ZK for example. The Property.Viewer interface is unclear if that is the way to solve this.
Sorry if my post is vague but I really am confused, esp. around my assumptions on addItem and how to “paint” the row data.
Thanks in advance,
Anthony