home *** CD-ROM | disk | FTP | other *** search
/ Symantec Visual Cafe for Java 2.5 / symantec-visual-cafe-2.5-database-dev-edition.iso / VCafe / prosrc.bin / DbDataSource.java < prev    next >
Encoding:
Java Source  |  1998-03-18  |  23.8 KB  |  757 lines

  1. /*
  2.  * Copyright (c) 1997 Krumel & Associates, Inc. All Rights Reserved.
  3.  *
  4.  * www.krumel.com - controls@krumel.com
  5.  *
  6.  * Permission is given to the buyer of this package for one software
  7.  * developer to use this software on one CPU (one workstation) and to make
  8.  * one backup copy.  You may uitilize and/or modify this class for use in your
  9.  * projects.  You may distribute or sell any executable which results from
  10.  * using this code in yur application, except a utility or class of similar
  11.  * nature to this product.  You may distribute this product in compiled
  12.  * form only, but soley to be used with your cmpiled executable product
  13.  * for the puposes of dynamic loading. You may NOT redistribute the source
  14.  * code in any form or make it accessible through a network or other
  15.  * distribution media to others. Please refer to the file "copyright.html"
  16.  * for further important copyright and licensing information.
  17.  *
  18.  * The source code is the confidential and proprietary information
  19.  * of Krumel & Associates, Inc. ("Confidential Information").  You shall
  20.  * not disclose such Confidential Information and shall use it only in
  21.  * accordance with the terms of the license agreement you entered into
  22.  * with Krumel & Associates, Inc..
  23.  
  24.  * KRUMEL & ASSOCIATES MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
  25.  * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
  26.  * NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  27.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. KRUMEL & ASSOCIATES SHALL NOT
  28.  * BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
  29.  * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  30.  */
  31.  
  32. package symantec.itools.db.awt;
  33.  
  34. import java.awt.Point;
  35. import java.awt.Image;
  36. import symantec.itools.db.awt.event.*;
  37. import symantec.itools.db.awt.genutil.Matrix;
  38.  
  39. /**
  40.  * A data source designed to support running on top of database APIs like JDBC or dbAnywhere.
  41.  * For APIs that do not provide scrollable cursors, the data source provides the ability to
  42.  * cache result set rows. If caching is provided, the state of each row is maintained by a
  43.  * DataState object. The state of a row can be inspected using the return value of rowState()
  44.  * in conjunction with the DataState class.
  45.  */
  46. public class DbDataSource implements DataSource {
  47.     Matrix          rowCache = new Matrix();
  48.  
  49.     TableView       view;
  50.     DbDataStore     store;
  51.     DbDataUpdater   updater;
  52.     MetaTable       meta;
  53.     boolean         caching = false;
  54.     Data            currData;
  55.     int             currDataRow, currDataCol;
  56.  
  57.     /**
  58.      * Creates a data source for the specified view and database information.
  59.      * @param v THe view that will display the data.
  60.      * @param s The data store responsible for retrieving the information from the
  61.      *      database.
  62.      * @param u The udpater responsible for updating the database information upon
  63.      *
  64.      */
  65.     public DbDataSource(DbDataStore s, DbDataUpdater u, MetaTable m) {
  66.         this(null, s, u, m);
  67.     }
  68.  
  69.     /**
  70.      * Creates a data source for the specified view and database information.
  71.      * @param v THe view that will display the data.
  72.      * @param s The data store responsible for retrieving the information from the
  73.      *      database.
  74.      * @param u The udpater responsible for updating the database information upon
  75.      *
  76.      */
  77.     public DbDataSource(TableView v, DbDataStore s, DbDataUpdater u, MetaTable m) {
  78.         view = v;
  79.         setupSource(s, u, m);
  80.     }
  81.  
  82.     /**
  83.      * Gets teh TableView dsplaying the data for the data source.
  84.      */
  85.     public TableView getView() {
  86.         return view;
  87.     }
  88.  
  89.     /**
  90.      * Sets the data store, updater and meta information classes for the data source.
  91.      */
  92.     public void setupSource(DbDataStore s, DbDataUpdater u, MetaTable m) {
  93.         store = s;
  94.         store.setDbDataSource(this);
  95.         updater = u;
  96.         meta = m;
  97.  
  98.         if (meta != null) {
  99.             meta.setDbDataSource(this);
  100.         }
  101.  
  102.         //cache if store doesn't
  103.         caching = !store.supportsCaching();
  104.     }
  105.  
  106.     /**
  107.      * Sets the TableView displaying the data.
  108.      */
  109.     public void setTableView(TableView v) {
  110.         view = v;
  111.     }
  112.  
  113.     /**
  114.      * Informs the data source whether the TableView will be requesting successive data
  115.      * for read only purposes.
  116.      * @param manual true if the data source should expect read only data requests
  117.      */
  118.     public void fetchMode(boolean manual) {
  119.         store.fetchMode(manual);
  120.     }
  121.  
  122.     /**
  123.      * Sets the Data type for cell data when no data value has been set.
  124.      */
  125.     public void setDefaultData(Data defaultValue) {}
  126.  
  127.     /**
  128.      * Requests the DataSource set an appropriate default data type
  129.      */
  130.     public void setDefaultData() {}
  131.  
  132.     /**
  133.      * Gets whether the DataSource has the ability to configure a TableView.
  134.      * @return True if MetaTable class is set, false otherwise.
  135.      */
  136.     public boolean supportsMeta() {
  137.         return meta != null;
  138.     }
  139.  
  140.     /**
  141.      * Gets the cache used to store data retrieved from database and added rows.
  142.      */
  143.     public Matrix getCache() { return rowCache; }
  144.  
  145.     /**
  146.      * Gets the number of rows currently stored in the cache.
  147.      */
  148.     public int lastCachedRow() {
  149.         return rowCache.rows() - 1;
  150.     }
  151.  
  152.     /**
  153.      * Gets the object that provides meta information.
  154.      */
  155.     public MetaTable getMetaTable() { return meta; }
  156.  
  157.     /**
  158.      * Sets the TableView displaying the data.
  159.      * @exception TypeNotSupported if the data source does not support the type of
  160.      *          action requested or is not successful
  161.      */
  162.     public void setupTableView(TableView v) throws TypeNotSupported {
  163.         if (meta == null) {
  164.             throw new TypeNotSupported("MetaTable not set");
  165.         }
  166.  
  167.         meta.setupTableView(view);
  168.     }
  169.  
  170.     /**
  171.      * Commits the current data.
  172.      * @exception   TypeNotSupported If the data source does not support the type of
  173.      *          action requested or is not successful
  174.      */
  175.     public void commitData() throws TypeNotSupported {
  176.         if (currData != null && currData.changed()) {
  177.             setData(currDataRow, currDataCol-1, currData);
  178.             currData.commit();
  179.             currData = null;
  180.             currDataRow = -1;
  181.         }
  182.     }
  183.  
  184.     /**
  185.      * Informs the data source of the current row of the TableView.
  186.      * @exception TypeNotSupported if the data source does not support the type of
  187.      *          action requested or is not successful
  188.      */
  189.     public void setCurrentRow(int row) throws TypeNotSupported {
  190.         store.setCurrentRow(row);
  191.     }
  192.  
  193.     /**
  194.      * Gets the data for a cell that should only be used for reading. It does
  195.      * not change the cell data being currently edited.
  196.      * @param row the cells row
  197.      * @exception DataNotAvailable if the requested data is not set in the data source
  198.      */
  199.     public Data readData(int row, int col) throws DataNotAvailable {
  200.         col++;
  201.  
  202.         if (currDataRow == row && currDataCol == col) {
  203.             return currData;
  204.         }
  205.  
  206.         //if caching and it is cached then return it
  207.         if (caching && rowCache.contains(row, col)) {
  208.             return (Data)rowCache.elementAt(row, col);
  209.         }
  210.  
  211.         //if not then go get it and then return it
  212.         //cache if store isn't caching for us
  213.             Data d = store.getData(row, col);
  214.  
  215.             if (caching) {
  216.                 rowCache.addElement(row, col, d);
  217.                 markClean(row);
  218.             }
  219.  
  220.             return d;
  221.     }
  222.  
  223.     /**
  224.      * Gets the data for a cell.   <p>
  225.      * Call this method when going to be doing edits. <p>
  226.      * Call commitData() when done with it (usually when lose focus).
  227.      * @exception DataNotAvailable if the requested data is not set in the data source
  228.      */
  229.     public Data getData(Coordinate coords) throws DataNotAvailable {
  230.         return getData(coords.row, coords.col);
  231.     }
  232.  
  233.     /**
  234.      * Gets the data for a cell.   <p>
  235.      * Call this method when going to be doing edits. <p>
  236.      * Call commitData() when done with it (usually when lose focus).
  237.      * @exception DataNotAvailable if the requested data is not set in the data source
  238.      */
  239.     public Data getData(int row, int col) throws DataNotAvailable {
  240.         col++;  //we maintain state information in col = 0 so it is all 1 based
  241.  
  242.         if (currDataRow == row && currDataCol == col) {
  243.             return currData;
  244.         }
  245.         currData = readData(row, col-1);
  246.         currDataRow = row;
  247.         currDataCol = col;
  248.  
  249.         return currData;
  250.     }
  251.  
  252.     /**
  253.      * Called by DbDataStore or DbUpdater to insert a new row to the result set.
  254.      * This method will mark the row as new.
  255.      */
  256.     public void insertResultSetRow(int row, Data data[]) {
  257.         synchronized(rowCache) {
  258.             //remember - row state stored in col 0
  259.             for (int col=1; col<=data.length; col++) {
  260.                 rowCache.updateElement(row, col, data[col-1]);
  261.             }
  262.  
  263.             markNew(row);
  264.         }
  265.     }
  266.  
  267.     /**
  268.      * Called by DbDataStore or DbUpdater to append a new row to the end of the
  269.      * result set. This method will mark the row as new.
  270.      */
  271.     public int appendResultSetRow(Data data[]) {
  272.         synchronized(rowCache) {
  273.             int rows = rowCache.rows();
  274.  
  275.             //remember - row state stored in col 0
  276.             for (int col=1; col<=data.length; col++) {
  277.                 rowCache.addElement(rows, col, data[col-1]);
  278.             }
  279.  
  280.             markNew(rows);
  281.  
  282.             return rows;
  283.         }
  284.     }
  285.  
  286.     /**
  287.      * Called by DbDataStore or DbUpdater to add a new row to the result set.
  288.      * This method will mark the row as clean.
  289.      */
  290.     public void addResultSetRow(int row, Data data[]) {
  291.         //row should already be zero relative by DbDataStore
  292.         //store has obtained a new row of information so store in matrix
  293.         //and mark row as clean
  294.  
  295.         //remember - row state stored in col 0
  296.         for (int col=1; col<=data.length; col++) {
  297.             rowCache.updateElement(row, col, data[col-1]);
  298.         }
  299.  
  300.         markClean(row);
  301.     }
  302.  
  303.     //It is assumed that data has been verified already by data object, but...
  304.     /**
  305.      * Sets the data value for a cell.
  306.      * @param r the row of the cell
  307.      * @param c the column of the cell
  308.      * @param data the data value for the cell
  309.      * @exception   TypeNotSupported If the data source does not support the type of
  310.      *          action requested or is not successful
  311.      */
  312.     public void setData(int row, int col, Data data) throws TypeNotSupported {
  313.         col++;  //we maintain state information in col = 0
  314.         //if cached then mark row for update and change data
  315.         if (caching) {
  316.             rowCache.updateElement(row, col, data);
  317.             markModified(row);
  318.             return;
  319.         }
  320.  
  321.         //not caching so tell source to update
  322.         store.update(row, col, data);
  323.     }
  324.  
  325.     /**
  326.      * Sets the data value for a cell.
  327.      * @param coord the cooridates of the cell
  328.      * @param data the data value for the cell
  329.      * @exception   TypeNotSupported If the data source does not support the type of
  330.      *          action requested or is not successful
  331.      */
  332.     public void setData(Coordinate coord, Data data) throws TypeNotSupported {
  333.         setData(coord.row, coord.col, data);
  334.     }
  335.  
  336.     /**
  337.      * Gets the textual representation of a cell's data
  338.      * @exception DataNotAvailable if the requested data is not set in the data source
  339.      */
  340.     public String getText(Coordinate coords) throws DataNotAvailable {
  341.         return getData(coords).toString();
  342.     }
  343.  
  344.     /**
  345.      * Undeletes a row in the data source
  346.      * @exception   TypeNotSupported If the data source does not support the type of
  347.      *          action requested or is not successful
  348.      */
  349.     public void undeleteRow(int row) throws TypeNotSupported {
  350.         //vj: Added to reset current data before undelete
  351.         currData=null;
  352.         currDataRow=-1;
  353.         if (caching) {
  354.             //for now just assume it was previously changed
  355.             //need to add ability to remember previous state through XOR
  356.             markModified(row);
  357.         }
  358.  
  359.         updater.undeleteRow(row);
  360.     }
  361.  
  362.     /**
  363.      * Deletes or marks a row for deletion from the data source
  364.      * @exception   TypeNotSupported If the data source does not support the type of
  365.      *          action requested or is not successful
  366.      */
  367.     public void deleteRow(int row) throws TypeNotSupported {
  368.         //vj: Added to reset current data before delete
  369.         currData=null;
  370.         currDataRow=-1;
  371.         if (caching) {
  372.             markDeleted(row);
  373.         }
  374.  
  375.         updater.deleteRow(row);
  376.     }
  377.  
  378.     /**
  379.      * Inserts a new row in the data source above the specified row
  380.      * @exception TypeNotSupported if the data source does not support the type of
  381.      *          action requested or is not successful
  382.      */
  383.     public void insertRow(int row) throws TypeNotSupported {
  384.         //vj: Added to reset current data before insert
  385.         currData=null;
  386.         currDataRow=-1;
  387.         updater.insertRow(row);
  388.     }
  389.  
  390.     /**
  391.      * Appends a new row at the end of the data source's data.
  392.      * @exception TypeNotSupported if the data source does not support the type of
  393.      *          action requested or is not successful
  394.      */
  395.     public int appendRow() throws TypeNotSupported {
  396.         return updater.appendRow();
  397.     }
  398.  
  399.     /**
  400.      * Gets whether the data source supports a specified type of data
  401.      */
  402.     public boolean supports(Coordinate coords, int type) {
  403.         if (type == Data.STRING) return true;
  404.  
  405.         return false;
  406.     }
  407.  
  408.     /**
  409.      * Gets an image representation of a cell's data
  410.      * @exception DataNotAvailable if the requested data is not set in the data source
  411.      */
  412.     public Image getImage(Coordinate coords) throws DataNotAvailable {
  413.         return getData(coords).toImage();
  414.     }
  415.  
  416.     /**
  417.      * Gives a data source a chance to perform any actions in response to a table
  418.      * level event.
  419.      */
  420.     public void handleTableEvent(TableEvent e) {
  421.     }
  422.  
  423.     /**
  424.      * Called in response to circulating an event caused by an invocation of
  425.      * TableView.routeEvent().  The event IDs are specified in the CellEvent class
  426.      */
  427.     public void handleCellEvent(CellEvent e) {
  428.         switch(e.getID()) {
  429.             case CellEvent.UNDO_CELL_EVENT:
  430.                 rollback();
  431.                 break;
  432.             case CellEvent.LOST_FOCUS:
  433.                 break;
  434.         }
  435.     }
  436.  
  437.     /**
  438.      * Routes any exceptions generated to the TableView for proper handling which may
  439.      * include putting a message on status bar or logging to a file.
  440.      */
  441.     public void handleException(int row, int col, Exception ex) {
  442.         view.handleException(row, col, ex);
  443.     }
  444.  
  445.     /**
  446.      * Gets the state of the row.
  447.      * @return the state of the row's data as defined by DataState.
  448.      */
  449.     public int rowState(int row) {
  450.         return store.rowState(row);
  451.     }
  452.  
  453.     /**
  454.      * Requests the data source remove all data.
  455.      */
  456.     public void clear() {
  457.         rowCache.removeAllElements();
  458.         currData = null;
  459.         currDataRow = -1;
  460.         store.clear();
  461.     }
  462.  
  463.     /**
  464.      * Requests the data source reread it data.
  465.      */
  466.     public void refresh() {
  467.         //clear cache, clear view, and re-issue query
  468.         rowCache.removeAllElements();
  469.         currData = null;
  470.         currDataRow = -1;
  471.         store.refresh();
  472.     }
  473.  
  474.     /**
  475.      * Requests that any actions performed on a row be undone. The meaning
  476.      * is left open and is to interpreted as appropriate for the type of
  477.      * data source
  478.      * @exception TypeNotSupported if the data source does not support the type of
  479.      *          action requested or is not successful
  480.      */
  481.     public void undoRow(int row) throws TypeNotSupported {
  482.         //vj: Added to reset current data before undo
  483.         currData=null;
  484.         currDataRow=-1;
  485.         store.undoRow(row);
  486.     }
  487.  
  488.     /**
  489.      * Requests the data source save the current state as appopriate.
  490.      * @exception TypeNotSupported if the data source does not support the type of
  491.      *          action requested or is not successful
  492.      */
  493.     public void save() throws TypeNotSupported {
  494.         //iterate cache and update all non-clean rows
  495.         //vj: Added to reset current data before undo
  496.         currData=null;
  497.         currDataRow=-1;
  498.         updater.save();
  499.     }
  500.  
  501.     /**
  502.      * Gets whether a cells data is editable or non-editable
  503.      * @return true if the data may be altered by the user.
  504.      */
  505.     public boolean isDataEditable(int row, int col) {
  506.  
  507.        // System.out.println("Into isDataEditable");
  508.  
  509.         if (meta != null) {
  510.             try {
  511.  
  512.                 //System.out.println( meta.isDataEditable(row, col+1));
  513.  
  514.                 return meta.isDataEditable(row, col+1);
  515.             } catch(DataNotAvailable ex) {
  516.                 return false;
  517.             }
  518.         }
  519.  
  520.         return true;
  521.     }
  522.  
  523.     /**
  524.      * Called by DbDataStore and DbUpdater to add a new row of data to the result
  525.      * set.
  526.      */
  527.     public DataState getRowDataState(int row) {
  528.         return (DataState)rowCache.elementAt(row, 0);
  529.     }
  530.  
  531.     /**
  532.      * Marks the row as modified.
  533.      */
  534.     public void markModified(int row) {
  535.         DataState    state;
  536.  
  537.         if (rowCache.contains(row, 0)) {
  538.             state = (DataState)rowCache.elementAt(row, 0);
  539.             state.markModified();
  540.         } else {
  541.             //it is really new, not modified
  542.             state = new DataState();
  543.             rowCache.addElement(row, 0, state);
  544.             state.markNew();
  545.         }
  546.     }
  547.  
  548.     /**
  549.      * Marks the row as new.
  550.      */
  551.     public void markNew(int row) {
  552.         DataState    state;
  553.  
  554.         if (rowCache.contains(row, 0)) {
  555.             state = (DataState)rowCache.elementAt(row, 0);
  556.         } else {
  557.             state = new DataState();
  558.             rowCache.addElement(row, 0, state);
  559.         }
  560.  
  561.         state.markNew();
  562.     }
  563.  
  564.     /**
  565.      * Marks the row as deleted.
  566.      */
  567.     public void markDeleted(int row) {
  568.         //if something is being deleted it should already be there so
  569.         //let's assume it is there.
  570.         DataState state = (DataState)rowCache.elementAt(row, 0);
  571.         state.markDeleted();
  572.     }
  573.  
  574.     /**
  575.      * Marks the row as clean.
  576.      */
  577.     public void markClean(int row) {
  578.         DataState    state;
  579.  
  580.         if (rowCache.contains(row, 0)) {
  581.             state = (DataState)rowCache.elementAt(row, 0);
  582.         } else {
  583.             state = new DataState();
  584.             rowCache.addElement(row, 0, state);
  585.         }
  586.  
  587.         state.markClean();
  588.     }
  589.  
  590.     /**
  591.      * Gets the last row valid in requested range
  592.      * @exception DataNotAvailable if the requested data is not set in the data source
  593.      */
  594.     public int validDataRowRange(int top, int bottom) throws DataNotAvailable {
  595.         //subtract one to make 0 relative
  596.         return store.validDataRowRange(top, bottom)-1;
  597.     }
  598.  
  599.     /**
  600.      * Gets the number of rows of data stored in the data source
  601.      */
  602.     public int rows() {
  603.         return store.rowsRetrieved();
  604.     }
  605.  
  606.     /**
  607.      * Requests the data source get all of the rows from its source of data.
  608.      */
  609.     public int fetchAllRows() {
  610.         return store.fetchAllRows();
  611.     }
  612.  
  613.     //Here are some methods needed to support DefaultData
  614.     /**
  615.      * Method used to support Defaultdata class. Gets the type of data supported
  616.      * by the cell.
  617.      */
  618.     public int type(int row, int col) {
  619.         return Data.STRING;
  620.     }
  621.  
  622.     /**
  623.      * Rolls the current cell to its original value.
  624.      */
  625.     public void rollback(int row, int col) { rollback(); }
  626.  
  627.     /**
  628.      * Rolls the current cell to its original value.
  629.      */
  630.     public void rollbackCurrentData() {
  631.         rollback();
  632.     }
  633.  
  634.     /**
  635.      * Rolls the current cell to its original value.
  636.      */
  637.     public void rollback() {
  638.         currData = null;
  639.         currDataRow = -1;
  640.     }
  641.  
  642.     /**
  643.      * Method used to support Defaultdata class. Commits the data for the
  644.      * specified cell
  645.      */
  646.     public void commit(int row, int col) {}
  647.  
  648.     /**
  649.      * Is never masked.
  650.      * @return <code>false</code>
  651.      */
  652.     public boolean isMasked(int row, int col) {
  653.         return false;
  654.     }
  655.  
  656.     /**
  657.      * Stubbed out function for future expansion.
  658.      * @exception TypeNotSupported if the data source does not support the type of
  659.      *          action requested or is not successful
  660.      */
  661.     public String getMask(int row, int col) throws TypeNotSupported {
  662.         throw new TypeNotSupported("stubbed");
  663.     }
  664.  
  665.     /**
  666.      * Method used to support Defaultdata class. Gets whether the data for the
  667.      * specified cell supports choice selection lists.
  668.      */
  669.     public boolean supportsChoice(int row, int col) {
  670.         return false;
  671.     }
  672.  
  673.     /**
  674.      * Method used to support Defaultdata class. Gets the choices for the cell to
  675.      * display.
  676.      * @exception TypeNotSupported if the data source does not support the type of
  677.      *          action requested or is not successful
  678.      */
  679.     public Data[] getChoices(int row, int col) throws TypeNotSupported {
  680.         throw new TypeNotSupported("stubbed");
  681.     }
  682.  
  683.     /**
  684.      * Method used to support Defaultdata class. Sets the textual value for a cell.
  685.      */
  686.     public void setText(int row, int col, String t) {}
  687.  
  688.     /**
  689.      * Method used to support Defaultdata class. Inserts a character at the
  690.      * specified location in the data value for a cell.
  691.      * @param row The cell's row
  692.      * @param col The cell's column
  693.      * @param pos The position to insert character
  694.      * @param c The character
  695.      */
  696.     public void insertChar(int row, int col, int pos, char c) {}
  697.  
  698.     /**
  699.      * Method used to support Defaultdata class. Sets the text for a cell to a
  700.      * character
  701.      */
  702.     public void setText(int row, int col, char c) {}
  703.  
  704.     /**
  705.      * Method used to support Defaultdata class.  Appends a character to the end
  706.      * of the textual representation of the cell's data.
  707.      */
  708.     public void appendChar(int row, int col, char c) {}
  709.  
  710.     /**
  711.      * Method used to support Defaultdata class. Clears the textual value of a cell.
  712.      */
  713.     public void clearText(int row, int col) {}
  714.  
  715.     /**
  716.      * Method used to support Defaultdata class. Deletes a character from a cell's
  717.      * data.
  718.      * @param row The cell's row
  719.      * @param col The cell's column
  720.      * @param pos The position to delete character
  721.      */
  722.     public void deleteChar(int row, int col, int pos) {}
  723.  
  724.     /**
  725.      * Method used to support Defaultdata class. Gets a substring from a cell's
  726.      * data.
  727.      * @param row The cell's row
  728.      * @param col The cell's column
  729.      * @param spos The starting position of the substring, inclusive
  730.      * @param epos The last position of the substring, exclusive
  731.      */
  732.     public String subString(int row, int col, int spos, int epos) {
  733.         return "stubbed";
  734.     }
  735.  
  736.     /**
  737.      * Method used to support Defaultdata class. Sets the image data for a cell
  738.      */
  739.     public void setImage(int row, int col, Image i) {}
  740.  
  741.     /**
  742.      * Method used to support Defaultdata class. Gets a string representation of
  743.      * a cell's data.
  744.      */
  745.     public String toString(int row, int col) {
  746.         return "stubbed";
  747.     }
  748.  
  749.     /**
  750.      * Method used to support Defaultdata class. Gets an image representationof
  751.      * a cell's data.
  752.      */
  753.     public Image toImage(int row, int col) {
  754.         return null;
  755.     }
  756. }
  757.