Fields Summary |
---|
protected TableModel | tableModelThe inner table model we are decorating |
private TableModelListener | tableModelListenerThis listener is used to register this class as a listener to
the decorated table model for update events |
private ArrayList | rowToModelIndexthese keeps reference to the decorated table model for data
only rows that match the search criteria are linked |
private RAMDirectory | directoryIn memory lucene index |
private Analyzer | analyzerCached lucene analyzer |
private static final String | ROW_NUMBERLinks between this table model and the decorated table model
are maintained through links based on row number. This is a
key constant to denote "row number" for indexing |
private String | searchStringCache the current search String. Also used internally to
key whether there is an active search running or not. i.e. if
searchString is null, there is no active search. |
Methods Summary |
---|
private void | clearSearchingState()Clear the currently active search
Resets the complete dataset of the decorated
table model.
searchString = null;
rowToModelIndex.clear();
for (int t=0; t<tableModel.getRowCount(); t++){
rowToModelIndex.add(new Integer(t));
}
|
public org.apache.lucene.analysis.Analyzer | getAnalyzer()
return analyzer;
|
public java.lang.Class | getColumnClass(int column)
return tableModel.getColumnClass(column);
|
public int | getColumnCount()
return (tableModel == null) ? 0 : tableModel.getColumnCount();
|
public java.lang.String | getColumnName(int column)
return tableModel.getColumnName(column);
|
private int | getModelRow(int row)
return ((Integer) rowToModelIndex.get(row)).intValue();
|
public int | getRowCount()
return (tableModel == null) ? 0 : rowToModelIndex.size();
|
public javax.swing.table.TableModel | getTableModel()
return tableModel;
|
public java.lang.Object | getValueAt(int row, int column)
return tableModel.getValueAt(getModelRow(row), column);
|
public boolean | isCellEditable(int row, int column)
return tableModel.isCellEditable(getModelRow(row), column);
|
private boolean | isSearching()
return searchString != null;
|
private void | reindex()Reset the search results and links to the decorated (inner) table
model from this table model.
try {
// recreate the RAMDirectory
directory = new RAMDirectory();
IndexWriter writer = new IndexWriter(directory, analyzer, true);
// iterate through all rows
for (int row=0; row < tableModel.getRowCount(); row++){
//for each row make a new document
Document document = new Document();
//add the row number of this row in the decorated table model
//this will allow us to retrive the results later
//and map this table model's row to a row in the decorated
//table model
document.add(new Field(ROW_NUMBER, "" + row, true, true, true));
//iterate through all columns
//index the value keyed by the column name
//NOTE: there could be a problem with using column names with spaces
for (int column=0; column < tableModel.getColumnCount(); column++){
String columnName = tableModel.getColumnName(column);
String columnValue = String.valueOf(tableModel.getValueAt(row, column)).toLowerCase();
document.add(new Field(columnName, columnValue, true, true, true));
}
writer.addDocument(document);
}
writer.optimize();
writer.close();
} catch (Exception e){
e.printStackTrace();
}
|
private void | resetSearchResults(org.apache.lucene.search.Hits hits)
try {
//clear our index mapping this table model rows to
//the decorated inner table model
rowToModelIndex.clear();
//iterate through the hits
//get the row number stored at the index
//that number is the row number of the decorated
//tabble model row that we are mapping to
for (int t=0; t<hits.length(); t++){
Document document = hits.doc(t);
Field field = document.getField(ROW_NUMBER);
rowToModelIndex.add(new Integer(field.stringValue()));
}
} catch (Exception e){
e.printStackTrace();
}
|
public void | search(java.lang.String searchString)Run a new search.
//if search string is null or empty, clear the search == search all
if (searchString == null || searchString.equals("")){
clearSearchingState();
fireTableDataChanged();
return;
}
try {
//cache search String
this.searchString = searchString;
//make a new index searcher with the in memory (RAM) index.
IndexSearcher is = new IndexSearcher(directory);
//make an array of fields - one for each column
String[] fields = new String[tableModel.getColumnCount()];
for (int t=0; t<tableModel.getColumnCount(); t++){
fields[t]=tableModel.getColumnName(t);
}
//build a query based on the fields, searchString and cached analyzer
//NOTE: This is an area for improvement since the MultiFieldQueryParser
// has some weirdness.
Query query = MultiFieldQueryParser.parse(searchString, fields, analyzer);
//run the search
Hits hits = is.search(query);
//reset this table model with the new results
resetSearchResults(hits);
} catch (Exception e){
e.printStackTrace();
}
//notify all listeners that the table has been changed
fireTableStructureChanged();
|
public void | setAnalyzer(org.apache.lucene.analysis.Analyzer analyzer)
this.analyzer = analyzer;
//reindex from the model with the new analyzer
reindex();
//rerun the search if there is an active search
if (isSearching()){
search(searchString);
}
|
public void | setTableModel(javax.swing.table.TableModel tableModel)Set the table model used by this table model
//remove listeners if there...
if (this.tableModel != null) {
this.tableModel.removeTableModelListener(tableModelListener);
}
this.tableModel = tableModel;
if (this.tableModel != null) {
this.tableModel.addTableModelListener(tableModelListener);
}
//recalculate the links between this table model and
//the inner table model since the decorated model just changed
reindex();
// let all listeners know the table has changed
fireTableStructureChanged();
|
public void | setValueAt(java.lang.Object aValue, int row, int column)
tableModel.setValueAt(aValue, getModelRow(row), column);
|