2010-12-05 6 views
2

私はかなりの時間を読んで、検索してきましたが、jTableを含むJavaプログラムでLuceneを使用する方法を頭に入れているようには見えません。jTableでLucene TableSearchを実装する方法

私ができることをしたいのは、新しい行エントリを送信するときにテーブルを検索することです。自分のjTableからTableModelを作成して、3.3 Lucene jarファイルを自分のパスに含めるとTableSearcherコンストラクタに渡しますか?私はいくつかのコードを含んでいます...お願いです、私はどんな方向性も歓迎します!ありがとう。ここ

はベクターに格納されたデータから自分のJTableを取り込むための私の方法であって

...ここ

public static boolean hasSearchResults = false; 
public String selectedRequirementName; 
public TableSearcher ts; 
DefaultTableModel sc; 

public TablePanel(int z, String name, String reason) { //pulls in panel number, project name, and whether the project was new or opened, from the MainGUI class 
    initComponents(); 
    sc=(DefaultTableModel) reqTable.getModel(); 
    ts = new TableSearcher(sc); 

    aProject = new Project(reason, name); //calls Project class to control the project 

    try{ 

     requirementsVector = new Vector(aProject.getRequirementsList()); 
     requirementsList =new String[requirementsVector.size()]; 

     for(int i=0; i < requirementsVector.size(); i++){ 
      requirementsList[i] = requirementsVector.get(i).getName(); 
      System.out.println(requirementsList[i]); 

      sc.addRow(new Object[]{ 
      requirementsVector.get(i).getName(), 
      requirementsVector.get(i).getDefinition(), 
      requirementsVector.get(i).getType(), 
      requirementsVector.get(i).getPriority(), 
      requirementsVector.get(i).getAssigned(), 
      requirementsVector.get(i).getDue(), 
      requirementsVector.get(i).getStatus()}); 
       //this.editingProjectName = name; 

     } 
    }catch(NullPointerException e1){ 
     System.out.println(e1); 
    } .... 

はJTableのに新しい行を挿入する私のコードである:

private void ConfirmActionPerformed(java.awt.event.ActionEvent evt) {           
    String ReqName = nameTextField.getText(); 
    String ReqDescription = descriptionTextField.getText(); 
    String Type = (String)jType.getSelectedItem(); 
    String Priority = (String)PriorityComboBox.getSelectedItem(); 
    String Assigned = (String)jDateAssignedMonth.getSelectedItem() + "/" + (String)jDateAssignedDay.getSelectedItem() + "/" + (String)jDateAssignedYear.getSelectedItem(); 
    String Due = (String)jDateDueMonth.getSelectedItem() + "/" + (String)jDateDueDay.getSelectedItem() + "/" + (String)jDateDueYear.getSelectedItem(); 
    String Status = (String)jStatus.getSelectedItem(); 

    // search string pass to TableSearcher 
    ts.search(ReqDescription); 


    if (editingaRow == false && !hasSearchResults){ 
     sc.addRow(new Object[]{ 
     ReqName,ReqDescription,Type,Priority,Assigned, Due, Status 
     }); 
     requirementsVector.add(new Requirement(ReqName, ReqDescription, Type, Priority, Assigned, Due,Status)); 
     aProject.saveRevision(requirementsVector, name); 
    }else if (editingaRow == true){ 
     sc.setValueAt(ReqName,selectedRow,0); 
     sc.setValueAt(ReqDescription,selectedRow,1); 
     sc.setValueAt(Type,selectedRow,2); 
     sc.setValueAt(Priority,selectedRow,3); 
     sc.setValueAt(Assigned,selectedRow,4); 
     sc.setValueAt(Due,selectedRow,5); 
     sc.setValueAt(Status,selectedRow,6); 

     requirementsVector.setElementAt(new Requirement(ReqName, ReqDescription, Type, Priority, Assigned, Due,Status),(selectedRow)); 

     aProject.saveRevision(requirementsVector, name); 

     editingaRow = false; 

    } 
    disableRequirementEditor(); 
    newReq.setEnabled(true); 
    reqTable.clearSelection(); 

} 

ここで私が使用しているTableSearcherモデルがあります(検索メソッドに新しい機能を追加しました)。何が起こっているのかは、新しいエントリを入力すると、そのエントリが重複として検出され、jFrameで返されます。私はTableSearcherの検索メソッド内に実装します。これは、索引付けされた表に一致しない一意の項目でのみ発生します。新しいエントリと一致するインデックスに検索結果がある場合、新しいエントリではなく、既存のエントリだけがjFrameに表示されます。

// provided by Jonathan Simon <[email protected]> 

クラスTableSearcherあなたのコードはLuceneのではないインデックステーブルのデータを行うように見えます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 final 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, IndexWriter.MaxFieldLength.UNLIMITED); 

     // 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, Field.Store.YES, Field.Index.ANALYZED)); 
      //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, Field.Store.YES, Field.Index.ANALYZED)); 
      } 
      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){ 
    // to store row numbers of results rows to display later 
    Vector<String> rowNums = new Vector(); 

    //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. 
     MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, analyzer); 
     Query query = parser.parse(searchString); 
     //run the search 
     Hits hits = is.search(query); 
     for (int t=0; t<hits.length(); t++){ 

      Document document = hits.doc(t); 
      Fieldable field = document.getField(ROW_NUMBER); 
      // adding row numbers to vector 
      rowNums.add(field.stringValue()); 

     } 

     // trying to display search results in new table 
     if(!rowNums.isEmpty()){ 
       TablePanel.hasSearchResults = true; 
       for (int v=0; v<rowNums.size(); v++){ 
        System.out.println("Match in row number " + rowNums.elementAt(v)); 
       } 

       JFrame frame = new JFrame("Possible Duplicates"); 

       String colNames[] = {"Name", "Definition", "Type", "Priority", "Date Assigned", "Due Date", "Status"}; 

       DefaultTableModel dtm = new DefaultTableModel(null,colNames); 

       for (int r = 0; r<rowNums.size(); r++){ 
        String ReqName = (String) tableModel.getValueAt(Integer.parseInt(rowNums.elementAt(r)), 0); 
        String ReqDescription = (String) tableModel.getValueAt(Integer.parseInt(rowNums.elementAt(r)), 1); 
        String Type = (String) tableModel.getValueAt(Integer.parseInt(rowNums.elementAt(r)), 2); 
        String Priority = (String) tableModel.getValueAt(Integer.parseInt(rowNums.elementAt(r)), 3); 
        String Assigned = (String) tableModel.getValueAt(Integer.parseInt(rowNums.elementAt(r)), 4); 
        String Due = (String) tableModel.getValueAt(Integer.parseInt(rowNums.elementAt(r)), 5); 
        String Status = (String) tableModel.getValueAt(Integer.parseInt(rowNums.elementAt(r)), 6); 
        dtm.addRow(new Object[]{ 
         ReqName,ReqDescription,Type,Priority,Assigned, Due, Status 
          }); 
       } 

       JTable tblResults = new JTable(dtm); 
       JScrollPane sp = new JScrollPane(tblResults); 
       JPanel panel = new JPanel(new BorderLayout()); 
       panel.setPreferredSize(new Dimension(900,300)); 
       panel.add(sp,BorderLayout.CENTER); 
       panel.add(new JLabel("Possible Duplicates",JLabel.CENTER),BorderLayout.SOUTH); 
       JOptionPane.showConfirmDialog(null,panel); 

      } 
     //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); 
      Fieldable field = document.getField(ROW_NUMBER); 
      rowToModelIndex.add(new Integer(field.stringValue())); 
      System.out.println("Something " + rowToModelIndex.add(new Integer(field.stringValue()))); 
      clearSearchingState(); 
     } 
    } 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; 
    } 

} 

答えて

0

を拡張します。これを行う簡単な方法の1つは、表示されるデータを制限するために接続できる公開された検索機能を使用して、内部的に索引付けする独自の表モデルを作成することです。これは、私がSwing Hacksで数年前に書いたことです。

索引付けをしないと、Luceneはクラスパス内にあるため、自動的には動作しません。ジョナサン

+0

は、だから私はずっとこの1 http://demo.spars.info/j/frameset.cgiようなものですTableSearcherと呼ばれる別のクラスを追加するような何かを行う可能性があります行くを取得するための出発点の詳細ですか?私のアプリケーションで "保存"ボタンを押した後、ここで私の現在のテーブルモデルを渡してください。compo_id = 61780&mode = frameset&ref = 3&method = 334&CASE = 0&MORPHO = 1&location = 1111111111111111111&LANG = 1。それから私はポップアップjpanel/jtableにこのデータを表示することができましたか? – taraloca

0

はあなたのケースでvery simple example

を見て、あなたが文書を作成するには、このような何かをするだろう、それは、インデックスに保存さになるだろう。

このコードは完全ではなく、必ずしもエラーフリーではありません。しかし、あなたは

Document doc = new Document(); 
    doc.add(new Field("ReqName", ReqName, Field.Store.YES, Field.Index.NOT_ANALYZED)); 
    doc.add(new Field("ReqDescription", ReqDescription, Field.Store.YES, Field.Index.ANALYZED)); 
    doc.add(new Field("Type", Type, Field.Store.YES, Field.Index.NOT_ANALYZED)); 
    doc.add(new Field("Priority", Priority, Field.Store.YES, Field.Index.NOT_ANALYZED)); 
    doc.add(new Field("Assigned", Assigned, Field.Store.YES, Field.Index.NOT_ANALYZED)); 
    doc.add(new Field("Due", Due, Field.Store.YES, Field.Index.NOT_ANALYZED)); 
    doc.add(new Field("Status", Status, Field.Store.YES, Field.Index.NOT_ANALYZED)); 
    writer.addDocument(doc); 
    writer.close();