JClass LiveTable

PreviousNextIndex

3

Working with Table Data

Overview: Data Handling in JClass LiveTable  Getting Data into your Table

Using Stock Data Sources  Setting Stock Data Source Properties

Loading Data from an XML Source  Creating your own Data Sources  Dynamically Updating Data 


3.1 Overview: Data Handling in JClass LiveTable

JClass LiveTable is a Java component that creates a table-formatted view of a given set of data. Data can come from many different types of sources; different applications can have different data storage needs. Since applications can generally store data more efficiently than a component, it is more practical for JClass LiveTable to use an external data object rather than storing the data internally. An external data model organizes the data in a way that is more convenient for the application, rather than for the component.

Consequently, JClass LiveTable uses a Model-View-Controller (MVC) architecture for data handling. The data in the table cells is stored in an external data source rather than the JCTable object itself. Either you create the data source object, or the data source can be a database. To use the latter, you need to use one of the LiveTable data-binding Beans. For more information about these Beans, please see JClass LiveTable Beans and IDEs, in Chapter 9.

With LiveTable's MVC architecture, the data source object is the Model, which manages the underlying data being displayed and manipulated. The JCTable object acts as both the View (the object displaying the data to the user) and the Controller (the object that manipulates and modifies the data).

Because the JCTable object and the data source are separated, you are free to use whatever data storage mechanism you want; the JCTable object doesn't need to know anything about the mechanism itself. The MVC architecture also helps improve the performance of JClass LiveTable programs by removing the need to load all of the table's data into memory, then copy it to the JCTable object. The data source is able to copy only the data that is currently displayed by the JCTable object. An external data source can also manage large sets of data more efficiently than the JCTable object can.

3.1.1 How the Table and Data Source Communicate

Between the JCTable object and the data source lies an object that implements the DataViewModel and/or the SortableDataViewModel. The default implementation in the table is TableDataView. While most developers will never have to work with it directly, it's important to realize that the TableDataView monitors the data source for changes and notifies the JCTable object when they occur. Additionally, the TableDataView has a set of translation tables that allow it to re-map rows or columns from the data source to the table. This is how JClass LiveTable can support features like column sorting and row or column swapping, where the appearance of the table changes, without manipulating the data source itself.


3.2 Getting Data into your Table

To display data in a JClass LiveTable application or applet, you need to create a data source object. Any object that implements the TableDataModel interface can be a data source. This can either be one of the stock data sources included with LiveTable (see Section 3.3, Using Stock Data Sources) or one of your own data sources (see Section 3.6, Creating your own Data Sources).

The TableDataModel interface is as follows:

  public interface TableDataModel {
  public Object getTableDataItem(int row, int column);
  public int getNumRows();
  public int getNumColumns();
  public Object getTableRowLabel(int row);
  public Object getTableColumnLabel(int column);
  public void addTableDataListener(TableDataListener l);
  public void removeTableDataListener(TableDataListener l);
  }

The primary method in the TableDataModel interface is getTableDataItem(), which retrieves the value of a specified cell. For more information on the types of cell data objects that Table understands, see Displaying and Editing Cells, in Chapter 4. In short, you can have any type of object (usually one of Integer, Double, String, or Image) in a cell.

Table Size

The size of the table is also specified by the data source, using the getNumRows() and getNumColumns() methods.

Row and Column Labels

If you want to display row or column labels, their values are provided using the getTableRowLabel() and getTableColumnLabel() methods. These methods return the same types of objects as getTableDataItem(), but labels are never editable or traversable.

Data Format Detection

When using the JCInputStream stock data source, LiveTable automatically detects whether a data stream is in standard table or CSV format. So by default, JCInputStreamDataSource and JCFileDataSource attempt to determine the format of the data source. To remove this automatic detection (and the overhead it creates), set a preferred data format type.

Data Source Listeners

Any time the data inside the data source changes, it should notify all of its listeners. To add and remove listeners to and from the data source, use the methods addTableDataListener() and removeTableDataListener().

3.2.1 Making the Data Source Editable

If you want users to be able to edit the data, you must implement the EditableTableDataModel interface. EditableTableDataModel is derived from TableDataModel and adds one new method: setTableDataItem().

  public interface EditableTableDataModel extends TableDataModel {
  public boolean setTableDataItem(Object o, int row, int column);
  }

When the user edits a cell in the table, the cell editor validates the data (for more information about cell editing, see Displaying and Editing Cells, in Chapter 4), and passes the new data to the data source using the setTableDataItem() method. If the data source does not accept the value of the object (for example, if the value is invalid in some way), it will return false to indicate that the edit has been rejected. If the new value is valid, then setTableDataItem() will return true and the data source will store the value.

The setEditable() Method

You can use the setEditable() method, which is part of the CellStyleModel implementation, to turn editing on and off for specific cells and ranges of cells. setEditable() has no effect on labels, as they can never be edited. For setEditable(true) to have any effect, the data source must be editable.


3.3 Using Stock Data Sources

While it isn't hard to create a data source for a table, JClass LiveTable includes several stock data sources to save you the work of writing data sources for the most common data types. The following data sources are found in the com.klg.jclass.table.data package:

Data Source

Description

JCAppletDataSource

Reads in data from the DATA tag of an applet.

JCCachedDataSource

Caches previously read data from the data source.

JCEditableCachedDataSource

Allows users to edit cell values in tables with the above data source.

JCEditableFileDataSource

Allows users to edit cell values in tables with the above data source.

JCEditableVectorDataSource

Allows users to edit cell values in tables with the above data source.

JCFileDataSource

Creates an input data stream from a file.

JCInputStreamDataSource

Base class for any data source that relies on streamed input. This data source type can handle comma-separated value (CSV) data files.

JCResultSetDataSource

Simple read-only JDBC database source.

JCSpreadLabel

Contains convenience methods for creating spreadsheet labels.

JCTableModelDataSource

Enables users to display and edit Swing TableModel data objects in JClass LiveTable. Swing TableModel objects are typically used by the Swing JTable component.

JCURLDataSource

Uses URLs to create a data source object.

JCVectorDataSource

General purpose data source: extended by almost all stock data sources.

Most of the stock data sources extend the JCVectorDataSource class. Please see Appendix E, JClass LiveTable Inheritance Hierarchy, for a complete hierarchy diagram that outlines the relationship between the stock data source classes.

3.3.1 JCVectorDataSource: the Data Source Workhorse

A JCVectorDataSource simply stores all of its data in memory using vectors. The JCVectorDataSource class contains methods that allow you to set individual elements, or to set all of the data in the data source from a vector or an array of objects.

Since JCVectorDataSource implements TableDataModel, it can't be edited by the JCTable object. If you want users to be able to edit the cell values through the table, you should use JCEditableVectorDataSource. The JCEditableVectorDataSource class is a subclass of JCVectorDataSource that implements the EdtitableTableDataModel interface model.

3.3.2 Getting Data from an Input Stream

JClass LiveTable provides the JCInputStreamDataSource class to read data in through a standard java.io.InputStream, and since it is derived from JCVectorDataSource, it has all of the same capabilities as a JCVectorDataSource (see Section 3.4, Setting Stock Data Source Properties). JCInputStreamDataSource accepts both CSV and table format data files, and items read into the data source are stored as either String or double objects. The data format for a simple table would be similar to the following (the # symbol denotes the beginning of a comment):

  TABLE 2 4 NOLABEL # 2 rows, 4 columns
  1 2 3 4 # row 1
  1 2 3 4 # row 2

If you want to include labels, the data format would be:

  TABLE 3 4
   'Column 1' 'Column 2' 'Column 3' 'Column 4'
  'Row 1' 1 2 3 4
  'Row 2' 1 4 9 16
  'Row 3' 1 16 81 256

The JCInputStreamDataSource class has the following subclasses that provide convenient constructors to create an InputStream from various sources:

3.3.3 Getting Data from a Database

The JCResultSetDataSource uses a JDBC database connection and an SQL query to create a data source. The JCResultSetDataSource is a rudimentary implementation of a data-bound data source to demonstrate that JClass LiveTable can be used with database applications quite easily.

Note: The JCResultSetDataSource is not a data source that can be edited; that is, it will not write to the database.

JClass LiveTable also comes with data-binding Beans that allow you to bind your table to any JDBC data source. For information about the data binding Beans, please refer to Data Binding with IDEs, in Chapter 9.

3.3.4 Caching Data with JCCachedDataSource

While JCVectorDataSource stores its memory using vectors, the JCCachedDataSource class stores its data in a vector of vectors. JCCachedDataSource uses another TableDataModel class to contain table cell and label information ("in between" the table and the data source). It will reference the cache first to see if the required data exists; if it does not, the call passes through to the original TableDataModel class, and the value is taken. When this happens, the retrieved value is also stored in JCCachedDataSource's other TableDataModel class.

This method saves time by creating a second instance of previously retrieved data, outside of the actual data source. JCCachedDataSource should only be used when the TableDataModel's getTableItem, getTableRowLabel, and/or getTableColumnLabel are calculation-intensive or expensive to retrieve.

Use JCEditableCachedDataSource to bind to an editable data source and be able to edit the cell contents.

Note: A non-editable data source bound to JCEditableCachedDataSource will display an editor but reject all changes.

3.3.5 Using Swing TableModel Data Objects

The JCTableModelDataSource enables you to use any type of Swing TableModel data object in JClass LiveTable. JCTableModelDataSource is an editable data source.

JCTableModelDataSource interprets and reformats the TableModel data to the layout used by JClass LiveTable. This makes it easier to replace the Swing JTable component with JClass LiveTable because you do not have to reformat your data.

When you create a JCTableModelDataSource, you need to pass the constructor a valid Swing TableModel object.


3.4 Setting Stock Data Source Properties

The following properties are set using methods of the JCVectorDataSource class. Since the stock data sources are derived from the JCVectorDataSource class, you can set these properties from any of the stock data sources (though all of the properties may not be applicable to the specific data source).

Note: The JCVectorDataSource class contains properties that are not inherent to the TableDataModel interface. If you create your own data source, you will have to produce your own methods for such operations as adding and deleting rows and columns.

3.4.1 Working with Rows and Columns

Setting the Number of Rows/Columns

The setNumRows() and setNumColumns() methods specify the number of rows and columns in the data source (default is 5 columns and 10 rows). These values do not affect the internal CellValues Vector of the data source. The values of the NumRows and NumColumns properties are updated by the addRow(), addColumn(), deleteRows(), and deleteColumns() methods (see below).

Specifying Row and Column Labels

You can set row and column labels by calling:

Column and row labels can be set as an array of Strings, or as a vector. Each element of the labels' vector may be an instance of a String, Image, Component, or other object. To clear column or row labels, call the method with a null argument.

  String clabels[] = { "Name", "Address", "Phone" };
  ...
  JCVectorDataSource vds;
  vds.setColumnLabels(clabels);

To retrieve the values, use:

Adding Rows and Columns

You can insert new rows and columns into the data source using the addColumn() and addRow() methods. The addColumn() method inserts a new column into the data source, shifting any cell values to the right of the insertion. The addRow() method inserts a new row into the data source, shifting any cell values down.

The addColumn() and addRow() methods are identical:

   Object label,
   Vector values)
   Object label,
   Vector values)

In the previous methods,

When calling addRow() and addColumn(), note the following:

Deleting Rows and Columns

Use the deleteRows() and deleteColumns() methods to remove rows and columns from the data source. When you delete a column, remaining cell values shift to the left; when you delete a row, existing cell values shift up.

The deleteRows() and deleteColumns() methods are identical:

   int num_rows)
   int num_columns)

In the previous methods,

When calling deleteRows() and deleteColumns(), note the following:

Moving Rows and Columns

To move a range of rows or columns in the data source, use the moveRows() and moveColumns() methods. The moveRows() and moveColumns() methods take the following forms:

   int num_rows,
   int destination)
   int num_columns,
   int destination)

In the previous methods,

When calling moveRows() and moveColumns(), note the following:

3.4.2 Working with Other Properties

Setting Cell Values

To set the cell values in the data source, use the setCell() or setCells() methods. The setCells() method can be a matrix of Strings or a vector of vectors. To remove all values, call clearCells().

Adding and Removing TableDataListeners

The JCVectorDataSource class contains methods for adding and removing listeners to the data source: addTableDataListener() and removeTableDataListener(). These methods monitor the data source for changes. For more information, see Section 3.7, Dynamically Updating Data.


3.5 Loading Data from an XML Source

3.5.1 XML Primer

XML - eXtensible Markup Language - is a scaled-down version of SGML (Standard Generalized Markup Language), the standard for creating a document structure. XML was designed especially for Web documents, and allows designers to create customized tags ("extensible"), thereby enabling a flexible approach to create common information formats for sharing both the format and the data on the Internet, intranets, and so on.

XML is similar to HTML in that both contain markup tags to describe the contents of a page or file. But HTML describes the content of a Web page (mainly text and graphic images) only in terms of how it is to be displayed and interacted with. XML, however, describes the content in terms of what data is being described. This means that an XML file can be used in various ways. For instance, an XML file can be utilized as a convenient way to exchange data across heterogeneous systems. As another example, an XML file can be processed (for example, via XSLT [Extensible Stylesheet Language Transformations]) in order to be visually displayed to the user by transforming it into HTML.

Here are links to more information on XML.

3.5.2 Using XML in JClass

In order to work with XML in your programs, or even to compile our XML examples, you will need to have the JAR files jaxp.jar and crimson.jar1 in your CLASSPATH. These files are distributed with JClass LiveTable - you can find them in JCLASS_HOME/lib/.

JClass LiveTable can accept XML data formatted to the specifications outlined in com.klg.jclass.util.xml.JCTableXMLParser. This class takes in a stream of data and parses it under the assumption that it is in the defined XML format that JClass LiveTable uses. It then populates the specified table with the resulting data.

Examples of XML in JClass

For XML data source examples, see the XMLFileData and XMLTableModelData examples in JCLASS_HOME/examples/table/datasource. These both use the colors.xml file in JCLASS_HOME/examples/table/datasource/.

You can also specify your own data parsing format. There are now constructors in the JCInputStreamDataSource, JCFileDataSource, JCURLDataSource, and JCAppletDataSource classes that take an object that implements the com.klg.jclass.table.data.JCFileFormatParser interface.

Interpreter

The interpreter, which lets JClass LiveTable interpret the incoming data via the defined XML format, must be explicitly set by the user. The interpreter to use for JClass LiveTable is com.klg.jclass.table.data.JCXMLFormatParser.

Many constructors in the various data sources in JClass LiveTable take the JCFileFormatParser interface that this class (JCXMLFormatParser) implements.

Here are a few code examples that load XML data using this interpreter:

TableDataModel tdm = new JCFileDataSource(fileName,
    new JCXMLFormatParser());


TableDataModel tdm = new JCURLDataSource(codeBase, fileName,
    new JCXMLFormatParser());

Note: A user can create a custom data format and create a custom data interpreter by implementing JCFileFormatParser.

3.5.3 Example XML Files for JClass LiveTable

Here is an XML file that contains data formatted to the specifications detailed in com.klg.jclass.util.xml.JCTableXMLParser:

<?xml version="1.0"?>
<!DOCTYPE JCTableData SYSTEM "JCTableData.dtd">
<JCTableData>
  <Row>
    <Cell>1</Cell> <Cell>2</Cell> <Cell>3</Cell> <Cell>4</Cell>
  </Row>
  <Row>
    <Cell>1</Cell> <Cell>2</Cell> <Cell>3</Cell> <Cell>4</Cell>
  </Row>
</JCTableData>

Here is another example XML file that contains data formatted to the specifications detailed in com.klg.jclass.util.xml.JCTableXMLParser, this one with row and column labels:

<?xml version="1.0"?>
<!DOCTYPE JCTableData SYSTEM "JCTableData.dtd">
<JCTableData>
  <ColumnLabel>Column 1</ColumnLabel>
  <ColumnLabel>Column 2</ColumnLabel>
  <ColumnLabel>Column 3</ColumnLabel>
  <ColumnLabel>Column 4</ColumnLabel>
  <Row>
    <RowLabel>Row 1</RowLabel>
    <Cell>1</Cell> <Cell>2</Cell> <Cell>3</Cell> <Cell>4</Cell>
  </Row>
  <Row>
    <RowLabel>Row 2</RowLabel>
    <Cell>1</Cell> <Cell>4</Cell> <Cell>9</Cell> <Cell>16</Cell>
  </Row>
  <Row>
    <RowLabel>Row 3</RowLabel>
    <Cell>1</Cell> <Cell>16</Cell> <Cell>81</Cell> <Cell>256</Cell>
  </Row>
</JCTableData>

3.5.4 Tags

<ColumnLabel> and <RowLabel> tags are optional. Every <Row> tag can contain any number of <Cell> tags. These <Cell> tags define the value of one cell within the row.

3.5.5 Creating a Swing TableModel class

For details on how to use the above XML format to create a Swing TableModel class instead of a standard JClass LiveTable data source, please look at the com.klg.jclass.util.xml.JCXMLTableModel class. The user can pass an XML input stream to this object and use the resulting table model to populate a JClass LiveTable, a Swing JTable, a JClass Chart, or any other object that takes a Swing TableModel class.

Also, the XMLTableModelData example in JCLASS_HOME/examples/table/datasource shows this.


3.6 Creating your own Data Sources

If the stock data sources provided with JClass LiveTable do not meet your needs, you can easily create your own data source objects by implementing the TableDataModel interface, as in the following example from examples/table/datasource/StaticDataSource.java:

import com.klg.jclass.table.TableDataModel;
import com.klg.jclass.table.JCTableDataListener;

public class StaticDataSource implements TableDataModel {

protected String data[];

public StaticDataSource(String strings[]) {
  if(strings == null)
    data = new String[0];
  else
    data = strings;
}

public Object getTableDataItem(int row, int column) {
  if(column == 0)
    return data[row];
  else
    return null;
}

public int getNumRows() {
  return data.length;
}

public int getNumColumns() {
  return 1;
}

public Object getTableRowLabel(int row) {
  return Integer.toString(row);
}

public Object getTableColumnLabel(int column) {
  return "Some Data";
}

public void addTableDataListener(JCTableDataListener l) {
}

public void removeTableDataListener(JCTableDataListener l) {
}
}

The StaticDataSource class takes a one-dimensional array of Strings and turns it into a read-only data source. The constructors take the array of Strings; the getTableDataItem() method supplies the data as it is needed. Note that the addTableDataListener() and removeTableDataListener() methods have been left empty because this data source is not going to be changing dynamically, and thus does not need to keep track of its listeners. You can attach this data source to a table quite easily. To see a demonstration of this, run the StaticTest.java file, found in the examples/table/datasource directory.

To make the items in the table editable, you must implement the EditableTableDataModel interface, as in examples/table/datasource/StaticEditableDataSource.java:

import com.klg.jclass.table.EditableTableDataModel;
import com.klg.jclass.table.JCTableDataListener;

public class StaticEditableDataSource implements EditableTableDataModel {

protected String data[];

public StaticEditableDataSource(String strings[]) {
  if(strings == null)
    data = new String[0];
  else
    data = strings;
}

public Object getTableDataItem(int row, int column) {
  if(column == 0)
    return data[row];
  else
    return null;
}

public boolean setTableDataItem(Object o, int row, int column) {
  if(column == 0) {
    if (o instanceof String)
      data[row] = (String)o;
    else
      data[row] = o.toString();
  }

  return true;
}

public int getNumRows() {
  return data.length;
}

public int getNumColumns() {
  return 1;
}

public Object getTableRowLabel(int row) {
  return Integer.toString(row);
}

public Object getTableColumnLabel(int column) {
  return "Some Data";
}

public void addTableDataListener(JCTableDataListener l) {
}

public void removeTableDataListener(JCTableDataListener l) {
}
}

The StaticEditableDataSource class could have been a subclass of StaticDataSource, adding only the setTableDataItem() method, but in this example it was shown as a standalone class to make sure everything is as clear as possible. Note that the object that is passed back to the data source in setTableDataItem() is not a String.

To see a demonstration of the StaticEditableDataSource class, run the StaticEditableTest.java file, found in the examples/table/datasource directory.


3.7 Dynamically Updating Data

Sometimes the data in the data source changes all by itself - for example, you may have a table displaying stock prices with data arriving in real-time over a network socket. As new prices arrive, your users would like the table to update the values of the appropriate cells.

To notify the table that the data has changed, send a JCTableDataEvent to all of the JCTableDataListener objects that have registered themselves with the data source.

The following is a simple example that creates a background thread that automatically updates cell values. It can be found in the file examples/table/datasource/DynamicDataSource.java:

import java.util.Enumeration;
import java.util.Random;
import com.klg.jclass.table.TableDataModel;
import com.klg.jclass.table.JCTableDataEvent;
import com.klg.jclass.table.JCTableDataListener;
import com.klg.jclass.util.JCListenerList;

public class DynamicDataSource implements TableDataModel, Runnable {

protected int data[] = {
  1, 2, 3, 4, 5, 6, 7, 8, 9,
};

protected JCListenerList listeners;
protected Thread kicker;

public DynamicDataSource() {
  kicker = new Thread(this);
  kicker.start();
}

public Object getTableDataItem(int row, int column) {
  if (column == 0) {
    return new Integer(data[row]);
  }
  return null;
}

public int getNumRows() {
  return data.length;
}

public int getNumColumns() {
  return 1;
}

public Object getTableRowLabel(int row) {
  return Integer.toString(row);
}

public Object getTableColumnLabel(int column) {
  return "Some Data";
}

public void addTableDataListener(JCTableDataListener l) {
  listeners = JCListenerList.add(listeners,l);
}

public void removeTableDataListener(JCTableDataListener l) {
  listeners = JCListenerList.remove(listeners,l);
}

public void run() {
  Random random = new Random();
  Enumeration e;
  JCTableDataListener l;
  JCTableDataEvent event;
  int i;

  for(;;) {
    i = random.nextInt() % data.length;
    if (i < 0) {
      i = -i;
    }
    data[i] += (int)(random.nextGaussian()*10);
    event = new JCTableDataEvent(this,i,0,0,0,
      JCTableDataEvent.CHANGE_VALUE);

    for(e = JCListenerList.elements(listeners); e.hasMoreElements(); ) {
      l = (JCTableDataListener)e.nextElement();
      l.dataChanged(event);
    }

    try {
      Thread.sleep(100);
    }
    catch(Exception ex) {
    }
  }
}
}

The DynamicDataSource class sends CHANGE_VALUE messages to all of its listeners whenever a value changes. When the JCTable object receives this message it retrieves the new value from the data source and repaints the appropriate cell. There are several other update commands available on the JCTableDataEvent class:

  • CHANGE_VALUE
  • NUM_ROWS
  • CHANGE_ROW
  • NUM_COLUMNS
  • CHANGE_COLUMN
  • ADD_COLUMN
  • CHANGE_ROW_LABEL
  • REMOVE_COLUMN
  • CHANGE_COLUMN_LABEL
  • MOVE_ROW
  • ADD_ROW
  • MOVE_COLUMN
  • REMOVE_ROW
  • RESET
  • All of the CHANGE_ messages cause the Table to reload the specified data and repaint the intersection of the data that has been changed and the data that is being shown on screen.

    The file examples/table/datasource/DynamicTest.java demonstrates the simple technique used in DynamicDataSource.java.

    Easy Listener Management

    If you do not want to have to manage the listeners, JClass LiveTable includes a class called AbstractDataSource. AbstractDataSource is an object provided by JCTable that implements TableDataModel, and has methods for adding and removing JCTableDataListeners. In addition, it contains several convenience methods for firing events, such as fireValueChanged() and fireRowLabelChanged() method.

    As an example, the DynamicDataSource.java program could be implemented again to use the AbstractDataSource as follows:

    import java.util.Enumeration;
    import java.util.Random;
    import com.klg.jclass.table.data.AbstractDataSource;
    import com.klg.jclass.table.JCTableDataEvent;
    import com.klg.jclass.table.JCTableDataListener;
    import com.klg.jclass.util.JCListenerList;

    public class DynamicDataSource2 extends AbstractDataSource
    implements Runnable {

    protected int data[] = {
      1, 2, 3, 4, 5, 6, 7, 8, 9,
    };

    protected Thread kicker;

    public DynamicDataSource2() {
      kicker = new Thread(this);
      kicker.start();
    }
    public Object getTableDataItem(int row, int column) {
      if(column == 0)
        return new Integer(data[row]);
      else
        return null;
    }

    public int getNumRows() {
      return data.length;
    }

    public int getNumColumns() {
      return 1;
    }

    public Object getTableRowLabel(int row) {
      return Integer.toString(row);
    }

    public Object getTableColumnLabel(int column) {
      return "Some Data";
    }

    public void run() {
      Random random = new Random();
      Enumeration e;
      JCTableDataListener l;
      JCTableDataEvent event;
      int i;

      for(;;) {
        i = random.nextInt() % data.length;
        if (i < 0) {
          i = -i;
        }

        data[i] += (int)(random.nextGaussian()*10);

        event = new JCTableDataEvent(this,i,0,0,0,
          JCTableDataEvent.CHANGE_VALUE);

        fireTableDataEvent(event);

        try {
          Thread.sleep(100);
        }
        catch(Exception ex) {
        }
      }
    }
    }

    Running examples/table/datasource/DynamicTest2.java demonstrates that the same results can be achieved more easily by using a subclass of AbstractDataSource.

    3.7.1 Adding and Removing Columns and Rows

    ADD_ROW, REMOVE_ROW, ADD_COLUMN, and REMOVE_COLUMN notify the table that a row or column has been added or removed so that the table can update its internal list of cell attributes. For example, if all your rows are different colors, and you delete a row, the remaining rows will still have the correct colors if you send a REMOVE_ROW message to the JCTable. Some of the event parameters may be ignored for row or column operations. For example, when you do an operation on an entire row or column, if you create an ADD_ROW event, the column parameter is ignored by the table. With the exception of the MOVE_ events, all of the events ignore the num_affected and destination parameters of the JCTableDataEvent.

    The MOVE_ROW and MOVE_COLUMN commands are the only commands that make use of the num_affected and destination parameters in the JCTableDataEvent. When you have a MOVE_ event, you can move multiple rows/columns (the num_affected parameter) and you must specify to which row/column you are moving (destination).

    The RESET message causes the JCTable object to re-initialize itself by re-reading the number of rows, number of columns and all the data from the data source. The table's visual attributes, such as fonts and colors, are not affected.

    Note: When a user edits a cell in the table and the value is put back into the data source via setTableDataItem(), the table will automatically repaint the cell with a new value.

    1You may substitute for crimson.jar any parser that is compliant with Sun's JAXP 1.1 specification. See Sun's JAXP documentation for more information:


    PreviousNextIndex