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.
|
|