source: trunk/java-client/org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java@ 2275

Last change on this file since 2275 was 2275, checked in by daven, 23 years ago

updated QueryHistory to include options (stemming) and to display them..
however there is a screen real estate problem :-(
But checking in the underlying support anyway. Will sort out display soon.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 17.2 KB
Line 
1/*
2 * SimpleGraphicalClient.java
3 * Copyright (C) 2001 New Zealand Digital Library Project
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.nzdl.gsdl.SimpleGraphicalClient;
20
21import java.awt.*;
22import java.awt.event.*;
23import java.io.*;
24import java.io.IOException;
25import java.util.*;
26import javax.swing.*;
27import javax.swing.event.*;
28import javax.swing.text.*;
29import javax.swing.text.html.*;
30
31
32// local libraries
33import org.nzdl.gsdl.service.NzdlCollectionInfo;
34import org.nzdl.gsdl.service.NzdlQuery;
35import org.nzdl.gsdl.service.NzdlRequest;
36import org.nzdl.gsdl.service.NzdlResponse;
37import org.nzdl.gsdl.service.NzdlResultSet;
38import org.nzdl.gsdl.service.NzdlService;
39import org.nzdl.gsdl.service.NzdlServiceClient;
40import org.nzdl.gsdl.util.*;
41
42
43/**
44 * A Class representing the Panel in which the Querying action happens.
45 *
46 * Does most of the actual `work' in the package.
47 *
48 * @author Dave Nichols ([email protected])
49 * @author stuart yeates ([email protected])
50 * @version $Revision: 2275 $
51 * @see org.nzdl.gsdl.service.SimpleGraphicalClient.SimpleGraphicalClient
52 * @see org.nzdl.gsdl.service.SimpleGraphicalClient.CSModel
53 * @see javax.swing.JPanel
54 */
55
56public class SearchPanel extends JPanel implements ActionListener, Constants
57{
58
59 CSModel csModel;
60 NzdlService nzdl;
61
62 JLabel collectionLabel;
63 JButton collectionInfoButton;
64 JTextField searchTextField;
65 JButton searchButton;
66 JComboBox collectionList;
67 JPanel queryFormulationPanel, resultsPanel, dataPanel, optionsPanel;
68 JPanel queryTypePanel, searchControlPanel;
69 JPanel collectionListPanel, searchTextFieldPanel, searchButtonPanel;
70 JList resultsList;
71 JCheckBox stemCheckBox, caseFoldCheckBox;
72 JRadioButton rankedRadioButton, booleanRadioButton;
73 ButtonGroup buttonGroup;
74 JScrollPane scrollResultsPane;
75 JScrollPane scrollDataPane;
76 JFrame windowParent;
77 //JEditorPane documentPane;
78 JTextPane documentPane; // make this a JTextComponent ??
79 JTextArea documentArea;
80 JTextComponent documentComponent;
81 HTMLEditorKit htmlEditorKit = new HTMLEditorKit();
82 StyledEditorKit styledEditorKit = new StyledEditorKit();
83 GMLDocument htmlDoc = new GMLDocument();
84 DefaultStyledDocument defaultStyledDoc = new DefaultStyledDocument();
85 final static GMLDocument blankDoc = new GMLDocument();
86
87 /**
88 * Construct and initialise a new SearchPanel
89 */
90
91 public SearchPanel( CSModel newCsModel, JFrame parent)
92 {
93 super();
94 windowParent = parent;
95 csModel = newCsModel;
96 nzdl = csModel.getNzdlService();
97 setLayout( new BoxLayout(this, BoxLayout.Y_AXIS));
98 setBorder(BorderFactory.createTitledBorder("Search"));
99
100
101 searchTextField = new JTextField("Enter search terms here", 35) {
102 public boolean isRequestFocusEnabled(){
103 return true;
104 }
105 };
106 searchTextField.setText("Enter search terms here");
107 searchTextField.setFont(searchTextFieldFont);
108 searchTextField.setColumns(35);
109 searchTextField.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
110 searchButton = new JButton("Search");
111
112 searchButton.addActionListener(this);
113 //searchButton.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
114 searchButton.setPreferredSize(new Dimension(80, 20));
115
116 collectionListPanel = new JPanel();
117 collectionListPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
118 collectionListPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
119 collectionLabel = new JLabel("Collection: ");
120
121 collectionList = new JComboBox(csModel.getCollectionList()){
122 public boolean isFocusTraversable() {
123 return false;
124 }
125 };
126 collectionList.setEditable(false);
127
128 collectionInfoButton = new JButton("Info...") {
129 public String getToolTipText(MouseEvent e) {
130 return "Collection information for '" + csModel.getLongCollectionName((String)collectionList.getSelectedItem()) +"'";
131 }
132 };
133 ToolTipManager.sharedInstance().registerComponent(collectionInfoButton);
134 collectionInfoButton.addActionListener(this);
135
136 collectionListPanel.add(collectionLabel);
137 collectionListPanel.add(collectionList);
138 collectionListPanel.add(collectionInfoButton);
139
140 searchTextFieldPanel = new JPanel();
141 searchTextFieldPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
142 searchTextFieldPanel.add(searchTextField);
143
144 //NzdlPreferences prefs = NzdlPreferences.getInstance();
145 String queryType = NzdlConstants.DEFAULT_QUERY_TYPE;
146 if (NzdlPreferences.getInstance().isString(NzdlConstants.QUERYTYPE)) {
147 queryType = NzdlPreferences.getInstance().getString(NzdlConstants.QUERYTYPE);
148 }
149 // check integrity of queryType
150 if (!((queryType.equals(NzdlConstants.RANKED_STRING)) | (queryType.equals(NzdlConstants.BOOLEAN_STRING)))) {
151 // preferences may have been corrupted!
152 queryType = NzdlConstants.DEFAULT_QUERY_TYPE;
153 }
154 boolean stemming = NzdlConstants.DEFAULT_STEMMING;
155 if (NzdlPreferences.getInstance().isBoolean(NzdlConstants.STEMMING))
156 stemming = NzdlPreferences.getInstance().getBoolean(NzdlConstants.STEMMING);
157 boolean caseFolding = NzdlConstants.DEFAULT_CASE_FOLDING;
158 if (NzdlPreferences.getInstance().isBoolean(NzdlConstants.CASE_FOLDING))
159 caseFolding = NzdlPreferences.getInstance().getBoolean(NzdlConstants.CASE_FOLDING);
160
161 optionsPanel = new JPanel();
162
163 queryTypePanel = new JPanel();
164 queryTypePanel.setLayout(new GridLayout(2,1));
165 rankedRadioButton = new JRadioButton(NzdlConstants.RANKED_STRING);
166 rankedRadioButton.setActionCommand(NzdlConstants.RANKED_STRING);
167 rankedRadioButton.setSelected(queryType.equals(rankedRadioButton.getText()));
168 rankedRadioButton.setToolTipText("Display results in a ranked list");
169
170 booleanRadioButton = new JRadioButton(NzdlConstants.BOOLEAN_STRING);
171 booleanRadioButton.setActionCommand(NzdlConstants.BOOLEAN_STRING);
172 booleanRadioButton.setSelected(queryType.equals(booleanRadioButton.getText()));
173 booleanRadioButton.setToolTipText("Allows the use of Boolean operators: AND(&) OR(|) and NOT(!)");
174 buttonGroup = new ButtonGroup();
175 buttonGroup.add(rankedRadioButton);
176 buttonGroup.add(booleanRadioButton);
177 queryTypePanel.add(rankedRadioButton);
178 queryTypePanel.add(booleanRadioButton);
179
180 stemCheckBox = new JCheckBox("Stemming", stemming);
181 stemCheckBox.setToolTipText("Strip endings such as '...ing', '...ed'");
182 caseFoldCheckBox = new JCheckBox("Match case", caseFolding);
183 caseFoldCheckBox.setToolTipText("Only match when the case is the same");
184
185 optionsPanel.add(queryTypePanel);
186 optionsPanel.add(stemCheckBox);
187 optionsPanel.add(caseFoldCheckBox);
188
189 searchButtonPanel = new JPanel();
190 searchButtonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
191 searchButtonPanel.add(searchButton);
192
193 searchControlPanel = new JPanel();
194 searchControlPanel.setLayout(new BorderLayout());
195 searchControlPanel.add(optionsPanel, BorderLayout.WEST);
196 searchControlPanel.add(searchButtonPanel, BorderLayout.EAST);
197
198 queryFormulationPanel = new JPanel();
199 queryFormulationPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
200 queryFormulationPanel.setLayout(new BoxLayout(queryFormulationPanel, BoxLayout.Y_AXIS));
201 queryFormulationPanel.add(Box.createHorizontalStrut(100));
202 queryFormulationPanel.add(collectionListPanel);
203 queryFormulationPanel.add(searchTextFieldPanel);
204 queryFormulationPanel.add(searchControlPanel);
205
206 resultsPanel = new JPanel();
207 resultsPanel.setLayout(new BorderLayout());
208 resultsPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
209 ResultModel resultListModel = csModel.getResultsModel();
210 resultsList = new JList(resultListModel);
211 resultsList.setFont(resultsFont);
212 resultsList.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
213 resultsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
214 scrollResultsPane = new JScrollPane(resultsList);
215 resultsPanel.add(scrollResultsPane, BorderLayout.CENTER);
216 csModel.addResult(Result.INITIAL_FAKE_RESULT);
217
218 dataPanel = new JPanel();
219 dataPanel.setLayout(new BorderLayout());
220 dataPanel.setBorder(BorderFactory.createEmptyBorder(3,3,3,3));
221 documentPane = new JTextPane() { // to control scrolling for raw text docs
222 public boolean getScrollableTracksViewportWidth() {
223 if (getSize().width < getParent().getSize().width)
224 return true;
225 else return false;
226 }
227 public void setSize(Dimension d) {
228 if (d.width < getParent().getSize().width)
229 d.width = getParent().getSize().width;
230 super.setSize(d);
231 }
232 }; // end custom JTextPane
233
234 documentPane.setEditable(false);
235 documentPane.setFont(docFont);
236 documentPane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
237 //documentPane.setPreferredSize(new Dimension(100, 100));
238
239 scrollDataPane = new JScrollPane(documentPane);
240 scrollDataPane.setPreferredSize(new Dimension(300, 300));
241 dataPanel.add(scrollDataPane, BorderLayout.CENTER);
242
243 parent.getRootPane().setDefaultButton(searchButton);
244
245 resultsList.addListSelectionListener(new ResultListSelectionHandler() );
246
247 add(Box.createHorizontalStrut(400));
248 add(queryFormulationPanel);
249 add(resultsPanel);
250 add(dataPanel);
251 searchTextField.requestFocus();
252 }
253
254 /** respond to the user pressing the Search button */
255
256 public void actionPerformed(ActionEvent e) {
257 String collectionName = collectionList.getSelectedItem().toString();
258 if (e.getSource() == searchButton ) {
259 // cursor not set when RETURN pressed, only when button clicked ?
260 windowParent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
261 String queryString = searchTextField.getText();
262 System.err.println("Search started (" + collectionName + "): \"" + queryString + "\" ..." );
263 //send query to collection
264 NzdlQuery nzdlQuery = new NzdlQuery(queryString);
265 nzdlQuery.setQueryType(buttonGroup.getSelection().getActionCommand());
266 System.err.println(buttonGroup.getSelection().getActionCommand());
267 //nzdlQuery.setQueryType("boolean");
268 nzdlQuery.setStemming(stemCheckBox.isSelected());
269 // interface reverses underlying logic so negate UI element state
270 nzdlQuery.setCaseFolding(! caseFoldCheckBox.isSelected());
271
272 // return the first numResults that match
273 nzdlQuery.setEndResults( -1 );
274 // "-1" means consider all the documents that match
275 nzdlQuery.setMaxDocs( -1 );
276
277 NzdlRequest request = new NzdlRequest( nzdlQuery );
278 NzdlResponse response = new NzdlResponse();
279
280 nzdl.service( collectionName, request, response );
281 NzdlResultSet results = response.getResultSet();
282 ArrayList docIDs = new ArrayList(results.getDocumentIDs());
283 // System.err.println("Size of docIDs = " + docIDs.size());
284 // paired collection of docIDs and Titles - but as Sets!
285 Map titleMetaData = nzdl.getMetaData( collectionName, docIDs, "Title" );
286 // created a paired collection of docIDs and Titles - as simple Strings!
287 HashMap titleMap = new HashMap();
288 for (ListIterator i = docIDs.listIterator(); i.hasNext(); ) {
289 String docID = (String) i.next();
290 //Set titleSet = (Set) titleMetaData.get( docID );
291 ArrayList titleList = new ArrayList((Set)titleMetaData.get(docID));
292 // use the first title as *the* title
293 titleMap.put(docID, titleList.get(0));
294 } // end for
295 // update the results list
296 csModel.clearResults();
297
298 if (docIDs.size() == 0 ) { // give some feedback for 0 results
299 csModel.addResult(Result.FAKE_RESULT);
300 documentPane.setStyledDocument(blankDoc);
301 }
302 else { // there are some results
303 Iterator docIDsIterator = docIDs.iterator();
304 while (docIDsIterator.hasNext()) {
305 String resultDocID = (String) docIDsIterator.next();
306 csModel.addResult(new Result((String)titleMap.get(resultDocID), resultDocID, collectionName ));
307 } //end while
308 if (NzdlPreferences.getInstance().getBoolean(NzdlConstants.DISPLAY_FIRST_DOC))
309 resultsList.setSelectedIndex(0);
310 } // end else
311
312
313 csModel.getQueryHistoryModel().add( new QueryHistoryItem(new Query(queryString), new Date(), collectionName, "user",docIDs.size(),buttonGroup.getSelection().getActionCommand(),stemCheckBox.isSelected(), caseFoldCheckBox.isSelected() ));
314
315 titleMap.clear();
316 titleMetaData.clear();
317 docIDs.clear();
318 windowParent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
319 } // end if
320 else {
321 if (e.getSource() == collectionInfoButton) {
322 CollectionInfoDialog cid = new CollectionInfoDialog(windowParent, collectionName, csModel);
323 }
324 else {
325 System.err.println("unknown Action event in SearchPanel");
326 }
327 }
328 } //end actionPerformed
329
330 /** handles selection events in the results list so that when the
331 user selects a new title (say) the document contents is
332 automatically displayed in the main panel */
333
334 class ResultListSelectionHandler implements ListSelectionListener {
335
336 // private Result previousSelection = null;
337
338 public void valueChanged(ListSelectionEvent e) {
339 // get the result object from the SelectedIndex
340 // assume we only get here with events from resultsList
341 int docLength = 0;
342 if (e.getValueIsAdjusting()) { return; }
343 Result result = (Result) resultsList.getSelectedValue();
344 if ((result == Result.FAKE_RESULT) || (result == Result.INITIAL_FAKE_RESULT)) {
345 documentPane.setStyledDocument( blankDoc );
346 System.err.println("clicked on fake result");
347 }
348 else { // a real result representing a real document to deal with
349
350 windowParent.setCursor(WAIT_CURSOR);
351
352 deleteDocContents(); // for memory/garbage collection
353
354 StringReader sr = new StringReader(nzdl.getDocument(result.getCollectionName(), result.getDocID()));
355
356 if (NzdlPreferences.getInstance().getBoolean(NzdlConstants.RAW_TEXT))
357 // display the document as raw text
358 displayAsRawText(sr);
359 else {
360 // treat as HTML
361 displayAsHTML(sr);
362 //htmlDoc.getImageData(nzdl, result.getCollectionName());
363 }
364
365 windowParent.setCursor(NORMAL_CURSOR);
366 }
367 } //end valueChanged
368 }//end ResultListSelectionHandler
369
370
371
372 private void deleteDocContents() {
373 //trash the old htmlDoc for memory/garbage collection
374 try {
375 if (htmlDoc != null)
376 htmlDoc.remove(0, htmlDoc.getLength());
377 if (defaultStyledDoc != null)
378 defaultStyledDoc.remove(0, defaultStyledDoc.getLength());
379 }
380 catch (Exception exception) {
381 throw new Error (exception.toString());
382 }
383 } // end deleteDocContents
384
385
386 public void switchToRawText() {
387 windowParent.setCursor(WAIT_CURSOR);
388 System.err.println("switching to raw text");
389 displayAsRawText(new StringReader(documentPane.getText()));
390 windowParent.setCursor(NORMAL_CURSOR);
391 }
392
393 public void displayAsRawText(StringReader sr) {
394 defaultStyledDoc = new DefaultStyledDocument();
395 documentPane.setEditorKit(styledEditorKit);
396 try {
397 styledEditorKit.read( sr, defaultStyledDoc, 0);
398 }
399 catch (Exception e) {
400 System.err.println(e);
401 }
402 documentPane.setDocument(defaultStyledDoc);
403 setCaretToStart(defaultStyledDoc.getLength());
404 } // end displayAsRawText
405
406
407 public void switchToHTML() {
408 windowParent.setCursor(WAIT_CURSOR);
409 System.err.println("switching to HTML");
410 displayAsHTML(new StringReader(documentPane.getText()));
411 windowParent.setCursor(NORMAL_CURSOR);
412 }
413
414 public void displayAsHTML(StringReader sr) {
415 htmlDoc = new GMLDocument();
416 documentPane.setEditorKit(htmlEditorKit);
417 try {
418 htmlEditorKit.read( sr, htmlDoc, 0);
419 }
420 catch (Exception e) {
421 System.err.println(e);
422 }
423 documentPane.setStyledDocument( htmlDoc );
424 setCaretToStart(htmlDoc.getLength());
425 } // end displayAsHTML
426
427
428 private void setCaretToStart(int docLength) {
429 // it seems as if they haven't considered
430 // documents with > MAX_INT num of chars ...
431 if (docLength > 0)
432 documentPane.setCaretPosition(1);
433 }
434
435 /*
436 * save prefs not in preferencesDialog
437 */
438 public void savePrefs() {
439 NzdlPreferences.getInstance().setBoolean(NzdlConstants.STEMMING,stemCheckBox.isSelected());
440 NzdlPreferences.getInstance().setBoolean(NzdlConstants.CASE_FOLDING,caseFoldCheckBox.isSelected());
441 NzdlPreferences.getInstance().setString(NzdlConstants.QUERYTYPE,buttonGroup.getSelection().getActionCommand());
442 } //savePrefs
443
444
445} //end SearchPanel
Note: See TracBrowser for help on using the repository browser.