source: main/trunk/greenstone3/src/java/org/greenstone/applet/phind/JResultCanvas.java@ 38799

Last change on this file since 38799 was 38799, checked in by anupama, 4 months ago
  1. ScrollPane wasn't being used and it didn't workout with the way the code used the scrollbar to calculate positioning, so I instantiated and used a JScrollBar instead in the same manner the awt ScrollBar was being used. 2. JResultTitle bar (JResultBox's row of column headings) wasn't appearing and neither was the scrollbar, or else the centre pane (ResultCanvas with results) wasn't appearing. The layout wasn't working except on resize. The solution was that ordering of adding to the layout had an effect. (Instantiating the objects added to the layout was order dependent also, as one kept a pointer to the other.) The solution turned to setPreferredSize() on the JResultTitle in its constructor, rather than calling setSize(). This fixed the layout and now I don't want to fiddle with it any more as it works out for the JApplet just as for the Applet, and still works when the JPhind JApplet class is run as an application from the commandline as well.
File size: 18.3 KB
Line 
1/**********************************************************************
2 *
3 * ResultCanvas.java -- a Canvas onto which a phrase list is drawn
4 *
5 * Copyright 1997-2000 Gordon W. Paynter
6 * Copyright 2000 The New Zealand Digital Library Project
7 *
8 * A component of the Greenstone digital library software
9 * from the New Zealand Digital Library Project at the
10 * University of Waikato, New Zealand.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 *********************************************************************/
27
28/*********************************************************************
29
30This class is used in the Phind java applet (Phind.java).
31
32The results of a query are displayed on a ResultCanvas object. Each
33entry in the result list is stored in a ResultItem, and the ResultCanvas
34contains a Vector of ResultItems.
35
36Each ResultCanvas is embedded in a ResultBox alongside a Scrollbar.
37When the ResultCanvas is drawn, it looks at the scrollbar, calculates
38which ResultItems are visible, then draws them on the screen.
39
40**********************************************************************/
41
42package org.greenstone.applet.phind;
43
44import javax.swing.JScrollBar;
45import javax.swing.JComponent;
46
47import java.awt.Graphics;
48import java.awt.Font;
49import java.awt.FontMetrics;
50import java.awt.Dimension;
51import java.awt.Color;
52import java.util.Vector;
53import java.awt.Image;
54//import java.awt.Event;
55import java.awt.event.MouseListener;
56import java.awt.event.MouseEvent;
57import java.awt.event.MouseAdapter;
58import java.net.URL;
59import java.util.Date;
60
61public class JResultCanvas extends JComponent {
62
63 // Other objects associated with this
64 JPhind phind;
65 JResultBox parent;
66 JScrollBar scrollbar;
67
68 // fonts and font spacings to use
69 Font areaPlain, areaBold;
70 int lineSpacing;
71
72 // The items to display on this canvas
73 int numberOfItems;
74 int firstItemDisplayed;
75 int itemSelected;
76 Vector<ResultItem> items;
77
78 // the background image
79 public static Image backgroundImage;
80
81
82 // Create a ResultCanvas from the ResultBox which is its parent.
83 JResultCanvas(JResultBox p) {
84
85 parent = p;
86 phind = p.phind;
87 scrollbar = p.s;
88 parent.disableScrollbar();
89
90 areaPlain = phind.plainFont;
91 areaBold = phind.boldFont;
92
93 lineSpacing = phind.fontSize + 2;
94
95 items = new Vector<ResultItem>();
96 numberOfItems = 0;
97 firstItemDisplayed = 0;
98 itemSelected = -1;
99
100 if (backgroundImage == null) {
101 backgroundImage = p.phind.backgroundImage;
102 }
103
104 // add a mouse listener for the mouse clicks. we only want to override
105 // one method, so we use the adaptor class
106 addMouseListener(new MouseAdapter() {
107 public void mouseClicked(MouseEvent evt) {
108 JResultCanvas.this.mouseClicked(evt); // custom method called mouseClicked
109 }
110 });
111
112
113 }
114
115 void resetCanvas( ) {
116 items.removeAllElements();
117 numberOfItems = 0;
118 repaint();
119 }
120
121
122 // Add a new search result.
123 // Return true if successful, otherwise false.
124 boolean addResultItem( ResultItem item ) {
125
126 // Add a new result, in sorted order.
127 // First sort key is item kind (lowest first),
128 // second is frequency (highest first).
129 // This is not efficient, but I don't care right now.
130 int index = 0;
131 while ((index < numberOfItems) &&
132 ((item.sort < items.elementAt(index).sort) ||
133 ((item.sort == items.elementAt(index).sort) &&
134 (item.frequency <= items.elementAt(index).frequency)))) {
135 index++;
136 }
137 items.insertElementAt(item,index);
138 numberOfItems++;
139 return true;
140 }
141
142
143 // Update more phrases/documents/links markers
144 void updateMarkers() {
145 updateMorePhrasesMarker();
146 updateMoreDocumentsMarker();
147 updateMoreLinksMarker();
148 }
149
150 // Make sure the more Phrases item only appears in the list
151 // if it is meant to.
152 void updateMorePhrasesMarker() {
153
154 System.out.println("updateMorePhrasesMarker() ");
155 System.out.println("expansions retrieved = "+parent.expansionsRetrieved +" num expansions = "+parent.numberOfExpansions);
156 // look for a marker
157 boolean found = false;
158 int index = 0;
159 while (!found && (index < numberOfItems)) {
160 if (items.elementAt(index).isMorePhrases()) {
161 found = true;
162 } else {
163 index++;
164 }
165 }
166
167 if (parent.expansionsRetrieved == parent.numberOfExpansions) {
168 // there should be no marker
169 if (found) {
170 items.removeElementAt(index);
171 numberOfItems--;
172 }
173
174 } else if (parent.expansionsRetrieved < parent.numberOfExpansions) {
175 if (!found) {
176 ResultItem ri = new ResultItem(ResultItem.morePhrases);
177 addResultItem(ri);
178 }
179 }
180 }
181
182
183 // Make sure the more documents marker appears when required
184 void updateMoreDocumentsMarker() {
185
186 // System.out.println("updateMoreDocumentsMarker() ");
187
188 // look for a marker
189 boolean found = false;
190 int index = 0;
191 while (!found && (index < numberOfItems)) {
192 if (items.elementAt(index).isMoreDocuments()) {
193 found = true;
194 } else {
195 index++;
196 }
197 }
198
199 if (parent.documentsRetrieved == parent.numberOfDocuments) {
200 // there should be no marker
201 if (found) {
202 items.removeElementAt(index);
203 numberOfItems--;
204 }
205
206 } else if (parent.documentsRetrieved < parent.numberOfDocuments) {
207 // there should be a marker
208 if (!found) {
209 ResultItem ri = new ResultItem(ResultItem.moreDocuments);
210 addResultItem(ri);
211 }
212 }
213 }
214
215
216 // Make sure the more links marker appears when required
217 void updateMoreLinksMarker() {
218
219 // System.out.println("updateMoreLinksMarker() ");
220
221 // look for a marker
222 boolean found = false;
223 int index = 0;
224 while (!found && (index < numberOfItems)) {
225 if (items.elementAt(index).isMoreLinks()) {
226 found = true;
227 } else {
228 index++;
229 }
230 }
231
232 if (parent.thesaurusLinksRetrieved == parent.numberOfThesaurusLinks) {
233 // there should be no marker
234 if (found) {
235 items.removeElementAt(index);
236 numberOfItems--;
237 }
238
239 } else if (parent.thesaurusLinksRetrieved < parent.numberOfThesaurusLinks) {
240 // there should be a marker
241 if (!found) {
242 ResultItem ri = new ResultItem(ResultItem.moreLinks);
243 addResultItem(ri);
244 }
245 }
246 }
247
248 public void paintComponent(Graphics g) {
249 super.paintComponent(g);
250
251 // calculate the canvas size, margins, and spacing
252
253 // Note: the size() method is deprecated, but getSize fails in NetScape 4
254 Dimension canvasSize = getSize();
255
256 g.setFont(areaPlain);
257 int space = g.getFontMetrics().stringWidth(" ");
258 int nought = g.getFontMetrics().stringWidth("0");
259
260 int firstColumnWidth = phind.column_1_width * nought;
261 int secondColumnWidth = phind.column_2_width * nought;
262 int columnWidth = firstColumnWidth + secondColumnWidth;
263
264 int firstColumnLeft = canvasSize.width - columnWidth;
265 int secondColumnLeft = firstColumnLeft + firstColumnWidth;
266
267 int mainLeftMargin = 0;
268 int mainRightMargin = firstColumnLeft;
269
270 // the number of items that will fit on the canvas
271 int visible = canvasSize.height / lineSpacing;
272
273 // calculate the first item to output
274 int scrollValue = scrollbar.getValue();
275 if (numberOfItems <= visible) {
276 scrollValue = 0;
277 } else if (scrollValue > (numberOfItems - visible)) {
278 scrollValue = numberOfItems - visible;
279 }
280 firstItemDisplayed = scrollValue;
281
282 // Draw the phrase area
283 Color fore = phind.panel_fg;
284 Color back = phind.panel_bg;
285
286
287 // draw the background
288 if (phind.showImage) {
289 try {
290 g.drawImage(backgroundImage,
291 mainLeftMargin, 0, mainRightMargin, canvasSize.height,
292 back, null);
293 } catch (Exception e) {
294 phind.showImage = false;
295 System.err.println("JResultCanvas paint error: " + e);
296 g.setColor(back);
297 g.fillRect(0, 0, canvasSize.width, canvasSize.height);
298 }
299 } else {
300 g.setColor(back);
301 g.fillRect(0, 0, canvasSize.width, canvasSize.height);
302 }
303
304 // If there are no phrases, output a brief explanation.
305 if (numberOfItems == 0) {
306 g.drawString("No phrases match this query.", mainLeftMargin + 10, lineSpacing);
307 }
308
309 // Output each of the visible ResultItems
310 ResultItem result;
311 int tab, i, y = 0;
312 int center = mainLeftMargin
313 + ((mainRightMargin - mainLeftMargin
314 - g.getFontMetrics().stringWidth(parent.searchPhrase)) / 2);
315 int thesColumn = mainLeftMargin + firstColumnWidth
316 + g.getFontMetrics().stringWidth("Narrower term");
317
318 String body, prefix, suffix;
319
320 for (i = scrollValue;
321 (i < numberOfItems) && (y + lineSpacing < canvasSize.height); i++) {
322
323 // Get the resultItem to output
324 result = items.elementAt(i);
325
326 // Graphics settings for drawing this line
327 y += lineSpacing;
328 g.setFont(areaPlain);
329
330 // Highlight the selected phrase.
331 if (i == itemSelected) {
332 g.setColor(phind.highlight_bg);
333 g.fillRect(mainLeftMargin, y-lineSpacing+2, mainRightMargin, lineSpacing);
334 }
335
336 // Draw the item
337
338 // Draw a phrase item
339 if (result.isPhrase()) {
340 prefix = result.prefixText();
341 body = result.mainText();
342 suffix = result.suffixText();
343
344 g.setColor(phind.expansion_fg);
345 g.setFont(areaPlain);
346 tab = center - g.getFontMetrics().stringWidth(prefix) - space;
347 g.drawString(prefix, tab, y);
348
349 g.setFont(areaBold);
350 g.drawString(body, center, y);
351
352 tab = center + space + g.getFontMetrics().stringWidth(body);
353 g.setFont(areaPlain);
354 g.drawString(suffix, tab, y);
355
356 }
357
358 // Draw a document item
359 else if (result.isDocument()){
360 body = result.mainText();
361
362 g.setColor(phind.document_fg);
363 g.setFont(areaPlain);
364 tab = (mainRightMargin - g.getFontMetrics().stringWidth(body)) / 2;
365 g.drawString(body, tab, y);
366
367 }
368
369 // Draw a thesaurus link item
370 else if (result.isLink()){
371 prefix = result.prefixText() + ":";
372 body = result.mainText();
373 tab = thesColumn - g.getFontMetrics().stringWidth(prefix) - space;
374
375 g.setColor(phind.thesaurus_fg);
376 g.setFont(areaPlain);
377 g.drawString(prefix, tab, y);
378 g.setFont(areaBold);
379 g.drawString(body, thesColumn, y);
380 }
381
382 // Draw a "more phrases/documents/links" marker
383 else if (result.isMorePhrases()
384 || result.isMoreDocuments()
385 || result.isMoreLinks()){
386 body = result.mainText();
387
388 if (result.isMorePhrases()) {
389 g.setColor(phind.expansion_bar_bg);
390 } else if (result.isMoreDocuments()) {
391 g.setColor(phind.document_bar_bg);
392 } else {
393 g.setColor(phind.thesaurus_bar_bg);
394 }
395 g.fillRect(mainLeftMargin, y-lineSpacing+2, mainRightMargin, lineSpacing);
396
397 if (result.isMorePhrases()) {
398 g.setColor(phind.expansion_bar_fg);
399 } else if (result.isMoreDocuments()) {
400 g.setColor(phind.document_bar_fg);
401 } else {
402 g.setColor(phind.thesaurus_bar_fg);
403 }
404 g.setFont(areaPlain);
405 tab = (mainRightMargin - g.getFontMetrics().stringWidth(body)) / 2;
406 g.drawString(body, tab, y);
407 }
408 }
409
410 // Draw the frequecy columns
411
412 // column backgrounds
413 g.setColor(phind.column_1_bg);
414 g.fillRect(firstColumnLeft, 0, firstColumnWidth, canvasSize.height);
415 g.setColor(phind.column_2_bg);
416 g.fillRect(secondColumnLeft, 0, secondColumnWidth, canvasSize.height);
417
418 // fill in the numbers
419 g.setColor(phind.column_1_fg);
420 g.setFont(areaPlain);
421 y = 0;
422 String docsText, freqText;
423
424 for (i = scrollValue;
425 (i < numberOfItems) && (y + lineSpacing < canvasSize.height); i++) {
426
427 // Get the resultItem to output
428 result = items.elementAt(i);
429 docsText = result.docsText();
430 freqText = result.freqText();
431
432 // Graphics settings for drawing this line
433 y += lineSpacing;
434
435 // Write the document frequency
436 if (docsText.length() > 0) {
437 tab = secondColumnLeft - space - g.getFontMetrics().stringWidth(docsText);
438 g.drawString(docsText, tab, y);
439 }
440
441 // Write the term frequency
442 if (freqText.length() > 0) {
443 tab = secondColumnLeft + secondColumnWidth
444 - space - g.getFontMetrics().stringWidth(freqText);
445 g.drawString(freqText, tab, y);
446 }
447 }
448
449 // Adjust the scrollbar
450 if (visible >= numberOfItems) {
451 parent.disableScrollbar();
452 } else {
453 scrollbar.setValues(scrollValue, visible, 0, numberOfItems);
454 // Deprecated - setPageIncrement() has been replaced by
455 // setBlockIncrement(), but the latter doesn't work on some
456 // browsers. Damn.
457 scrollbar.setBlockIncrement(visible - 1);
458 //scrollbar.setPageIncrement(visible - 1);
459 // Deprecated - more nonsense: enable() has been replaced by
460 // setEnabled(true), but this doesn't work on some browsers.
461 scrollbar.setEnabled(true);
462 //scrollbar.enable();
463 }
464
465
466 // draw the border
467 if (phind.showBorder) {
468 g.setColor(phind.panel_fg);
469 g.drawRect(0,0, canvasSize.width - 1, canvasSize.height - 1);
470 }
471 }
472
473 // handle mouse clicks in the new way. just copy gordons thing for now
474 public void mouseClicked(MouseEvent event) {
475
476 // ignore actions that occur within 1 second of the last
477 Date now = new Date();
478 // System.out.println("Click time: " + now.toString());
479 if (now.getTime() < (phind.lastQueryEndTime.getTime() + 1000)) {
480 System.out.println("Ignoring click - too close to last query.");
481 return;
482 }
483
484 // which Item is selected?
485 int rowSelected = event.getY() / lineSpacing;
486 itemSelected = rowSelected + firstItemDisplayed;
487 ResultItem item = items.elementAt(itemSelected);
488
489 if (itemSelected <= numberOfItems) {
490
491 //User clicks on a phrase
492 if (item.isPhrase()) {
493 itemSelected = itemSelected;
494 update(getGraphics());
495 parent.lookupPhrase(item.hiddenText(), item.toString(), 2);
496
497 // If meta key is held down, send query to search engine
498 /*if (event.metaDown() && !phind.library_address.equals("")) {
499 String address = phind.library_address
500 + "a=q&sa=text&c=" + phind.collection
501 + "&q=%22" + item.toString().replace(' ', '+') + "%22";
502 phind.displayWebPage(address, phind.searchWindowName);
503 }*/
504 }
505
506 // Click on a thesaurus link
507 else if (item.isLink()) {
508 itemSelected = itemSelected;
509 update(getGraphics());
510 parent.lookupPhrase(item.hiddenText(), item.toString(), 2);
511
512 // If meta key is held down, send query to search engine
513 /*if (event.metaDown() && !phind.library_address.equals("")) {
514 String address = phind.library_address
515 + "a=q&sa=text&c=" + phind.collection
516 + "&q=%22" + item.toString().replace(' ', '+') + "%22";
517 phind.displayWebPage(address, phind.searchWindowName);
518 }*/
519 }
520
521 // The user clicks on a URL; display it.
522 else if (item.isDocument()) {
523 itemSelected = itemSelected;
524 update(getGraphics());
525
526 String address = phind.library_address
527 + "a=d&c=" + phind.collection
528 + "&d=" + item.hiddenText()
529 + "&q=" + parent.searchPhrase.replace(' ', '+');
530
531 phind.displayWebPage(address, phind.documentWindowName);
532 }
533
534 // When the user clicks on "get more phrases" or other marker,
535 // we have to send a new query to the host
536 else if (item.isMorePhrases()){
537 parent.lookupPhrase(parent.searchKey, parent.searchPhrase, 3);
538 } else if (item.isMoreDocuments()){
539 parent.lookupPhrase(parent.searchKey, parent.searchPhrase, 4);
540 } else if (item.isMoreLinks()){
541 parent.lookupPhrase(parent.searchKey, parent.searchPhrase, 5);
542
543
544 }
545 repaint();
546 }
547 }
548
549 // If uncommenting this, it may need porting from awt to swing
550
551 // User interaction
552 //
553 // All interaction with the ResultCanvas is through mouse clicks, and
554 // is handles in this method. Note we ignore clicks that follow
555 // another too closely to avoid problems with slow connections.
556 /* public boolean processEvent(Event event) {
557
558 if (event.id == Event.MOUSE_UP) {
559
560 // ignore actions that occur within 1 second of the last
561 Date now = new Date();
562 // System.out.println("Click time: " + now.toString());
563 if (now.getTime() < (phind.lastQueryEndTime.getTime() + 1000)) {
564 System.out.println("Ignoring click - too close to last query.");
565 return true;
566 }
567
568 // which Item is selected?
569 int rowSelected = event.y / lineSpacing;
570 itemSelected = rowSelected + firstItemDisplayed;
571 ResultItem item = (ResultItem) items.elementAt(itemSelected);
572
573 if (itemSelected <= numberOfItems) {
574
575 //User clicks on a phrase
576 if (item.isPhrase()) {
577 itemSelected = itemSelected;
578 update(getGraphics());
579 parent.lookupPhrase(item.hiddenText(), item.toString(), 2);
580
581 // If meta key is held down, send query to search engine
582 if (event.metaDown() && !phind.library_address.equals("")) {
583 String address = phind.library_address
584 + "a=q&sa=text&c=" + phind.collection
585 + "&q=%22" + item.toString().replace(' ', '+') + "%22";
586 phind.displayWebPage(address, phind.searchWindowName);
587 }
588 }
589
590 // Click on a thesaurus link
591 else if (item.isLink()) {
592 itemSelected = itemSelected;
593 update(getGraphics());
594 parent.lookupPhrase(item.hiddenText(), item.toString(), 2);
595
596 // If meta key is held down, send query to search engine
597 if (event.metaDown() && !phind.library_address.equals("")) {
598 String address = phind.library_address
599 + "a=q&sa=text&c=" + phind.collection
600 + "&q=%22" + item.toString().replace(' ', '+') + "%22";
601 phind.displayWebPage(address, phind.searchWindowName);
602 }
603 }
604
605 // The user clicks on a URL; display it.
606 else if (item.isDocument()) {
607 itemSelected = itemSelected;
608 update(getGraphics());
609
610 String address = phind.library_address
611 + "a=r&c=" + phind.collection
612 + "&r=" + item.hiddenText()
613 + "&q=" + parent.searchPhrase.replace(' ', '+');
614
615 phind.displayWebPage(address, phind.documentWindowName);
616 }
617
618 // When the user clicks on "get more phrases" or other marker,
619 // we have to send a new query to the host
620 else if (item.isMorePhrases()){
621 parent.lookupPhrase(parent.searchKey, parent.searchPhrase, 3);
622 } else if (item.isMoreDocuments()){
623 parent.lookupPhrase(parent.searchKey, parent.searchPhrase, 4);
624 } else if (item.isMoreLinks()){
625 parent.lookupPhrase(parent.searchKey, parent.searchPhrase, 5);
626
627
628 }
629 repaint();
630 }
631 }
632 return true;
633 } */
634
635}
636
637
638
Note: See TracBrowser for help on using the repository browser.