package org.geotools.swing.table; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.swing.table.AbstractTableModel; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.util.NullProgressListener; import org.jdesktop.swingworker.SwingWorker; import org.opengis.feature.Feature; import org.opengis.feature.FeatureVisitor; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; /** * A Swing {@code TableModel} to retrieve attribute values from * each feature in a feature collection and cache them for a * {@code JTable} * <p> * * * @source $URL$ */ public class FeatureCollectionTableModel extends AbstractTableModel { private static final long serialVersionUID = -7119885084300393935L; private SimpleFeatureType schema; List<Object[]> cache = new ArrayList<Object[]>(); public IOException exception; /** * A worker class to get the attributes of each feature and load * them into the {@code TableModel}. The work is performed on a * background thread. */ class TableWorker extends SwingWorker<List<Object[]>, Object[]> { SimpleFeatureCollection features; /** * Constructor * * @param features the feature collection to be loaded into the table */ TableWorker( SimpleFeatureCollection features ) { this.features = features; } /** * {@code SwingWorker} method to visit each feature and retrieve * its attributes */ public List<Object[]> doInBackground() { List<Object[]> list = new ArrayList<Object[]>(); final NullProgressListener listener = new NullProgressListener(); try { features.accepts( new FeatureVisitor() { public void visit(Feature feature) { SimpleFeature simple = (SimpleFeature) feature; Object[] values = simple.getAttributes().toArray(); ArrayList<Object> row = new ArrayList<Object>( Arrays.asList( values )); row.add(0, simple.getID() ); publish( row.toArray() ); if( isCancelled() ) listener.setCanceled(true); } } , listener ); } catch (IOException e) { exception = e; } return list; } /** * Add a batch of feature data to the table * * @param chunks batch of feature data */ @Override protected void process(List<Object[]> chunks) { int from = cache.size(); cache.addAll( chunks ); int to = cache.size(); fireTableRowsInserted( from, to ); } } TableWorker load; /** * Constructor * * @param features the feature collection to load into the table */ public FeatureCollectionTableModel( SimpleFeatureCollection features ){ this.load = new TableWorker( features ); load.execute(); this.schema = features.getSchema(); } /** * Cancel the running job, if any */ public void dispose() { load.cancel(false); } /** * Retrieve the specified column name * * @param column column index * * @return the column name */ @Override public String getColumnName(int column) { if( column == 0 ){ return "FeatureIdentifer"; } return schema.getDescriptor( column-1 ).getLocalName(); } /** * Get the number of columns in the table * * @return the number of columns */ public int getColumnCount() { if( exception != null ){ return 1; } return schema.getAttributeCount()+1; } /** * Get the number of rows in the table * * @return the number of rows */ public int getRowCount() { if( exception != null ){ return 1; } return cache.size(); } /** * Get the value of a specified table entry * * @param rowIndex the row index * @param columnIndex the column index * * @return the table entry */ public Object getValueAt(int rowIndex, int columnIndex) { if ( rowIndex < cache.size() ){ Object row[] = cache.get( rowIndex ); return row[ columnIndex ]; } return null; } }