Author: ehatcher
Date: Tue Mar 8 17:52:13 2005
New Revision: 156591
URL: http://svn.apache.org/viewcvs?view=rev&rev=156591
Log:
Contribution of slick Swing models to enable on-the-fly searching of
tables and lists. Created by Jonathan Simon.
Added:
lucene/java/trunk/contrib/swing/
lucene/java/trunk/contrib/swing/build.xml
lucene/java/trunk/contrib/swing/docs/
lucene/java/trunk/contrib/swing/docs/index.html
lucene/java/trunk/contrib/swing/src/
lucene/java/trunk/contrib/swing/src/java/
lucene/java/trunk/contrib/swing/src/java/org/
lucene/java/trunk/contrib/swing/src/java/org/apache/
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/ListSearcher.java
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/TableSearcher.java
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/package.html
lucene/java/trunk/contrib/swing/src/java/overview.html
lucene/java/trunk/contrib/swing/src/test/
lucene/java/trunk/contrib/swing/src/test/org/
lucene/java/trunk/contrib/swing/src/test/org/apache/
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseListModel.java
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseTableModel.java
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/DataStore.java
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/ListSearcherSimulator.java
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/RestaurantInfo.java
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TableSearcherSimulator.java
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestBasicList.java
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestBasicTable.java
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestSearchingList.java
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestSearchingTable.java
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestUpdatingList.java
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestUpdatingTable.java
Added: lucene/java/trunk/contrib/swing/build.xml
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/build.xml?view=auto&rev=156591
==============================================================================
--- lucene/java/trunk/contrib/swing/build.xml (added)
+++ lucene/java/trunk/contrib/swing/build.xml Tue Mar 8 17:52:13 2005
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+
+<project name="swing" default="default">
+
+ <description>
+ Swing Models
+ </description>
+
+ <import file="../common.xml"/>
+
+ <target name="list-demo" depends="compile">
+ <java classname="org.apache.lucene.swing.models.ListSearcherSimulator"
+ fork="yes" spawn="yes"
+ classpathref="test.classpath"
+ />
+ </target>
+
+ <target name="table-demo" depends="compile">
+ <java classname="org.apache.lucene.swing.models.TableSearcherSimulator"
+ fork="yes" spawn="yes"
+ classpathref="test.classpath"
+ />
+ </target>
+</project>
Added: lucene/java/trunk/contrib/swing/docs/index.html
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/docs/index.html?view=auto&rev=156591
==============================================================================
--- lucene/java/trunk/contrib/swing/docs/index.html (added)
+++ lucene/java/trunk/contrib/swing/docs/index.html Tue Mar 8 17:52:13 2005
@@ -0,0 +1,97 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Untitled Document</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+<body>
+<h1><strong> Lucene Powered Swing Data Models </strong></h1>
+<p><strong>by Jonathan Simon </strong></p>
+<p> </p>
+<p><strong>What it is.</strong></p>
+<p>This package contains classes that help you easily integrate Lucene based
searching
+ into your Swing components. Currently there are classes to index and search
+ JTables and JLists. This is done using model decorators rather than custom
models
+ to make it easier to search current models as well as new ones. </p>
+<p><em>These models do not actually contain any data</em>. Rather, the
ListModel
+ decorator (ListSearcher) and the TableModel decorator (TableSearcher) take a
+ model in the constructor and delegate all calls to it (after a little
alteration,
+ but we'll get to that). That said, these are not full fledged models
themselves.
+ You still have to have another model to decorate with the searching models.
+ If you are adding searching to a pre-existing model, you can use your
pre-existing
+ model directly. Otherwise, you can implement a model from scratch or use a
pre-existing
+ one to get started. </p>
+<p><strong>What it isn't. </strong></p>
+<p>A complete component: These are just models. They are not complete
components
+ with search fields and buttons laid out like a searchable interface. You
still
+ have to build that since the UI changes drastically between applciations.</p>
+<p>A complete model: There are just model decorators. You can't just set the
model
+ of a JList or JTable to one of these models, and you can't add data directly
+ to these models. </p>
+<p>A front end for a lucene index: In other words, you can't use these classes
+ to point a JTable directly to a Lucene index. Although that's interesting in
+ its own right, this is not that. </p>
+<p><strong>Usage: </strong></p>
+<p>Coding to both models nearly identical. They both take the model to
decorate
+ at construction time. Here is the code from the demo to decorate a JTable
model
+ with the TableSearcher and set it as the table model. </p>
+<pre><code>//make a new JTable
+JTable table = new JTable();
+//make my base model, the model with the data
+BaseTableModel tableModel = new BaseTableModel(DataStore.getRestaurants());
+//decorate the tableModel with the TableSearcher
+TableSearcher searchTableModel = new TableSearcher(tableModel);
+//set the TableModel in the table to the TableSearcher
+table.setModel(searchTableModel);
+</code></pre>
+<p>Initially, you won't notice a difference. This is because there is no
active
+ search which displays all data from the underlying model. You search by
calling
+ the <code>search</code>() method passing a search string. This filters the
data
+ set down without changing the underlying data model -- one of the main
reasons
+ for decorating in the first place. Any valid Lucene search string should
work
+ (see notes for more info on this). You'll probaby have some code somewhere
like
+ this in your app to connect a text field and search button to the model. </p>
+<pre><code>//create components
+final JTextField searchField = new JTextField();
+JButton searchButton = new JButton("Go");
+
+//make an action listener
+ActionListener searchListener = new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ searchTableModel.search(searchField.getText().trim().toLowerCase());
+ }
+};
+
+//register listeners
+searchButton.addActionListener(searchListener);
+searchField.addActionListener(searchListener);</code></pre>
+<p>You also might want to have a clear search button, working the same way.
But
+ to keep things simple, if you search will a <code>null </code>String or an
empty
+ String, the search clears and you will once again see all of your data. </p>
+<p><strong>Demo notes:</strong> </p>
+<p>The list demo does real time searching. In other words, as you type,
searches
+ run and the result set updates. The table demo has a search button, and only
+ searches when the button is clicked. They both work, I just implemented them
+ this way to show the different UI metaphors and that they both work.</p>
+<p><strong>Implementation notes: </strong></p>
+<p>This code started as a proof of concept so it's not a <em>fully</em>
featured
+ model. Don't get me wrong, it <em>fully</em> works, but it could use some
improvement
+ that it will hopefully get over time. I just wanted to get it out there and
+ get people using it. I'm also trying to keep everything as simple as
possible.
+ Here are some of the issues. </p>
+<ul>
+ <li>You can't change the model after the Searcher is constructed. </li>
+ <li>The search model decorators <em>do</em> update when the decorated model
+ is updated, but not in a very efficient way. The whole search model is
reindexed
+ when anything changes. This is a definite scaling issue. </li>
+ <li>The indexing and searching logic needs to be generally more configurable
+ to allow custom tailoring of searched and indexing. </li>
+ <li>The TableSearcher uses column names to index column values. This could
be
+ an issue with multiple word column names. </li>
+ <li>The ListSearcher uses MultiFieldQueryParser even though its not really
indexing
+ multiple fields. </li>
+</ul>
+<p> </p>
+<p> </p>
+</body>
+</html>
Added:
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/ListSearcher.java
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/ListSearcher.java?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/ListSearcher.java
(added)
+++
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/ListSearcher.java
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,279 @@
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.WhitespaceAnalyzer;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Hits;
+import org.apache.lucene.queryParser.MultiFieldQueryParser;
+
+import javax.swing.*;
+import javax.swing.event.ListDataListener;
+import javax.swing.event.ListDataEvent;
+import java.util.ArrayList;
+
+/**
+ * See table searcher explanation.
+ *
+ * @author Jonathan Simon - [EMAIL PROTECTED]
+ */
+public class ListSearcher extends AbstractListModel {
+ private ListModel listModel;
+
+ /**
+ * The reference links between the decorated ListModel
+ * and this list model based on search criteria
+ */
+ private ArrayList rowToModelIndex = new ArrayList();
+
+ /**
+ * In memory lucene index
+ */
+ private RAMDirectory directory;
+
+ /**
+ * Cached lucene analyzer
+ */
+ private Analyzer analyzer;
+
+ /**
+ * Links between this list model and the decorated list model
+ * are maintained through links based on row number. This is a
+ * key constant to denote "row number" for indexing
+ */
+ private static final String ROW_NUMBER = "ROW_NUMBER";
+
+ /**
+ * Since we only have one field, unlike lists with multiple
+ * fields -- we are just using a constant to denote field name.
+ * This is most likely unnecessary and should be removed at
+ * a later date
+ */
+ private static final String FIELD_NAME = "FIELD_NAME";
+
+ /**
+ * Cache 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.
+ */
+ private String searchString = null;
+ private ListDataListener listModelListener;
+
+ public ListSearcher(ListModel newModel) {
+ analyzer = new WhitespaceAnalyzer();
+ setListModel(newModel);
+ listModelListener = new ListModelHandler();
+ newModel.addListDataListener(listModelListener);
+ clearSearchingState();
+ }
+
+ private void setListModel(ListModel newModel) {
+ //remove listeners if there...
+ if (newModel != null) {
+ newModel.removeListDataListener(listModelListener);
+ }
+
+ listModel = newModel;
+ if (listModel != null) {
+ listModel.addListDataListener(listModelListener);
+ }
+
+ //recalculate the links between this list model and
+ //the inner list model since the decorated model just changed
+ reindex();
+
+ // let all listeners know the list has changed
+ fireContentsChanged(this, 0, getSize());
+ }
+
+ private void reindex() {
+ try {
+ // recreate the RAMDirectory
+ directory = new RAMDirectory();
+ IndexWriter writer = new IndexWriter(directory, analyzer, true);
+
+ // iterate through all rows
+ for (int row=0; row < listModel.getSize(); row++){
+
+ //for each row make a new document
+ Document document = new Document();
+ //add the row number of this row in the decorated list model
+ //this will allow us to retrive the results later
+ //and map this list model's row to a row in the decorated
+ //list model
+ document.add(new Field(ROW_NUMBER, "" + row, true, true,
true));
+ //add the string representation of the row to the index
+ document.add(new Field(FIELD_NAME,
String.valueOf(listModel.getElementAt(row)).toLowerCase(), true, true, true));
+ writer.addDocument(document);
+ }
+ writer.optimize();
+ writer.close();
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Run a new search.
+ *
+ * @param searchString Any valid lucene search string
+ */
+ public void search(String searchString){
+
+ //if search string is null or empty, clear the search == search all
+ if (searchString == null || searchString.equals("")){
+ clearSearchingState();
+ fireContentsChanged(this, 0, getSize());
+ 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 = {FIELD_NAME};
+
+ //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 list model with the new results
+ resetSearchResults(hits);
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+
+ //notify all listeners that the list has been changed
+ fireContentsChanged(this, 0, getSize());
+ }
+
+ /**
+ *
+ * @param hits The new result set to set this list to.
+ */
+ private void resetSearchResults(Hits hits) {
+ try {
+ //clear our index mapping this list model rows to
+ //the decorated inner list 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();
+ }
+ }
+
+ /**
+ * @return The current lucene analyzer
+ */
+ public Analyzer getAnalyzer() {
+ return analyzer;
+ }
+
+ /**
+ * @param analyzer The new analyzer to use
+ */
+ public void setAnalyzer(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);
+ }
+ }
+
+ private boolean isSearching() {
+ return searchString != null;
+ }
+
+ private void clearSearchingState() {
+ searchString = null;
+ rowToModelIndex.clear();
+ for (int t=0; t<listModel.getSize(); t++){
+ rowToModelIndex.add(new Integer(t));
+ }
+ }
+
+ private int getModelRow(int row){
+ return ((Integer) rowToModelIndex.get(row)).intValue();
+ }
+
+ public int getSize() {
+ return (listModel == null) ? 0 : rowToModelIndex.size();
+ }
+
+ public Object getElementAt(int index) {
+ return listModel.getElementAt(getModelRow(index));
+ }
+
+
+ class ListModelHandler implements ListDataListener {
+
+ public void contentsChanged(ListDataEvent e) {
+ somethingChanged();
+ }
+
+ public void intervalAdded(ListDataEvent e) {
+ somethingChanged();
+ }
+
+ public void intervalRemoved(ListDataEvent e) {
+ somethingChanged();
+ }
+
+ private void somethingChanged(){
+ // If we're not searching, just pass the event along.
+ if (!isSearching()) {
+ clearSearchingState();
+ reindex();
+ fireContentsChanged(ListSearcher.this, 0, getSize());
+ return;
+ }
+
+ // Something has happened to the data that may have invalidated
the search.
+ reindex();
+ search(searchString);
+ fireContentsChanged(ListSearcher.this, 0, getSize());
+ return;
+ }
+
+ }
+
+
+}
Added:
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/TableSearcher.java
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/TableSearcher.java?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/TableSearcher.java
(added)
+++
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/TableSearcher.java
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,354 @@
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.analysis.WhitespaceAnalyzer;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Hits;
+import org.apache.lucene.queryParser.MultiFieldQueryParser;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.util.List;
+
+import javax.swing.*;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.*;
+
+
+/**
+ * This is a TableModel that encapsulates Lucene
+ * search logic within a TableModel implementation.
+ * It is implemented as a TableModel decorator,
+ * similar to the TableSorter demo from Sun that decorates
+ * a TableModel and provides sorting functionality. The benefit
+ * of this architecture is that you can decorate any TableModel
+ * implementation with this searching table model -- making it
+ * easy to add searching functionaliy to existing JTables -- or
+ * making new search capable table lucene.
+ *
+ * This decorator works by holding a reference to a decorated ot inner
+ * TableModel. All data is stored within that table model, not this
+ * table model. Rather, this table model simply manages links to
+ * data in the inner table model according to the search. All methods on
+ * TableSearcher forward to the inner table model with subtle filtering
+ * or alteration according to the search criteria.
+ *
+ * Using the table model:
+ *
+ * Pass the TableModel you want to decorate in at the constructor. When
+ * the TableModel initializes, it displays all search results. Call
+ * the search methid with any vaid Lucene search String and the data
+ * will be filtered by the search string. Users can always clear the search
+ * at any time by searching with an empty string. Additionally, you can
+ * add a button calling the clearSearch() method.
+ *
+ * @author Jonathan Simon - [EMAIL PROTECTED]
+ */
+public class TableSearcher extends AbstractTableModel {
+
+ /**
+ * The inner table model we are decorating
+ */
+ protected TableModel tableModel;
+
+ /**
+ * This listener is used to register this class as a listener to
+ * the decorated table model for update events
+ */
+ private TableModelListener tableModelListener;
+
+ /**
+ * these keeps reference to the decorated table model for data
+ * only rows that match the search criteria are linked
+ */
+ private ArrayList rowToModelIndex = new ArrayList();
+
+
+ //Lucene stuff.
+
+ /**
+ * In memory lucene index
+ */
+ private RAMDirectory directory;
+
+ /**
+ * Cached lucene analyzer
+ */
+ private Analyzer analyzer;
+
+ /**
+ * Links 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 static final String ROW_NUMBER = "ROW_NUMBER";
+
+ /**
+ * Cache 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.
+ */
+ private String searchString = null;
+
+ /**
+ * @param tableModel The table model to decorate
+ */
+ public TableSearcher(TableModel tableModel) {
+ analyzer = new WhitespaceAnalyzer();
+ tableModelListener = new TableModelHandler();
+ setTableModel(tableModel);
+ tableModel.addTableModelListener(tableModelListener);
+ clearSearchingState();
+ }
+
+ /**
+ *
+ * @return The inner table model this table model is decorating
+ */
+ public TableModel getTableModel() {
+ return tableModel;
+ }
+
+ /**
+ * Set the table model used by this table model
+ * @param tableModel The new table model to decorate
+ */
+ public void setTableModel(TableModel tableModel) {
+
+ //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();
+ }
+
+
+ /**
+ * Reset the search results and links to the decorated (inner) table
+ * model from this table model.
+ */
+ private void reindex() {
+ 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();
+ }
+ }
+
+ /**
+ * @return The current lucene analyzer
+ */
+ public Analyzer getAnalyzer() {
+ return analyzer;
+ }
+
+ /**
+ * @param analyzer The new analyzer to use
+ */
+ public void setAnalyzer(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);
+ }
+ }
+
+ /**
+ * Run a new search.
+ *
+ * @param searchString Any valid lucene search string
+ */
+ public void search(String searchString){
+
+ //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();
+ }
+
+ /**
+ *
+ * @param hits The new result set to set this table to.
+ */
+ private void resetSearchResults(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();
+ }
+ }
+
+ private int getModelRow(int row){
+ return ((Integer) rowToModelIndex.get(row)).intValue();
+ }
+
+ /**
+ * Clear the currently active search
+ * Resets the complete dataset of the decorated
+ * table model.
+ */
+ private void clearSearchingState(){
+ searchString = null;
+ rowToModelIndex.clear();
+ for (int t=0; t<tableModel.getRowCount(); t++){
+ rowToModelIndex.add(new Integer(t));
+ }
+ }
+
+ // TableModel interface methods
+ public int getRowCount() {
+ return (tableModel == null) ? 0 : rowToModelIndex.size();
+ }
+
+ public int getColumnCount() {
+ return (tableModel == null) ? 0 : tableModel.getColumnCount();
+ }
+
+ public String getColumnName(int column) {
+ return tableModel.getColumnName(column);
+ }
+
+ public Class getColumnClass(int column) {
+ return tableModel.getColumnClass(column);
+ }
+
+ public boolean isCellEditable(int row, int column) {
+ return tableModel.isCellEditable(getModelRow(row), column);
+ }
+
+ public Object getValueAt(int row, int column) {
+ return tableModel.getValueAt(getModelRow(row), column);
+ }
+
+ public void setValueAt(Object aValue, int row, int column) {
+ tableModel.setValueAt(aValue, getModelRow(row), column);
+ }
+
+ private boolean isSearching() {
+ return searchString != null;
+ }
+
+ private class TableModelHandler implements TableModelListener {
+ public void tableChanged(TableModelEvent e) {
+ // If we're not searching, just pass the event along.
+ if (!isSearching()) {
+ clearSearchingState();
+ reindex();
+ fireTableChanged(e);
+ return;
+ }
+
+ // Something has happened to the data that may have invalidated
the search.
+ reindex();
+ search(searchString);
+ fireTableDataChanged();
+ return;
+ }
+
+ }
+
+}
Added:
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/package.html
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/package.html?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/package.html
(added)
+++
lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/package.html
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,5 @@
+<html>
+<body>
+Decorators for JTable TableModel and JList ListModel encapsulating Lucene
indexing and searching functionality. .
+</body>
+</html>
Added: lucene/java/trunk/contrib/swing/src/java/overview.html
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/java/overview.html?view=auto&rev=156591
==============================================================================
--- lucene/java/trunk/contrib/swing/src/java/overview.html (added)
+++ lucene/java/trunk/contrib/swing/src/java/overview.html Tue Mar 8 17:52:13
2005
@@ -0,0 +1,7 @@
+<html>
+ <head>
+ <title>Jakarta Lucene Swing Component Models</title>
+ </head>
+ <body>
+ </body>
+</html>
\ No newline at end of file
Added:
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseListModel.java
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseListModel.java?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseListModel.java
(added)
+++
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseListModel.java
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,55 @@
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * @author Jonathan Simon - [EMAIL PROTECTED]
+ */
+public class BaseListModel extends AbstractListModel {
+ private ArrayList data = new ArrayList();
+
+ public BaseListModel(Iterator iterator) {
+ while (iterator.hasNext()) {
+ data.add(iterator.next());
+ }
+ }
+
+ public int getSize() {
+ return data.size();
+ }
+
+ public Object getElementAt(int index) {
+ return data.get(index);
+ }
+
+ public void addRow(Object toAdd) {
+ data.add(toAdd);
+ fireContentsChanged(this, 0, getSize());
+ }
+
+ public void removeRow(Object toRemove) {
+ data.remove(toRemove);
+ fireContentsChanged(this, 0, getSize());
+ }
+
+
+
+}
Added:
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseTableModel.java
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseTableModel.java?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseTableModel.java
(added)
+++
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseTableModel.java
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,100 @@
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import javax.swing.table.AbstractTableModel;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * @author Jonathan Simon - [EMAIL PROTECTED]
+ */
+public class BaseTableModel extends AbstractTableModel {
+ private ArrayList columnNames = new ArrayList();
+ private ArrayList rows = new ArrayList();
+
+ public BaseTableModel(Iterator data) {
+ columnNames.add("Name");
+ columnNames.add("Type");
+ columnNames.add("Phone");
+ columnNames.add("Street");
+ columnNames.add("City");
+ columnNames.add("State");
+ columnNames.add("Zip");
+
+ while (data.hasNext()) {
+ Object nextRow = (Object) data.next();
+ rows.add(nextRow);
+ }
+ }
+
+ public int getColumnCount() {
+ return columnNames.size();
+ }
+
+ public int getRowCount() {
+ return rows.size();
+ }
+
+ public void addRow(RestaurantInfo info){
+ rows.add(info);
+ fireTableDataChanged();
+ }
+
+ public void removeRow(RestaurantInfo info){
+ rows.remove(info);
+ fireTableDataChanged();
+ }
+
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return false;
+ }
+
+ public Class getColumnClass(int columnIndex) {
+ return String.class;
+ }
+
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ RestaurantInfo restaurantInfo = (RestaurantInfo) rows.get(rowIndex);
+ if (columnIndex == 0){ // name
+ return restaurantInfo.getName();
+ } else if (columnIndex == 1){ // category
+ return restaurantInfo.getType();
+ } else if (columnIndex == 2){ // phone
+ return restaurantInfo.getPhone();
+ } else if (columnIndex == 3){ // street
+ return restaurantInfo.getStreet();
+ } else if (columnIndex == 4){ // city
+ return restaurantInfo.getCity();
+ } else if (columnIndex == 5){ // state
+ return restaurantInfo.getState();
+ } else if (columnIndex == 6){ // zip
+ return restaurantInfo.getZip();
+ } else {
+ return "";
+ }
+ }
+
+ public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+ //no op
+ }
+
+ public String getColumnName(int columnIndex) {
+ return columnNames.get(columnIndex).toString();
+ }
+
+}
Added:
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/DataStore.java
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/DataStore.java?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/DataStore.java
(added)
+++
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/DataStore.java
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,205 @@
+package org.apache.lucene.swing.models;
+
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import java.util.Iterator;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.math.BigDecimal;
+
+/**
+ * @author Jonathan Simon - [EMAIL PROTECTED]
+ */
+public class DataStore {
+
+ private static final String ITALIAN_CATEGORY = "Italian";
+ private static final String CUBAN_CATEGORY = "Cuban";
+ private static final String STEAK_CATEGORY = "Steak";
+ private static int id = 0;
+
+ static Collection restaurants = new ArrayList();
+ static RestaurantInfo pinos = new RestaurantInfo();
+ static RestaurantInfo canolis = new RestaurantInfo();
+ static RestaurantInfo picadillo = new RestaurantInfo();
+ static RestaurantInfo versailles = new RestaurantInfo();
+ static RestaurantInfo laCaretta = new RestaurantInfo();
+ static RestaurantInfo laCaretta2 = new RestaurantInfo();
+ static RestaurantInfo laCaretta3 = new RestaurantInfo();
+ static RestaurantInfo ranchaLuna = new RestaurantInfo();
+ static RestaurantInfo leMerais = new RestaurantInfo();
+ static RestaurantInfo chris = new RestaurantInfo();
+ static RestaurantInfo outback = new RestaurantInfo();
+ static RestaurantInfo outback2 = new RestaurantInfo();
+ static RestaurantInfo outback3 = new RestaurantInfo();
+ static RestaurantInfo outback4 = new RestaurantInfo();
+
+
+ public static Iterator getRestaurants(){
+ return restaurants.iterator();
+ }
+
+ static {
+ pinos.setId(getNextId());
+ pinos.setType(ITALIAN_CATEGORY);
+ pinos.setName("Pino's");
+ pinos.setPhone("(305) 111-2222");
+ pinos.setStreet("12115 105th Street ");
+ pinos.setCity("Miami");
+ pinos.setState("FL");
+ pinos.setZip("33176");
+ restaurants.add(pinos);
+
+ canolis.setId(getNextId());
+ canolis.setType(ITALIAN_CATEGORY);
+ canolis.setName("Canoli's");
+ canolis.setPhone("(305) 234-5543");
+ canolis.setStreet("12123 85th Street ");
+ canolis.setCity("Miami");
+ canolis.setState("FL");
+ canolis.setZip("33176");
+ restaurants.add(canolis);
+
+ picadillo.setId(getNextId());
+ picadillo.setType(CUBAN_CATEGORY);
+ picadillo.setName("Picadillo");
+ picadillo.setPhone("(305) 746-7865");
+ picadillo.setStreet("109 12th Street ");
+ picadillo.setCity("Miami");
+ picadillo.setState("FL");
+ picadillo.setZip("33176");
+ restaurants.add(picadillo);
+
+ versailles.setId(getNextId());
+ versailles.setType(CUBAN_CATEGORY);
+ versailles.setName("Cafe Versailles");
+ versailles.setPhone("(305) 201-5438");
+ versailles.setStreet("312 8th Street ");
+ versailles.setCity("Miami");
+ versailles.setState("FL");
+ versailles.setZip("33176");
+ restaurants.add(versailles);
+
+ laCaretta.setId(getNextId());
+ laCaretta.setType(CUBAN_CATEGORY);
+ laCaretta.setName("La Carretta");
+ laCaretta.setPhone("(305) 342-9876");
+ laCaretta.setStreet("348 8th Street ");
+ laCaretta.setCity("Miami");
+ laCaretta.setState("FL");
+ laCaretta.setZip("33176");
+ restaurants.add(laCaretta);
+
+ laCaretta2.setId(getNextId());
+ laCaretta2.setType(CUBAN_CATEGORY);
+ laCaretta2.setName("La Carretta");
+ laCaretta2.setPhone("(305) 556-9876");
+ laCaretta2.setStreet("31224 23rd Street ");
+ laCaretta2.setCity("Miami");
+ laCaretta2.setState("FL");
+ laCaretta2.setZip("33176");
+ restaurants.add(laCaretta2);
+
+ laCaretta3.setId(getNextId());
+ laCaretta3.setType(CUBAN_CATEGORY);
+ laCaretta3.setName("La Carretta");
+ laCaretta3.setPhone("(305) 682-9876");
+ laCaretta3.setStreet("23543 107th Street ");
+ laCaretta3.setCity("Miami");
+ laCaretta3.setState("FL");
+ laCaretta3.setZip("33176");
+ restaurants.add(laCaretta3);
+
+ ranchaLuna.setId(getNextId());
+ ranchaLuna.setType(CUBAN_CATEGORY);
+ ranchaLuna.setName("Rancha Luna");
+ ranchaLuna.setPhone("(305) 777-4384");
+ ranchaLuna.setStreet("110 23rd Street ");
+ ranchaLuna.setCity("Miami");
+ ranchaLuna.setState("FL");
+ ranchaLuna.setZip("33176");
+ restaurants.add(ranchaLuna);
+
+ leMerais.setId(getNextId());
+ leMerais.setType(STEAK_CATEGORY);
+ leMerais.setName("Le Merais");
+ leMerais.setPhone("(212) 654-9187");
+ leMerais.setStreet("11 West 46th Street");
+ leMerais.setCity("New York");
+ leMerais.setState("NY");
+ leMerais.setZip("10018");
+ restaurants.add(leMerais);
+
+ chris.setId(getNextId());
+ chris.setType(STEAK_CATEGORY);
+ chris.setName("Ruth's Chris Seakhouse");
+ chris.setPhone("(305) 354-8885");
+ chris.setStreet("12365 203rd Street ");
+ chris.setCity("Miami");
+ chris.setState("FL");
+ chris.setZip("33176");
+ restaurants.add(chris);
+
+ outback.setId(getNextId());
+ outback.setType(STEAK_CATEGORY);
+ outback.setName("Outback");
+ outback.setPhone("(305) 244-7623");
+ outback.setStreet("348 136th Street ");
+ outback.setCity("Miami");
+ outback.setState("FL");
+ outback.setZip("33176");
+ restaurants.add(outback);
+
+ outback2.setId(getNextId());
+ outback2.setType(STEAK_CATEGORY);
+ outback2.setName("Outback");
+ outback2.setPhone("(305) 533-6522");
+ outback2.setStreet("21 207th Street ");
+ outback2.setCity("Miami");
+ outback2.setState("FL");
+ outback2.setZip("33176");
+ restaurants.add(outback2);
+
+ outback3.setId(getNextId());
+ outback3.setType(STEAK_CATEGORY);
+ outback3.setName("Outback");
+ outback3.setPhone("(305) 244-7623");
+ outback3.setStreet("10117 107th Street ");
+ outback3.setCity("Miami");
+ outback3.setState("FL");
+ outback3.setZip("33176");
+ restaurants.add(outback3);
+
+ outback4.setId(getNextId());
+ outback4.setType(STEAK_CATEGORY);
+ outback4.setName("Outback");
+ outback4.setPhone("(954) 221-3312");
+ outback4.setStreet("10 11th Street ");
+ outback4.setCity("Aventura");
+ outback4.setState("FL");
+ outback4.setZip("32154");
+ restaurants.add(outback4);
+
+ }
+
+ private static int getNextId(){
+ id++;
+ return id;
+ }
+
+}
Added:
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/ListSearcherSimulator.java
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/ListSearcherSimulator.java?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/ListSearcherSimulator.java
(added)
+++
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/ListSearcherSimulator.java
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,86 @@
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import javax.swing.*;
+import javax.swing.event.DocumentListener;
+import javax.swing.event.DocumentEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import java.awt.*;
+
+/**
+ * @author Jonathan Simon - [EMAIL PROTECTED]
+ */
+public class ListSearcherSimulator {
+
+ public ListSearcherSimulator() {
+ JFrame frame = new JFrame();
+ frame.setBounds(200,200, 400,250);
+
+ JList list = new JList();
+ JScrollPane scrollPane = new JScrollPane(list);
+
+ final BaseListModel listModel = new
BaseListModel(DataStore.getRestaurants());
+ final ListSearcher listSearcher = new ListSearcher(listModel);
+
+ list.setModel(listSearcher);
+
+ final JTextField searchField = new JTextField();
+ searchField.getDocument().addDocumentListener(
+ new DocumentListener(){
+ public void changedUpdate(DocumentEvent e) {
+
listSearcher.search(searchField.getText().trim().toLowerCase());
+ }
+
+ public void insertUpdate(DocumentEvent e) {
+
listSearcher.search(searchField.getText().trim().toLowerCase());
+ }
+
+ public void removeUpdate(DocumentEvent e) {
+
listSearcher.search(searchField.getText().trim().toLowerCase());
+ }
+ }
+ );
+
+ frame.getContentPane().setLayout(new BorderLayout());
+ frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
+
+ JPanel searchPanel = new JPanel();
+ searchPanel.setLayout(new BorderLayout(10,10));
+ searchPanel.add(searchField, BorderLayout.CENTER);
+ searchPanel.add(new JLabel("Search: "), BorderLayout.WEST);
+
+ JPanel topPanel = new JPanel(new BorderLayout());
+ topPanel.add(searchPanel, BorderLayout.CENTER);
+ topPanel.add(new JPanel(), BorderLayout.EAST);
+ topPanel.add(new JPanel(), BorderLayout.WEST);
+ topPanel.add(new JPanel(), BorderLayout.NORTH);
+ topPanel.add(new JPanel(), BorderLayout.SOUTH);
+
+ frame.getContentPane().add(topPanel, BorderLayout.NORTH);
+
+ frame.setTitle("Lucene powered table searching");
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.show();
+ }
+
+ public static void main(String[] args) {
+ new ListSearcherSimulator();
+ }
+
+}
Added:
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/RestaurantInfo.java
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/RestaurantInfo.java?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/RestaurantInfo.java
(added)
+++
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/RestaurantInfo.java
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,102 @@
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jonathan Simon - [EMAIL PROTECTED]
+ */
+public class RestaurantInfo {
+ private int id;
+ private String name;
+
+ private String type;
+
+ private String phone;
+ private String street;
+ private String city;
+ private String state;
+ private String zip;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getStreet() {
+ return street;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getZip() {
+ return zip;
+ }
+
+ public void setZip(String zip) {
+ this.zip = zip;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String toString() {
+ return getName() + " - " + getPhone();
+ }
+
+}
Added:
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TableSearcherSimulator.java
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TableSearcherSimulator.java?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TableSearcherSimulator.java
(added)
+++
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TableSearcherSimulator.java
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,83 @@
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+/**
+ * @author Jonathan Simon - [EMAIL PROTECTED]
+ */
+public class TableSearcherSimulator {
+
+ public TableSearcherSimulator() {
+ JFrame frame = new JFrame();
+ frame.setBounds(200,200, 400,250);
+
+ JTable table = new JTable();
+ final BaseTableModel tableModel = new
BaseTableModel(DataStore.getRestaurants());
+ final TableSearcher searchTableModel = new TableSearcher(tableModel);
+
+ table.setModel(searchTableModel);
+ JScrollPane scrollPane = new JScrollPane(table);
+
+ final JTextField searchField = new JTextField();
+ JButton searchButton = new JButton("Go");
+
+ ActionListener searchListener = new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+
searchTableModel.search(searchField.getText().trim().toLowerCase());
+ searchField.requestFocus();
+ }
+ };
+
+ searchButton.addActionListener(searchListener);
+ searchField.addActionListener(searchListener);
+
+
+
+ frame.getContentPane().setLayout(new BorderLayout());
+ frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
+
+ JPanel searchPanel = new JPanel();
+ searchPanel.setLayout(new BorderLayout(10,10));
+ searchPanel.add(searchField, BorderLayout.CENTER);
+ searchPanel.add(searchButton, BorderLayout.EAST);
+
+ JPanel topPanel = new JPanel(new BorderLayout());
+ topPanel.add(searchPanel, BorderLayout.CENTER);
+ topPanel.add(new JPanel(), BorderLayout.EAST);
+ topPanel.add(new JPanel(), BorderLayout.WEST);
+ topPanel.add(new JPanel(), BorderLayout.NORTH);
+ topPanel.add(new JPanel(), BorderLayout.SOUTH);
+
+ frame.getContentPane().add(topPanel, BorderLayout.NORTH);
+
+ frame.setTitle("Lucene powered table searching");
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.show();
+
+ }
+
+
+ public static void main(String[] args) {
+ new TableSearcherSimulator();
+ }
+
+}
Added:
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestBasicList.java
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestBasicList.java?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestBasicList.java
(added)
+++
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestBasicList.java
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,52 @@
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.util.ArrayList;
+
+/**
+ * @author Jonathan Simon - [EMAIL PROTECTED]
+ **/
+public class TestBasicList extends TestCase {
+ private ListModel baseListModel;
+ private ListSearcher listSearcher;
+ private ArrayList list;
+
+ protected void setUp() throws Exception {
+ list = new ArrayList();
+ list.add(DataStore.canolis);
+ list.add(DataStore.chris);
+
+ baseListModel = new BaseListModel(list.iterator());
+ listSearcher = new ListSearcher(baseListModel);
+ }
+
+
+ public void testRows(){
+ assertEquals(list.size(), listSearcher.getSize());
+ }
+
+ public void testValueAt(){
+ assertEquals(baseListModel.getElementAt(0),
listSearcher.getElementAt(0));
+ assertNotSame(baseListModel.getElementAt(1),
listSearcher.getElementAt(0));
+ }
+
+}
Added:
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestBasicTable.java
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestBasicTable.java?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestBasicTable.java
(added)
+++
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestBasicTable.java
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,59 @@
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+
+import javax.swing.table.TableModel;
+import java.util.ArrayList;
+
+/**
+ * @author Jonathan Simon - [EMAIL PROTECTED]
+ */
+public class TestBasicTable extends TestCase {
+ private TableModel baseTableModel;
+ private TableSearcher tableSearcher;
+ private ArrayList list;
+
+ protected void setUp() throws Exception {
+ list = new ArrayList();
+ list.add(DataStore.canolis);
+ list.add(DataStore.chris);
+
+ baseTableModel = new BaseTableModel(list.iterator());
+ tableSearcher = new TableSearcher(baseTableModel);
+ }
+
+ public void testColumns(){
+
+ assertEquals(baseTableModel.getColumnCount(),
tableSearcher.getColumnCount());
+ assertEquals(baseTableModel.getColumnName(0),
tableSearcher.getColumnName(0));
+ assertNotSame(baseTableModel.getColumnName(0),
tableSearcher.getColumnName(1));
+ assertEquals(baseTableModel.getColumnClass(0),
tableSearcher.getColumnClass(0));
+ }
+
+ public void testRows(){
+ assertEquals(list.size(), tableSearcher.getRowCount());
+ }
+
+ public void testValueAt(){
+ assertEquals(baseTableModel.getValueAt(0,0),
tableSearcher.getValueAt(0,0));
+ assertEquals(baseTableModel.getValueAt(0,3),
tableSearcher.getValueAt(0,3));
+ }
+
+}
Added:
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestSearchingList.java
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestSearchingList.java?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestSearchingList.java
(added)
+++
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestSearchingList.java
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,48 @@
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import junit.framework.TestCase;
+
+import javax.swing.table.TableModel;
+import javax.swing.*;
+
+
+/**
+ * @author Jonathan Simon - [EMAIL PROTECTED]
+ */
+public class TestSearchingList extends TestCase {
+ private ListModel baseListModel;
+ private ListSearcher listSearcher;
+
+ protected void setUp() throws Exception {
+ baseListModel = new BaseListModel(DataStore.getRestaurants());
+ listSearcher = new ListSearcher(baseListModel);
+ }
+
+ public void testSearch(){
+ //make sure data is there
+ assertEquals(baseListModel.getSize(), listSearcher.getSize());
+ //search for pino's
+ listSearcher.search("pino's");
+ assertEquals(1, listSearcher.getSize());
+ //clear search and check that
+ listSearcher.search(null);
+ assertEquals(baseListModel.getSize(), listSearcher.getSize());
+ }
+
+}
Added:
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestSearchingTable.java
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestSearchingTable.java?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestSearchingTable.java
(added)
+++
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestSearchingTable.java
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,46 @@
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import junit.framework.TestCase;
+
+import javax.swing.table.TableModel;
+
+/**
+ * @author Jonathan Simon - [EMAIL PROTECTED]
+ */
+public class TestSearchingTable extends TestCase {
+ private TableModel baseTableModel;
+ private TableSearcher tableSearcher;
+
+ protected void setUp() throws Exception {
+ baseTableModel = new BaseTableModel(DataStore.getRestaurants());
+ tableSearcher = new TableSearcher(baseTableModel);
+ }
+
+ public void testSearch(){
+ //make sure data is there
+ assertEquals(baseTableModel.getRowCount(),
tableSearcher.getRowCount());
+ //search for pino's
+ tableSearcher.search("pino's");
+ assertEquals(1, tableSearcher.getRowCount());
+ //clear search and check that
+ tableSearcher.search(null);
+ assertEquals(baseTableModel.getRowCount(),
tableSearcher.getRowCount());
+ }
+
+}
Added:
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestUpdatingList.java
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestUpdatingList.java?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestUpdatingList.java
(added)
+++
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestUpdatingList.java
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,81 @@
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import junit.framework.TestCase;
+
+import javax.swing.table.TableModel;
+
+/**
+ * @author Jonathan Simon - [EMAIL PROTECTED]
+ */
+public class TestUpdatingList extends TestCase {
+ private BaseListModel baseListModel;
+ private ListSearcher listSearcher;
+
+ RestaurantInfo infoToAdd1, infoToAdd2;
+
+ protected void setUp() throws Exception {
+ baseListModel = new BaseListModel(DataStore.getRestaurants());
+ listSearcher = new ListSearcher(baseListModel);
+
+ infoToAdd1 = new RestaurantInfo();
+ infoToAdd1.setName("Pino's");
+
+ infoToAdd2 = new RestaurantInfo();
+ infoToAdd2.setName("Pino's");
+ infoToAdd2.setType("Italian");
+ }
+
+ public void testAddWithoutSearch(){
+ assertEquals(baseListModel.getSize(), listSearcher.getSize());
+ int count = listSearcher.getSize();
+ baseListModel.addRow(infoToAdd1);
+ count++;
+ assertEquals(count, listSearcher.getSize());
+ }
+
+ public void testRemoveWithoutSearch(){
+ assertEquals(baseListModel.getSize(), listSearcher.getSize());
+ baseListModel.addRow(infoToAdd1);
+ int count = listSearcher.getSize();
+ baseListModel.removeRow(infoToAdd1);
+ count--;
+ assertEquals(count, listSearcher.getSize());
+ }
+
+ public void testAddWithSearch(){
+ assertEquals(baseListModel.getSize(), listSearcher.getSize());
+ listSearcher.search("pino's");
+ int count = listSearcher.getSize();
+ baseListModel.addRow(infoToAdd2);
+ count++;
+ assertEquals(count, listSearcher.getSize());
+ }
+
+ public void testRemoveWithSearch(){
+ assertEquals(baseListModel.getSize(), listSearcher.getSize());
+ baseListModel.addRow(infoToAdd1);
+ listSearcher.search("pino's");
+ int count = listSearcher.getSize();
+ baseListModel.removeRow(infoToAdd1);
+ count--;
+ assertEquals(count, listSearcher.getSize());
+ }
+
+
+}
Added:
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestUpdatingTable.java
URL:
http://svn.apache.org/viewcvs/lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestUpdatingTable.java?view=auto&rev=156591
==============================================================================
---
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestUpdatingTable.java
(added)
+++
lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/TestUpdatingTable.java
Tue Mar 8 17:52:13 2005
@@ -0,0 +1,81 @@
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import junit.framework.TestCase;
+
+import javax.swing.table.TableModel;
+
+/**
+ * @author Jonathan Simon - [EMAIL PROTECTED]
+ */
+public class TestUpdatingTable extends TestCase {
+ private BaseTableModel baseTableModel;
+ private TableSearcher tableSearcher;
+
+ RestaurantInfo infoToAdd1, infoToAdd2;
+
+ protected void setUp() throws Exception {
+ baseTableModel = new BaseTableModel(DataStore.getRestaurants());
+ tableSearcher = new TableSearcher(baseTableModel);
+
+ infoToAdd1 = new RestaurantInfo();
+ infoToAdd1.setName("Pino's");
+ infoToAdd1.setType("Italian");
+
+ infoToAdd2 = new RestaurantInfo();
+ infoToAdd2.setName("Pino's");
+ infoToAdd2.setType("Italian");
+ }
+
+ public void testAddWithoutSearch(){
+ assertEquals(baseTableModel.getRowCount(),
tableSearcher.getRowCount());
+ int count = tableSearcher.getRowCount();
+ baseTableModel.addRow(infoToAdd1);
+ count++;
+ assertEquals(count, tableSearcher.getRowCount());
+ }
+
+ public void testRemoveWithoutSearch(){
+ assertEquals(baseTableModel.getRowCount(),
tableSearcher.getRowCount());
+ int count = tableSearcher.getRowCount();
+ baseTableModel.addRow(infoToAdd1);
+ baseTableModel.removeRow(infoToAdd1);
+ assertEquals(count, tableSearcher.getRowCount());
+ }
+
+ public void testAddWithSearch(){
+ assertEquals(baseTableModel.getRowCount(),
tableSearcher.getRowCount());
+ tableSearcher.search("pino's");
+ int count = tableSearcher.getRowCount();
+ baseTableModel.addRow(infoToAdd2);
+ count++;
+ assertEquals(count, tableSearcher.getRowCount());
+ }
+
+ public void testRemoveWithSearch(){
+ assertEquals(baseTableModel.getRowCount(),
tableSearcher.getRowCount());
+ baseTableModel.addRow(infoToAdd1);
+ tableSearcher.search("pino's");
+ int count = tableSearcher.getRowCount();
+ baseTableModel.removeRow(infoToAdd1);
+ count--;
+ assertEquals(count, tableSearcher.getRowCount());
+ }
+
+
+}