t e m p o r a l 
 d o o r w a y 

Showing Only Rows Containing A Specific String

 

Introduction

One of the most fundamental operations of a database program is to show a limited set of the records available, based on some criteria. True, one can use a query against a database to select only those rows of interest, but the method of using the filterRow listener can be faster and more flexible.

Context

For the purpose of this project, create a frame and a datamodule. On the frame place a JBCL data aware grid (borland.jbcl.control.GridControl). In the data module, create a table, a view and, if you need it, a file. The view works with the table via the storageDataSet property, which is set to the table. The grid should have its dataSet property attached to the View. Along with the grid, the frame should also have a text edit box of some sort (referred to as filterEdit in the example below) such as a com.sun.java.swing.JTextField.

The filterRow Event Handler

Next, click on the view and click on the Event tab of the inspector. Double-click on the filterRow property and add the following code as shown in the event handler:

void view_filterRow(ReadRow row, RowFilterResponse response) throws DataSetException
{
    try
    {
      String locateText = filterEdit.getText();

      if (locateText.length() == 0)
      {
         response.add();
         return;
      };

      String field = row.getString(fieldToFilter);
      FastStringBuffer currentContent = new FastStringBuffer(field);
      FastStringBuffer locateTextBuffer = new FastStringBuffer(locateText);

      int locationOfLocateTextInCurrentContent =
         CurrentContent.IndexOfSubString(locateTextBuffer,1);

      if (locationOfLocateTextInCurrentContent > -1)
      {
         response.add();
      }
      else
      {
         response.ignore();
      };
    }
    catch (NullPointerException nullPointer)
    {
    };
}

The only special variable in this is fieldToFilter, which is the name of the field to which the filter should be applied. This could be set statically or could be the result of a selection from a menu or check box by the user.

Some Potential Confusion

Because my application had a table connected to a view with the view displayed in the data aware controls, I initially believed I should set the filterRow for the table to contain this code, and that this would be reflected in the view. This did not work, and it was a mystery for a while, especially when I debugged the filterRow and it seemed to be running properly. But I eventually realized that the view did not see the filtering action unless the filterRow was its filterRow. Note that this is actually very convenient, since it means that there can be multiple views of the same table which see differently filtered sets of data.

Triggering The Filter

view.refilter() will cause the filterRow to be executed for every row in the view.

How This Works

Basically, the handler gets every row in the data set, one at a time, when the refilter() is called. The response parameter offers two methods - add() which says "yes, include the row"; you can also, as I have, call ignore() (which says "don't include the row"), though the documentation states that is unnecessary, since ignoring the row is the default.

Copyright © 2004 by Mark Cashman (unless otherwise indicated), All Rights Reserved