source: trunk/gsdl/src/phind/client/ResultCanvas.java@ 1621

Last change on this file since 1621 was 1621, checked in by paynter, 24 years ago

The phind Java Applet client.

This code is version 2.2.1 of the applet, which was created an 1997 and
last updated in December 1999. Later versions will be numbered according
to the version of Greenstone they are released with. The applet does not
work with the generate and CGI programs currently in the Greenstone CVS,
but future versions will, all going well.

  • Property svn:keywords set to Author Date Id Revision
File size: 11.3 KB
Line 
1// ResultCanvas.java
2
3/*
4
5The results of a query are displayed on a ResultCanvas object.
6Each line of the result is stored in a Result, and the ResultCanvas
7contains a Vector of ResultItems.
8
9Each ResultCanvas is embedded in a ResultBox alongside a
10Scrollbar. When the ResultCanvas is drawn, it looks at the
11scrollbar, calculates which ResultItems are visible, then draws
12them on the screen.
13
14*/
15
16import java.awt.Canvas;
17import java.awt.Scrollbar;
18import java.awt.Graphics;
19import java.awt.Font;
20import java.awt.FontMetrics;
21import java.awt.Dimension;
22import java.awt.Color;
23import java.util.Vector;
24import java.awt.Image;
25import java.awt.Event;
26
27import java.net.URL;
28import java.applet.Applet;
29import java.util.Date;
30
31public class ResultCanvas extends Canvas {
32
33 // Other objects associated with this
34 Phind phind;
35 ResultBox parent;
36 Scrollbar scrollbar;
37
38 // fonts and font spacings to use
39 Font areaPlain, areaBold;
40 int lineSpacing;
41
42 // The phrases to display on this canvas
43 int numberOfPhrases;
44 int firstPhraseDisplayed;
45 int phraseSelected;
46 Vector phrases;
47
48 // the background image
49 public static Image backgroundImage;
50
51
52 // Create a ResultCanvas from the ResultBox which is its parent.
53 ResultCanvas(ResultBox p) {
54
55 parent = p;
56 phind = p.phind;
57 scrollbar = p.s;
58 parent.disableScrollbar();
59
60 areaPlain = phind.plainFont;
61 areaBold = phind.boldFont;
62
63 lineSpacing = phind.fontSize + 2;
64
65 phrases = new Vector();
66 numberOfPhrases = 0;
67 firstPhraseDisplayed = 0;
68 phraseSelected = -1;
69
70 if (backgroundImage == null) {
71 backgroundImage = p.phind.backgroundImage;
72 }
73
74 }
75
76 void resetCanvas( ) {
77 phrases.removeAllElements();
78 numberOfPhrases = 0;
79 repaint();
80 }
81
82
83 // add a new item of input.
84 // return true if successful, otherwise false.
85 boolean addResultItem( ResultItem item ) {
86
87 // Add a new result, in sorted order.
88 // First sort key is item kind (lowest first),
89 // second is frequency (highest first).
90 // This is not efficient, but I don't care right now.
91 int index = 0;
92 while ((index < numberOfPhrases) &&
93 ((item.kind > ((ResultItem) phrases.elementAt(index)).kind) ||
94 ((item.kind == ((ResultItem) phrases.elementAt(index)).kind) &&
95 (item.freq <= ((ResultItem) phrases.elementAt(index)).freq)))) {
96 index++;
97 }
98 phrases.insertElementAt(item,index);
99 numberOfPhrases++;
100 return true;
101 }
102
103
104 // Make sure the more Phrases item only appears in the list
105 // if it is meant to.
106 void updateMorePhrasesMarker() {
107
108 // System.out.println("updateMorePhrasesMarker() ");
109
110 // look for a marker
111 boolean found = false;
112 int index = 0;
113 while (!found && (index < numberOfPhrases)) {
114 if (((ResultItem) phrases.elementAt(index)).isMorePhrases()) {
115 // System.out.println("found marker at: " + index + " of " + numberOfPhrases);
116 found = true;
117 } else {
118 index++;
119 }
120 }
121
122 if (parent.expansionsRetrieved == parent.numberOfExpansions) {
123 // there should be no marker
124 // System.out.println("No marker needed");
125 if (found) {
126 // System.out.println("Remove marker");
127 phrases.removeElementAt(index);
128 numberOfPhrases--;
129 }
130
131 } else if (parent.expansionsRetrieved < parent.numberOfExpansions) {
132 // there should be a marker
133 // System.out.println("Needs marker");
134
135 if (!found) {
136 // System.out.println("Add marker");
137 ResultItem ri = new ResultItem(ResultItem.morePhrases, parent.searchKey);
138 addResultItem(ri);
139 }
140 }
141 }
142
143
144 // Make sure the more documents marker appears when required
145 void updateMoreDocumentsMarker() {
146
147 // System.out.println("updateMoreDocumentsMarker() ");
148
149 // look for a marker
150 boolean found = false;
151 int index = 0;
152 while (!found && (index < numberOfPhrases)) {
153 if (((ResultItem) phrases.elementAt(index)).isMoreDocuments()) {
154 found = true;
155 } else {
156 index++;
157 }
158 }
159
160 if (parent.documentsRetrieved == parent.numberOfDocuments) {
161 // there should be no marker
162 if (found) {
163 phrases.removeElementAt(index);
164 numberOfPhrases--;
165 }
166
167 } else if (parent.documentsRetrieved < parent.numberOfDocuments) {
168 // there should be a marker
169 if (!found) {
170 ResultItem ri = new ResultItem(ResultItem.moreDocuments, parent.searchKey);
171 addResultItem(ri);
172 }
173 }
174 }
175
176
177
178
179
180
181 public void update(Graphics g) {
182 paint(g);
183 }
184
185 public void paint(Graphics g) {
186
187 // calculate the canvas size, margins, and spacing
188 Dimension canvasSize = getSize();
189
190 g.setFont(areaPlain);
191 int space = g.getFontMetrics().stringWidth(" ");
192 int margin = g.getFontMetrics().stringWidth(" 8888 ");
193
194 int leftMargin = 0;
195 int secondColumn = canvasSize.width - margin;
196 int firstColumn = secondColumn - margin;
197 int rightMargin = firstColumn;
198
199 // calculate the number of values that will fit onscreen
200 int visible = canvasSize.height / lineSpacing;
201
202 //System.out.println("h " + canvasSize.height + ", l "
203 // + lineSpacing + ", v " + visible);
204
205 // get the initial scrollbar setting
206 // and calculate the first result to output
207 int scrollValue = scrollbar.getValue();
208 if (numberOfPhrases <= visible) {
209 scrollValue = 0;
210 } else if (scrollValue > (numberOfPhrases - visible)) {
211 scrollValue = numberOfPhrases - visible;
212 }
213 firstPhraseDisplayed = scrollValue;
214
215 // draw the background
216 if (phind.showImage) {
217 g.drawImage(backgroundImage,
218 leftMargin, 0, rightMargin, canvasSize.height,
219 Color.white, null);
220 } else {
221 g.setColor(Color.white);
222 g.fillRect(0, 0, canvasSize.width, canvasSize.height);
223 }
224
225 // First column
226 g.setColor(new Color(235, 245, 235));
227 g.fillRect(firstColumn, 0, margin, canvasSize.height);
228
229 // Second column
230 g.setColor(new Color(200, 220, 200));
231 g.fillRect(secondColumn, 0, margin, canvasSize.height);
232 g.setColor(Color.black);
233
234 // if there are no phrases, output a brief explanation.
235 if (numberOfPhrases == 0) {
236 g.drawString("No phrases match this query.", leftMargin + 10, lineSpacing);
237 }
238
239 // Output each of the visible ResultItems
240 int tab, i, y = 0;
241 int center = leftMargin + ((rightMargin - leftMargin - g.getFontMetrics().stringWidth(parent.searchPhrase)) / 2);
242 ResultItem result;
243
244 for (i = scrollValue; (i < numberOfPhrases) && (y + lineSpacing < canvasSize.height); i++) {
245
246 // Get the resultItem to output
247 result = (ResultItem) phrases.elementAt(i);
248
249 // Graphics settings for drawing this line
250 y += lineSpacing;
251 g.setFont(areaPlain);
252
253 // Highlight if the selected phrase.
254 if (i == phraseSelected) {
255 g.setColor(new Color(255, 220, 115));
256 g.fillRect(leftMargin, y-lineSpacing+2, rightMargin, lineSpacing);
257 g.setColor(Color.black);
258 }
259
260 // Draw the item - it could be phrase or a URL
261
262 // Write the document frequency
263 if ((result.documents > 1) || result.isPhrase()) {
264 g.drawString(" " + Integer.toString(result.documents), firstColumn, y);
265 }
266
267 // Write the term frequency
268 if (result.freq > 0) {
269 g.drawString(" " + Integer.toString(result.freq), secondColumn, y);
270 }
271
272 // Write the expand button
273 //if (result.expansion > 0) {
274 // g.drawString(" +", leftMargin, y);
275 //}
276
277
278 if (result.isPhrase()) {
279 // The item is a Phrase
280 tab = center - g.getFontMetrics().stringWidth(result.prefix) - space;
281 g.drawString(result.prefix, tab, y);
282 g.setFont(areaBold);
283 g.drawString(result.body, center, y);
284 tab = center + space + g.getFontMetrics().stringWidth(result.body);
285 g.setFont(areaPlain);
286 g.drawString(result.suffix, tab, y);
287
288 } else if (result.isDocument()){
289 // The item is a URL
290 g.setFont(areaPlain);
291 g.setColor(Color.blue);
292 tab = (rightMargin - g.getFontMetrics().stringWidth(result.suffix)) / 2;
293 g.drawString(result.suffix, tab, y);
294 g.setColor(Color.black);
295
296 } else if (result.isMorePhrases()){
297 // The item is a More documents marker
298 g.setColor(new Color(255, 200, 200));
299 g.fillRect(leftMargin, y-lineSpacing+2, rightMargin, lineSpacing);
300 g.setColor(Color.black);
301
302 g.setFont(areaPlain);
303 tab = (rightMargin - g.getFontMetrics().stringWidth("Get more phrases")) / 2;
304 g.drawString("Get more phrases", tab, y);
305
306 } else if (result.isMoreDocuments()){
307 // The item is a More documents marker
308 g.setColor(new Color(150, 193, 156));
309 g.fillRect(leftMargin, y-lineSpacing+2, rightMargin, lineSpacing);
310 g.setColor(Color.black);
311
312 g.setFont(areaPlain);
313 tab = (rightMargin - g.getFontMetrics().stringWidth("Get more documents")) / 2;
314 g.drawString("Get more documents", tab, y);
315
316 }
317
318 }
319
320 // adjust the scrollbar
321 if (visible >= numberOfPhrases) {
322 parent.disableScrollbar();
323 } else {
324 //System.out.println("s " + scrollValue + ", v " + visible
325 // + ", m " + (numberOfPhrases));
326 scrollbar.setValues(scrollValue, visible, 0, numberOfPhrases);
327 scrollbar.setBlockIncrement(visible - 1);
328 scrollbar.setEnabled(true);
329 }
330
331 g.drawRect(0,0, canvasSize.width - 1, canvasSize.height - 1);
332 }
333
334
335 // Handle user input
336 public boolean handleEvent(Event event) {
337
338 if (event.id == Event.MOUSE_UP) {
339
340 // ignore actions that occur within 1 second of the last
341 Date now = new Date();
342 // System.out.println("Click time: " + now.toString());
343 if (now.getTime() < (phind.lastQueryEndTime.getTime() + 1000)) {
344 System.out.println("Ignoring click - too close to last query.");
345 return true;
346 }
347
348 // which Item is selected?
349 int rowSelected = event.y / lineSpacing;
350 int itemSelected = rowSelected + firstPhraseDisplayed;
351 ResultItem item = (ResultItem) phrases.elementAt(itemSelected);
352
353 // System.out.println("Select: " + String.valueOf(rowSelected) );
354 if (itemSelected <= numberOfPhrases) {
355
356 // What do we do with the event?
357 // If user clicks on a phrase, we expand the phrase
358 // or send the phrase to a search engine (right click)
359
360 if (item.isPhrase()) {
361 // Expand the phrase
362
363 phraseSelected = itemSelected;
364 update(getGraphics());
365
366 parent.lookupPhrase(item.rule, item.toString(), 2);
367
368 if (event.metaDown()) {
369 // Also send to search engine
370 if (phind.search_url.equals("none") || phind.search_url.equals("")) {
371 System.out.println("No searching in this collection");
372 } else {
373 URL url;
374 try {
375 url = new URL(phind.search_url + "%22" + item.toString() + "%22&");
376 phind.getAppletContext().showDocument(url, "phindsearch");
377 System.out.println("The query is: " + url.toString());
378 } catch (Exception e) {
379 System.out.println("URL error: " + e.toString());
380 }
381 }
382 }
383
384 } else if (item.isDocument()) {
385 // The user clicks on a URL; display it.
386 phraseSelected = itemSelected;
387 update(getGraphics());
388
389 URL url;
390 try {
391 url = new URL(item.body);
392 // System.out.println("URL selected: " + url.toString());
393 phind.getAppletContext().showDocument(url, "phindselect");
394 } catch (Exception e) {
395 System.out.println("URL error: " + e.toString());
396 }
397
398 } else if (item.isMorePhrases()){
399 // The user clicks on a "get more phrases" marker.
400 // We have to send a new query to the host
401 parent.lookupPhrase(parent.searchKey, parent.searchPhrase, 3);
402
403 } else if (item.isMoreDocuments()){
404 parent.lookupPhrase(parent.searchKey, parent.searchPhrase, 4);
405
406
407 }
408 repaint();
409 }
410 }
411 return true;
412 }
413
414}
415
416
417
Note: See TracBrowser for help on using the repository browser.