Clover coverage report - angkor - 0.4
Coverage timestamp: ti okt 15 2002 22:32:48 CEST
file stats: LOC: 373   Methods: 33
NCLOC: 261   Classes: 1
Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover.
 
 Source file Conditionals Statements Methods TOTAL
Table.java 50% 61,7% 78,8% 62,4%
 1   
 /*
 2   
  * Angkor Web Framework
 3   
  *
 4   
  * Distributable under LGPL license.
 5   
  * See terms of license at gnu.org.
 6   
  */
 7   
 package com.tirsen.angkor.table;
 8   
 
 9   
 import com.tirsen.angkor.Debug;
 10   
 import com.tirsen.angkor.RenderContext;
 11   
 import com.tirsen.angkor.View;
 12   
 import com.tirsen.angkor.event.ChangeEvent;
 13   
 import com.tirsen.angkor.event.ChangeListener;
 14   
 import com.tirsen.angkor.widget.Container;
 15   
 import com.tirsen.angkor.widget.ValueModel;
 16   
 import org.apache.log4j.Category;
 17   
 
 18   
 import java.io.IOException;
 19   
 import java.util.ArrayList;
 20   
 import java.util.Collection;
 21   
 import java.util.Iterator;
 22   
 import java.util.List;
 23   
 
 24   
 /**
 25   
  * The table should support the following features:
 26   
  * Implemented ones:
 27   
  * <li> Fetch values from the model.
 28   
  * <li> A default cell-view-factory.
 29   
  * <li> Cell-view-factories for each column overriding the default one.
 30   
  * <li> Cell-view-factories for rows not getting values from the model.
 31   
  * (for example a column for executing actions on the object on the row or for marking rows to remove)
 32   
  * TODOs:
 33   
  * <li> Row-view-factories for rows not getting values from the model.
 34   
  * (for example a last line for adding new objects)
 35   
  * <li> Inserting view-only view-factories before and after columns and rows.
 36   
  *
 37   
  * The implicit model and view-only row-view-factories and column-view-factories will probably
 38   
  * be refactored into a TableColumn-class instead. The TableColumn-class has an index into the model
 39   
  * if it is from the model and a view-factory for the cells. This way columns can be arranged in any order
 40   
  * and still maintain a simple link to the model. This does not support the view-only rows so oftenly
 41   
  * used on the web for creating a new row in the model, ie. a view-only row is not supported
 42   
  * (in contrast to the view-only columns which are supported).
 43   
  *
 44   
  * @author $Author: tirsen $
 45   
  * @version $Revision: 1.5 $
 46   
  * <BR>
 47   
  * $Id: Table.java,v 1.5 2002/10/09 21:37:37 tirsen Exp $
 48   
  */
 49   
 public class Table extends Container
 50   
 {
 51   
     private static final Category logger = Debug.getCategory();
 52   
 
 53   
     private TableModel model;
 54   
     private TableCellViewFactory viewFactory;
 55   
     private boolean readOnly = true;
 56   
 
 57   
     /**
 58   
      * The created views are cached so that errors and other view-state can be displayed.
 59   
      */
 60   
     private List views;
 61   
 
 62   
     /**
 63   
      * A list of <code>TableColumn</code>s.
 64   
      */
 65   
     private List tableColumns;
 66   
 
 67  2
     public Table()
 68   
     {
 69  2
         this(true);
 70   
     }
 71   
 
 72  2
     public Table(boolean readOnly)
 73   
     {
 74  2
         this.readOnly = readOnly;
 75   
     }
 76   
 
 77   
     private ChangeListener resetCreatedViewsListener = new ChangeListener()
 78   
     {
 79  29
         public void stateChanged(ChangeEvent evt)
 80   
         {
 81  29
             System.out.println("resetting");
 82  29
             resetCreatedViews();
 83   
         }
 84   
     };
 85   
 
 86  2
     public void setModel(TableModel model)
 87   
     {
 88  1
         if (this.model != null) this.model.removeChangeListener(resetCreatedViewsListener);
 89  2
         this.model = model;
 90  2
         if (this.model != null) this.model.addChangeListener(resetCreatedViewsListener);
 91  2
         resetCreatedViews();
 92  2
         createTableColumns();
 93   
     }
 94   
 
 95  5
     public List getRowViews(int row)
 96   
     {
 97  5
         maybeCreateCellViews();
 98  5
         List cells = (List) views.get(row - getStartRow());
 99   
 
 100  5
         return cells;
 101   
     }
 102   
 
 103  2
     public void setReadOnly(boolean readOnly)
 104   
     {
 105  2
         this.readOnly = readOnly;
 106   
     }
 107   
 
 108  5
     private void maybeCreateCellViews()
 109   
     {
 110  5
         if (views == null)
 111   
         {
 112  4
             logger.debug("recreating table cell views");
 113  4
             createCellViews();
 114   
         }
 115   
     }
 116   
 
 117  4
     private void createCellViews()
 118   
     {
 119  4
         int capacity = getEndRow() - getStartRow() + 1;
 120  4
         views = new ArrayList(capacity);
 121  4
         int end = getEndRow();
 122  4
         for (int row = getStartRow(); row <= end; row++)
 123   
         {
 124  9
             int columns = getColumnCount();
 125  9
             Collection cells = new ArrayList(columns);
 126   
 
 127  9
             for (int columnIndex = 0; columnIndex < columns; columnIndex++)
 128   
             {
 129  15
                 TableColumn column = getTableColumn(columnIndex);
 130   
 
 131  15
                 if (column.isVisible())
 132   
                 {
 133  15
                     View view = column.getCellView(this, row, columnIndex);
 134  15
                     view.setContainer(this);
 135  15
                     cells.add(view);
 136   
                 }
 137   
             }
 138  9
             views.add(cells);
 139   
         }
 140   
     }
 141   
 
 142  5
     public View getCellView(int row, int column)
 143   
     {
 144  5
         return (View) getRowViews(row).get(column);
 145   
     }
 146   
 
 147  15
     private TableColumn getTableColumn(int column)
 148   
     {
 149  15
         return (TableColumn) tableColumns.get(column);
 150   
     }
 151   
 
 152  0
     public ValueModel getCellModel(int row, int column)
 153   
     {
 154  0
         TableColumn tableColumn = getTableColumn(column);
 155  0
         return tableColumn.getCellModel(row);
 156   
     }
 157   
 
 158   
     /**
 159   
      * Call this method when we have a suspicion that cell-views will need to be recreated.
 160   
      */
 161  39
     public void resetCreatedViews()
 162   
     {
 163  39
         views = null;
 164   
     }
 165   
 
 166  0
     public List getChildren()
 167   
     {
 168  0
         List all = super.getChildren();
 169  0
         for (Iterator iterator = views.iterator(); iterator.hasNext();)
 170   
         {
 171  0
             List cells = (List) iterator.next();
 172  0
             all.addAll(cells);
 173   
         }
 174  0
         return all;
 175   
     }
 176   
 
 177  2
     private TableCellViewFactory createDefaultTableCellViewFactory()
 178   
     {
 179  2
         if (readOnly)
 180  2
             return new ReadOnlyCellViewFactory();
 181   
         else
 182  0
             return new DefaultTableCellViewFactory();
 183   
     }
 184   
 
 185  3
     public TableCellViewFactory getViewFactory()
 186   
     {
 187  2
         if (viewFactory == null) viewFactory = createDefaultTableCellViewFactory();
 188  3
         return viewFactory;
 189   
     }
 190   
 
 191   
     /**
 192   
      * Creates all TableColumns based upon the TableModel.
 193   
      * These can be modified <em>after</em> setting the model.
 194   
      * When the model is set the table-columns are recreated.
 195   
      */
 196  2
     private void createTableColumns()
 197   
     {
 198  2
         int columns = getTableModel().getColumnCount();
 199  2
         tableColumns = new ArrayList(columns);
 200  2
         for (int column = 0; column < columns; column++)
 201   
         {
 202  3
             TableColumn tableColumn = new TableColumn(getTableModel(), column);
 203  3
             tableColumn.setViewFactory(getViewFactory());
 204  3
             addTableColumn(tableColumn);
 205   
         }
 206   
     }
 207   
 
 208  0
     public void setTableCellViewFactory(TableCellViewFactory viewFactory)
 209   
     {
 210  0
         this.viewFactory = viewFactory;
 211   
     }
 212   
 
 213  6
     public int getRowCount()
 214   
     {
 215  6
         return getTableModel().getRowCount();
 216   
     }
 217   
 
 218   
     /**
 219   
      * Returns the number of columns table.
 220   
      * Note that this is necessarily not the same number of columns as in the model.
 221   
      */
 222  9
     public int getColumnCount()
 223   
     {
 224  9
         return tableColumns == null ? 0 : tableColumns.size();
 225   
     }
 226   
 
 227  24
     public TableModel getTableModel()
 228   
     {
 229  1
         if (model == null) model = createDefaultTableModel();
 230  24
         return model;
 231   
     }
 232   
 
 233  1
     protected TableModel createDefaultTableModel()
 234   
     {
 235  1
         return new DefaultTableModel();
 236   
     }
 237   
 
 238  0
     public String getColumnName(int column)
 239   
     {
 240  0
         return getTableModel().getColumnName(column);
 241   
     }
 242   
 
 243   
     /**
 244   
      * If any number is set to a negative number it is subtracted from the number of rows.
 245   
      * As a special case of this setting end to -1 sets the range to end at the last row.
 246   
      * If end is lower or equal to start sets the range to show all.
 247   
      */
 248  5
     public void setRange(int start, int end)
 249   
     {
 250  5
         resetCreatedViews();
 251  5
         if (end <= start)
 252   
         {
 253  0
             start = 0;
 254  0
             end = -1;
 255   
         }
 256  5
         model.setRange(start, end);
 257   
     }
 258   
 
 259   
     /**
 260   
      * Insert a new column at the specified index.
 261   
      */
 262  0
     public void addTableColumn(int index, TableColumn column)
 263   
     {
 264  0
         resetCreatedViews();
 265  0
         tableColumns.add(index, column);
 266  0
         column.addChangeListener(resetCreatedViewsListener);
 267   
     }
 268   
 
 269   
     /**
 270   
      * Add a new column at the end.
 271   
      */
 272  3
     public void addTableColumn(TableColumn column)
 273   
     {
 274  0
         if (tableColumns == null) tableColumns = new ArrayList();
 275  3
         resetCreatedViews();
 276  3
         tableColumns.add(column);
 277  3
         column.addChangeListener(resetCreatedViewsListener);
 278   
     }
 279   
 
 280  0
     public void setColumnCellViewFactory(int column, TableCellViewFactory columnFactory)
 281   
     {
 282  0
         if (tableColumns == null) tableColumns = new ArrayList();
 283  0
         resetCreatedViews();
 284  0
         TableColumn tableColumn = getTableColumn(column);
 285  0
         tableColumn.setViewFactory(columnFactory);
 286   
     }
 287   
 
 288  21
     public int getStartRow()
 289   
     {
 290  21
         return model.getStart();
 291   
     }
 292   
 
 293  12
     public int getEndRow()
 294   
     {
 295  12
         return model.getEnd();
 296   
     }
 297   
 
 298   
     private int scrollStart = 0;
 299   
     private int scrollEnd = 0;
 300   
     private int scrollNumberOfRows = 0;
 301   
 
 302  1
     public void scrollToStart()
 303   
     {
 304  1
         scrollStart = 0;
 305  1
         scrollEnd = scrollNumberOfRows - 1;
 306  1
         setRange(scrollStart, scrollEnd);
 307   
     }
 308   
 
 309  2
     public void scrollForward()
 310   
     {
 311  2
         scrollStart += scrollNumberOfRows;
 312  2
         scrollEnd += scrollNumberOfRows;
 313  2
         setRange(scrollStart, scrollEnd);
 314   
     }
 315   
 
 316  2
     public void scrollBackward()
 317   
     {
 318  2
         scrollStart -= scrollNumberOfRows;
 319  2
         scrollEnd -= scrollNumberOfRows;
 320  2
         setRange(scrollStart, scrollEnd);
 321   
     }
 322   
 
 323   
     /**
 324   
      * Sets the maximum number of rows for scrolling. If set to 0 disables scrolling (ie. shows all).
 325   
      * A call to this method automatically scrolls to the start of the table.
 326   
      */
 327  1
     public void setNumberOfScrollRows(int numberOfRows)
 328   
     {
 329  1
         this.scrollNumberOfRows = numberOfRows;
 330  1
         scrollToStart();
 331   
     }
 332   
 
 333  0
     public void render(RenderContext context) throws IOException
 334   
     {
 335  0
         context.startTag("table id=\"" + uniqueId(context) + "\" border=\"" + (isDebugTables() ? "1" : "0") + "\"");
 336   
 
 337   
         //int modelColumns = getTableModel().getColumnCount();
 338   
 
 339  0
         context.startTag("tr");
 340  0
         for (int columnIndex = 0; columnIndex < getColumnCount(); columnIndex++)
 341   
         {
 342  0
             TableColumn column = getTableColumn(columnIndex);
 343  0
             if (column.isVisible())
 344   
             {
 345  0
                 String name = column.getColumnName();
 346  0
                 context.startTag("th");
 347  0
                 if (name != null)
 348  0
                     context.println(name);
 349   
                 else
 350  0
                     context.println("&nbsp;");
 351  0
                 context.endTag("th");
 352   
             }
 353   
         }
 354  0
         context.endTag("tr");
 355   
 
 356  0
         int endRow = getEndRow();
 357  0
         for (int row = getStartRow(); row <= endRow; row++)
 358   
         {
 359  0
             context.startTag("tr");
 360  0
             Iterator iterator = getRowViews(row).iterator();
 361  0
             while (iterator.hasNext())
 362   
             {
 363  0
                 View cell = (View) iterator.next();
 364  0
                 context.startTag("td");
 365  0
                 cell.render(context);
 366  0
                 context.endTag("td");
 367   
             }
 368  0
             context.endTag("tr");
 369   
         }
 370  0
         context.endTag("table");
 371   
     }
 372   
 }
 373