zinger.bsheet
Class BSHTableModel

java.lang.Object
  extended by javax.swing.table.AbstractTableModel
      extended by javax.swing.table.DefaultTableModel
          extended by zinger.bsheet.BSHTableModel
All Implemented Interfaces:
java.io.Serializable, java.util.EventListener, javax.swing.event.CellEditorListener, javax.swing.table.TableModel
Direct Known Subclasses:
TableSort.ComparatorTableModel

public class BSHTableModel
extends javax.swing.table.DefaultTableModel
implements javax.swing.event.CellEditorListener

Core Bean Sheet functionality. This class provides integration between Bean Shell and Swing. Also contains some parsing and formatting logic.

Author:
Alexey Zinger (inline_four@yahoo.com)
See Also:
Serialized Form

Nested Class Summary
 class BSHTableModel.BSHCellEditor
          Extentions to default cell editing.
 class BSHTableModel.BSHCellRenderer
          Extensions to default cell rendering.
 
Field Summary
protected  java.util.Map appearanceMap
           
protected  bsh.Interpreter bsh
          Instance of Bean Shell interpreter.
protected  java.lang.Object[][] cache
          Evaluation cache.
protected  java.util.regex.Pattern cellRangePattern
          Regular expression object representing a cell range iterator (e.g.
protected  java.util.regex.Pattern cellRefPattern
          Regular expression object representing a cell address reference (e.g.
protected  java.util.regex.Pattern cellRelativeRefPattern
          Regular expression object representing a relative cell reference (e.g.
protected  java.util.Map columnFormats
          A map of column format arrays.
protected  Dependencies dependencies
          Two-way dependencies tracker.
protected  int editingColumn
          Current column being edited.
protected  int editingRow
          Current row being edited.
protected  boolean rowIndexes
          Controls whether the left-most column (index 0) shows row index.
protected  ObjectPool setRecycler
          Object pool for Set objects.
protected  ObjectPool stringBufferRecycler
          Object pool for StringBuffer objects.
protected  boolean suppressDependencies
           
protected  java.util.BitSet[] valuesCached
           
 
Fields inherited from class javax.swing.table.DefaultTableModel
columnIdentifiers, dataVector
 
Fields inherited from class javax.swing.table.AbstractTableModel
listenerList
 
Constructor Summary
BSHTableModel(int rowCount, int columnCount)
          Instantiates the model using initial row and column counts.
 
Method Summary
 void editingCanceled(javax.swing.event.ChangeEvent ev)
           
 void editingStopped(javax.swing.event.ChangeEvent ev)
           
 java.lang.Object evalValueAt(int column, int row)
          Evaluates a value at the given cell address.
 void fireTableChanged(javax.swing.event.TableModelEvent ev)
           
 void fireTableStructureChanged()
           
 void followDependencies(int column, int row)
          Calls recursive followDependencies(Point, Set).
protected  void followDependencies(java.awt.Point coord, java.util.Set processed)
          Recursively runs according to cell's dependencies.
 java.lang.Object formatValueAt(java.lang.Object value, int column, int row)
          Formats the given value using formatting rules for the given address.
 Appearance getAppearance(int column, int row, boolean mutable)
           
 java.util.Map getAppearanceMap()
           
 java.lang.Class getColumnClass(int column)
          Extends default behavior to return a class object representing JTableHeader for column 0.
 java.lang.String getColumnName(int column)
          Extends default behavior to return null for column 0.
 java.text.Format getFormat(int column, int row)
          Returns the format object associated with the given cell or column.
 java.util.Map getFormats()
          Returns internal format map.
 int getLastNonEmptyColumn()
           
 int getLastNonEmptyRow()
           
 java.lang.Object getValueAt(int row, int column)
          Extends default behavior to always return row index for column 0.
 boolean isCellEditable(int row, int column)
          Extends default behavior to return false for column 0.
protected  boolean isValueCached(int column, int row)
          Checks for cache state for a specific cell.
protected  void refreshCacheAndDependencies()
          Recreates internal value cache and dependencies objects (cache and dependencies).
protected  void refreshLastNonEmpty()
           
 Appearance removeAppearance(int column, int row)
           
 java.lang.String replaceReferences(java.lang.String evalString, java.util.Set dependencies)
          Replaces cell address references with Bean Shell-compatible statements.
 void requestDependency(int causeCol, int causeRow, int effectCol, int effectRow)
          Requests a dependency from one cell to another.
 void setAppearanceMap(java.util.Map appearanceMap)
           
 void setFormat(java.text.Format format, int column, int row)
          Associates the given format object with the given cell or column.
 void setFormats(java.util.Map formats)
          Sets internal format map.
 void setValueAt(java.lang.Object value, int row, int column)
          Sets a value at the given address.
protected  void setValueCached(boolean cached, int column, int row)
          Sets cache state for a specific cell.
 void sort(int startRow, int nRows, int[] cols, java.util.Comparator[] comps)
          Sorts rows of data in the model in the specified columns spanning nRows rows starting with startRow.
 
Methods inherited from class javax.swing.table.DefaultTableModel
addColumn, addColumn, addColumn, addRow, addRow, convertToVector, convertToVector, getColumnCount, getDataVector, getRowCount, insertRow, insertRow, moveRow, newDataAvailable, newRowsAdded, removeRow, rowsRemoved, setColumnCount, setColumnIdentifiers, setColumnIdentifiers, setDataVector, setDataVector, setNumRows, setRowCount
 
Methods inherited from class javax.swing.table.AbstractTableModel
addTableModelListener, findColumn, fireTableCellUpdated, fireTableDataChanged, fireTableRowsDeleted, fireTableRowsInserted, fireTableRowsUpdated, getListeners, getTableModelListeners, removeTableModelListener
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

editingRow

protected int editingRow
Current row being edited.


editingColumn

protected int editingColumn
Current column being edited.


bsh

protected final bsh.Interpreter bsh
Instance of Bean Shell interpreter.


cellRefPattern

protected final java.util.regex.Pattern cellRefPattern
Regular expression object representing a cell address reference (e.g. [B10]).


cellRangePattern

protected final java.util.regex.Pattern cellRangePattern
Regular expression object representing a cell range iterator (e.g. [B2:C15]).


cellRelativeRefPattern

protected final java.util.regex.Pattern cellRelativeRefPattern
Regular expression object representing a relative cell reference (e.g. [-1+2]).


stringBufferRecycler

protected final ObjectPool stringBufferRecycler
Object pool for StringBuffer objects. This object is thread safe.


setRecycler

protected final ObjectPool setRecycler
Object pool for Set objects. This object is thread safe.


dependencies

protected transient Dependencies dependencies
Two-way dependencies tracker.


cache

protected transient java.lang.Object[][] cache
Evaluation cache. This two-dimensional array is used by evalValueAt(int, int) method. As of 0.8, the model accomodates cached null values by means of explicity cached status flags.

See Also:
evalValueAt(int, int), isValueCached(int, int), setValueCached(boolean, int, int), valuesCached

valuesCached

protected transient java.util.BitSet[] valuesCached
Since:
Bean Sheet 0.8
See Also:
evalValueAt(int, int), isValueCached(int, int), setValueCached(boolean, int, int), dependencies

columnFormats

protected java.util.Map columnFormats
A map of column format arrays. This object maps column name to an array of formats.

See Also:
getFormat(int, int), setFormat(java.text.Format, int, int)

appearanceMap

protected java.util.Map appearanceMap

rowIndexes

protected boolean rowIndexes
Controls whether the left-most column (index 0) shows row index. This is a bit of a band-aid measure meant to help with TableSort.ComparatorTableModel and other future extensions of this class. May become deprecated in favor of cleaner API.

Since:
0.9.4

suppressDependencies

protected boolean suppressDependencies
Since:
1.0.3
Constructor Detail

BSHTableModel

public BSHTableModel(int rowCount,
                     int columnCount)
Instantiates the model using initial row and column counts.

Method Detail

setValueAt

public void setValueAt(java.lang.Object value,
                       int row,
                       int column)
Sets a value at the given address. If the value is a string, not a formula, and a Format object is available for the given address, parsing the value is attempted using the Formatobject. If the parsing is successful, the object stored in the model itself is the result of the parsing. For example, if the format is an instance of SimpleDateFormat, and its pattern is set to "yyyy-MM-dd", then the value string "1977-9-6" would be parsed and stored as an instance of Date representing September 6, 1977.

Specified by:
setValueAt in interface javax.swing.table.TableModel
Overrides:
setValueAt in class javax.swing.table.DefaultTableModel
See Also:
getFormat(int, int)

formatValueAt

public java.lang.Object formatValueAt(java.lang.Object value,
                                      int column,
                                      int row)
Formats the given value using formatting rules for the given address. If no formatting rules are available for the given address or if it fails for the given value, the value itself is returned without any formatting applied.

See Also:
getFormat(int, int)

getValueAt

public java.lang.Object getValueAt(int row,
                                   int column)
Extends default behavior to always return row index for column 0. Column 0 is a special column that is used as a row header.

Specified by:
getValueAt in interface javax.swing.table.TableModel
Overrides:
getValueAt in class javax.swing.table.DefaultTableModel

getColumnName

public java.lang.String getColumnName(int column)
Extends default behavior to return null for column 0. Column 0 is a special column that is used as a row header.

Specified by:
getColumnName in interface javax.swing.table.TableModel
Overrides:
getColumnName in class javax.swing.table.DefaultTableModel

getColumnClass

public java.lang.Class getColumnClass(int column)
Extends default behavior to return a class object representing JTableHeader for column 0. Column 0 is a special column that is used as a row header.

Specified by:
getColumnClass in interface javax.swing.table.TableModel
Overrides:
getColumnClass in class javax.swing.table.AbstractTableModel

isCellEditable

public boolean isCellEditable(int row,
                              int column)
Extends default behavior to return false for column 0. Column 0 is a special column that is used as a row header.

Specified by:
isCellEditable in interface javax.swing.table.TableModel
Overrides:
isCellEditable in class javax.swing.table.DefaultTableModel

removeAppearance

public Appearance removeAppearance(int column,
                                   int row)

getAppearance

public Appearance getAppearance(int column,
                                int row,
                                boolean mutable)

setFormat

public void setFormat(java.text.Format format,
                      int column,
                      int row)
Associates the given format object with the given cell or column. If row is 0, the format is associated with the entire column.

See Also:
getFormat(int, int)

getFormat

public java.text.Format getFormat(int column,
                                  int row)
Returns the format object associated with the given cell or column. If row is 0, the returned format is for the entire column. Also if there is no format available for the given cell, the format for the column is then returned.

See Also:
setFormat(java.text.Format, int, int)

isValueCached

protected boolean isValueCached(int column,
                                int row)
Checks for cache state for a specific cell. As of 0.8, the model maintains an array of bit sets that maintain these states.

Since:
Bean Sheet 0.8
See Also:
setValueCached(boolean, int, int)

setValueCached

protected void setValueCached(boolean cached,
                              int column,
                              int row)
Sets cache state for a specific cell. As of 0.8, the model maintains an array of bit sets that maintain these states.

Since:
Bean Sheet 0.8
See Also:
isValueCached(int, int)

evalValueAt

public java.lang.Object evalValueAt(int column,
                                    int row)
Evaluates a value at the given cell address. If the object is a formula string (starts with =, then the formula is processed using internal preprocessing rules and then passed on to the Bean Shell interpreter (bsh).

The preprocessing rules encompass the following steps:

  1. setting cell-specific variables in Bean Shell context (col, row);
  2. setting cell dependencies;
  3. replacing cell address references.

See Also:
isValueCached(int, int), setValueCached(boolean, int, int), replaceReferences(java.lang.String, java.util.Set), bsh

replaceReferences

public java.lang.String replaceReferences(java.lang.String evalString,
                                          java.util.Set dependencies)
Replaces cell address references with Bean Shell-compatible statements. There are 3 kinds of cell references allowed:
TypeSyntaxExampleEquivalent
Explicit [<column name><row index>] [B10] model.evalValueAt(model.findColumn("B"), 10)
Relative [<column index delta><row index delta>] [-1+2] model.evalValueAt(col - 1, row + 2)
Range [<start column name><start row index>:<end column name><end row index>] [B2:C15] range("[B2:C15]")
Dependencies are not automatically created for range type references. Typically the user of a range will do that in the course of iterating.


editingCanceled

public void editingCanceled(javax.swing.event.ChangeEvent ev)
Specified by:
editingCanceled in interface javax.swing.event.CellEditorListener

editingStopped

public void editingStopped(javax.swing.event.ChangeEvent ev)
Specified by:
editingStopped in interface javax.swing.event.CellEditorListener

followDependencies

public void followDependencies(int column,
                               int row)
Calls recursive followDependencies(Point, Set).

See Also:
followDependencies(java.awt.Point, java.util.Set)

followDependencies

protected void followDependencies(java.awt.Point coord,
                                  java.util.Set processed)
Recursively runs according to cell's dependencies.

Since:
1.0.3

requestDependency

public void requestDependency(int causeCol,
                              int causeRow,
                              int effectCol,
                              int effectRow)
Requests a dependency from one cell to another. This method exposes API, primarily meant for ability to establish dependencies without the use of the standard [] cell address notation. This is especially useful when defining Bean Shell commands or processing logic within a spreadsheet, such as operations on ranges defined by their start and end points.


refreshCacheAndDependencies

protected void refreshCacheAndDependencies()
Recreates internal value cache and dependencies objects (cache and dependencies). This is useful when the model structure (dimensions) changes.

See Also:
cache, dependencies

refreshLastNonEmpty

protected void refreshLastNonEmpty()
Since:
0.9.2

getLastNonEmptyRow

public int getLastNonEmptyRow()
Since:
0.9.2

getLastNonEmptyColumn

public int getLastNonEmptyColumn()
Since:
0.9.2

fireTableStructureChanged

public void fireTableStructureChanged()
Overrides:
fireTableStructureChanged in class javax.swing.table.AbstractTableModel

fireTableChanged

public void fireTableChanged(javax.swing.event.TableModelEvent ev)
Overrides:
fireTableChanged in class javax.swing.table.AbstractTableModel

getFormats

public java.util.Map getFormats()
Returns internal format map.

See Also:
columnFormats, setFormats(java.util.Map)

setFormats

public void setFormats(java.util.Map formats)
Sets internal format map.

See Also:
columnFormats, getFormats()

getAppearanceMap

public java.util.Map getAppearanceMap()

setAppearanceMap

public void setAppearanceMap(java.util.Map appearanceMap)

sort

public void sort(int startRow,
                 int nRows,
                 int[] cols,
                 java.util.Comparator[] comps)
Sorts rows of data in the model in the specified columns spanning nRows rows starting with startRow. Custom comparators can be provided in an array. Provided comparators are matched against their corresponding columns using array indexes. If comparator array is shorter than the column index array, the rest of the columns are sorted in their natural order. Each element in the comparator array represents a comparator used for that particular column's sorting. A null comparator represents natural data order. It may be assumed that no null column values will be passed to the custom comparators for comparison. null values are handled entirely by BSHTableModelComparable.

Parameters:
startRow - starting row
nRows - number of rows
cols - column indexes
comps - custom comparators. Must not be null.
See Also:
BSHTableModelComparable