source: trunk/gsdl/src/java/org/nzdl/gsdl/Phind/Phind.java@ 3178

Last change on this file since 3178 was 3178, checked in by kjdon, 22 years ago

fixed an obscure IE bug - it was adding a port number of -1 to the url

  • in tidy_URL
  • Property svn:keywords set to Author Date Id Revision
File size: 26.7 KB
Line 
1/**********************************************************************
2 *
3 * Phind.java -- the Phind java applet
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/*********************************************************************
30
31To use the applet, you'll need to embed it in a web page like this:
32
33<APPLET CODE="Phind.class" WIDTH=500 HEIGHT=500>
34
35 <PARAM NAME=collection VALUE="fao.org">
36 <PARAM NAME=classifier VALUE="1">
37 <PARAM NAME=phindcgi VALUE="http://kowhai/cgi-bin/phindcgi">
38 <PARAM NAME=library VALUE="http://kowhai/cgi-bin/library">
39 <PARAM NAME=backdrop VALUE="http://kowhai/~paynter/transfer/phindtest/green1.jpg">
40 The Phind java applet.
41</APPLET>
42
43There are a bunch of other parameters; these are described in the
44getParameters method below. It is all done for you in Greenstone
45in the document.dm macro file (the _phindapplet_ macro).
46
47You may have problems with Java applet security. Java applet's can only
48open socket connections (including the HTTP connections the applet uses
49to get data) to the same server the applet was loaded from. This means
50that your phindcgi, library, and (optional) backdrop URLs must be on the
51same machine that your web page was loaded from.
52
53**********************************************************************
54
55The applet comprises several classes:
56
571. Phind (this file) is the applet class, loaded by the browser.
58 It also handles network connections.
592. ResultDisplay is a Panel that sits in the applet and displays
60 things; displays are connected in a doubly-linked list.
613. ResultBox holds the results of a query. Result boxes are shown
62 to the user through ResultDisplays. Another doubly-linked list.
634. ResultTitle acts as a caption to a ResultBox describing its contents.
645. ResultCanvas is what the ResultBox data is drawn on. It draws the
65 words on the screen, and handles user input from the mouse.
666. ResultItem represents a single result object (a phrase or document).
677. PhindTitle is for drawing backdrops in ResultDisplays.
68
69**********************************************************************/
70
71package org.nzdl.gsdl.Phind;
72
73import java.awt.BorderLayout;
74import java.awt.Button;
75import java.awt.Choice;
76import java.awt.Color;
77import java.awt.Component;
78import java.awt.Dimension;
79import java.awt.Event;
80import java.awt.FlowLayout;
81import java.awt.Font;
82import java.awt.GridLayout;
83import java.awt.Image;
84import java.awt.Label;
85import java.awt.Panel;
86import java.awt.TextField;
87
88import java.net.URL;
89import java.io.DataInputStream;
90
91import java.net.Socket;
92import java.net.InetAddress;
93import java.net.UnknownHostException;
94import java.io.IOException;
95
96import java.util.Vector;
97import java.util.Date;
98
99import org.nzdl.gsdl.Phind.URLUTF8Encoder;
100
101public class Phind extends java.applet.Applet {
102
103 // What is the collection called?
104 public String collection;
105
106 // Which phind classifier are we using? (There may be more than one.)
107 public String classifier;
108
109 // Internet address of phind resources
110 public String library_address, phindcgi_address;
111
112 // Initial serach term
113 public String initialSearch;
114
115 // Number of phrases to retrieve at any one time
116 public int phraseBlockSize;
117
118 // Appearance parameters
119 public boolean vertical;
120 public int depth;
121
122 // Font
123 public int fontSize;
124 public String fontName;
125 public Font plainFont, boldFont;
126
127 // Do we want a background image in the applet?
128 public boolean showImage;
129 public String backdrop_address;
130 public Image backgroundImage;
131 public boolean showBorder;
132
133 // Colours
134 public Color panel_fg, panel_bg,
135 column_1_fg, column_1_bg,
136 column_2_fg, column_2_bg,
137 highlight_fg, highlight_bg,
138 thesaurus_fg, thesaurus_bg, thesaurus_bar_fg, thesaurus_bar_bg,
139 expansion_fg, expansion_bg, expansion_bar_fg, expansion_bar_bg,
140 document_fg, document_bg, document_bar_fg, document_bar_bg,
141 message_fg, message_bg;
142
143 // Column dimensions
144 int column_1_width, column_2_width;
145
146 // Where do we open new windows
147 String searchWindowName, documentWindowName;
148
149 // the mode of operation
150 int mode;
151 final int initMode = 0;
152 final int idleMode = 1;
153 final int searchMode = 2;
154
155 // Elements of the control panel
156 boolean showControlPanel;
157 Label titleLabel;
158 TextField wordField;
159 Button searchButton, prevButton, nextButton;
160
161 // Holders for the downloaded data
162 Panel resultPanel;
163 ResultDisplay firstDisplay, lastDisplay;
164
165 // The time at which the last query finished
166 Date lastQueryEndTime;
167
168 // lastQueryEndTime is stored to ensure a 1 second gap between a query
169 // returning and a new one beginning. It is needed because the FAO
170 // folks in Rome have a huge lag, and frquently click several times
171 // while they wait; these clicks are turned into new queries, which
172 // they await again. It is no elegant solution, but it seems like the
173 // easiest, given that I don't know threads.
174 // 1. The search button is easy to disable, and is disabled when a
175 // socket connection is in progress.
176 // 2. ResutCanvas widgets can'r be similarly disabled because the
177 // browser hides or wipes them, which looks very bad.
178 // 3. I cannot just ignore clicks on canvasses because the browser
179 // caches the clicks while the socket connection is going on, and then
180 // sends them through afterwards, when the canvas is accepting clicks
181 // again.
182 // 4. Current sequence of events is to record the time the last query
183 // ends, then whenever a click happens make sure a second has past. if
184 // you double-click the the first query is sent, returns, end-tie is
185 // set, and the second (and any others made during query time) is
186 // *immediately* processed, but since 1 second hasn't past it is
187 // ignored.
188
189
190 public String getAppletInfo() {
191 return "Phind by Gordon Paynter ([email protected]). Copyright 1997-2000.";
192 }
193
194
195 public void init() {
196
197 mode = initMode;
198
199 // Read applet parameters
200 getParameters();
201
202 // Initialise the user interface
203 setBackground(panel_bg);
204 lastQueryEndTime = new Date();
205
206 // fonts used to output text
207 plainFont = new Font(fontName, Font.PLAIN, fontSize);
208 boldFont = new Font(fontName, Font.BOLD, fontSize);
209
210 // The phind applet layout manager
211 setLayout(new BorderLayout());
212
213 // Panel containing the displays is in the center of the display
214 resultPanel = new Panel();
215 if (vertical) {
216 resultPanel.setLayout(new GridLayout(depth,1,0,2));
217 } else {
218 System.out.println("horizontal");
219 resultPanel.setLayout(new GridLayout(1,depth,2,0));
220 }
221 add("Center", resultPanel);
222
223 // Create ResultDisplays and place into the interface
224 ResultDisplay d1, d2 = null;
225 firstDisplay = new ResultDisplay(this, null);
226 resultPanel.add(firstDisplay);
227
228 if (depth == 1) {
229 lastDisplay = firstDisplay;
230 } else {
231 d1 = firstDisplay;
232 for (int i = 2; i <= depth; i++) {
233 d2 = new ResultDisplay(this, d1);
234 resultPanel.add(d2);
235 d1 = d2;
236 }
237 lastDisplay = d2;
238 }
239
240 // The control panel
241 initialiseControlPanel();
242
243 // lets get started then
244 setStatus("Welcome to Phind.");
245 mode = idleMode;
246
247 // Perform initial search, if requested
248 if (initialSearch.length() > 0) {
249 searchForWord(initialSearch);
250 }
251 }
252
253
254 // Display a message in the status bar
255 void setStatus(String status) {
256 showStatus(status);
257 }
258
259 // The user performs an action in the interface
260 public boolean action(Event evt, Object arg) {
261
262 if (evt.target == searchButton) {
263 searchForWord(getSearchTerm());
264 } else if (evt.target == wordField) {
265 searchForWord(getSearchTerm());
266 } else if (evt.target == prevButton) {
267 shiftPrevious();
268 } else if (evt.target == nextButton) {
269 shiftNext();
270 } else {
271 System.out.println("unknown action: " + evt.toString()
272 + ", object: " + arg.toString());
273 }
274 return true;
275 }
276
277
278 // Search for a word
279 //
280 // Called on two occasions:
281 // when the "Search" Button is pressed, or
282 // to perform an "initial search"
283 void searchForWord(String searchWord) {
284
285 if (mode == idleMode) {
286
287 setSearchTerm(searchWord);
288
289 // Convert the String from UTF8 charaters into
290 // an encoding that is okay for a URL.
291 searchWord = URLUTF8Encoder.encode(searchWord);
292
293 // Look up the word
294 if (searchWord.length() > 1) {
295 setStatus("searching for \"" + searchWord + "\"");
296 firstDisplay.emptyContents();
297 ResultBox result = lookupPhraseOnServer(null, false, searchWord, searchWord, 2);
298
299 // if there is an error, return
300 if (result == null) {
301 setStatus("No results for \"" + searchWord + "\"");
302 return;
303 }
304
305 // display the result
306 result.display = firstDisplay.display(result);
307 result.resize(result.display.size());
308 result.paintAll(result.getGraphics());
309 }
310
311 enablePreviousAndNext();
312 }
313 }
314
315
316 // Search for a phrase
317 //
318 // If querymode is 2, the user has clicked on a phrase.
319 // If querymode is 3, the user has requested more phrases.
320 // If querymode is 4, the user has requested more documents.
321 void searchForPhrase(ResultBox source, String key, String phrase, int queryMode) {
322
323 // System.out.println("searchForPhrase: " + key + " " + phrase + " " + queryMode);
324
325 if (mode == idleMode) {
326
327 // If we are going to replace the first ResultDisplay, then empty it
328 if (queryMode <= 2) {
329 if (source.display.next != null) source.display.next.emptyContents();
330 }
331
332 // look up the word
333 setStatus("Searching for \"" + phrase + "\"");
334 ResultBox result = lookupPhraseOnServer(source, true, key, phrase, queryMode);
335 if (result == null) {
336 setStatus("No result for \"" + phrase + "\"");
337 return;
338 }
339
340 // If this is not already displayed, display it in the last free spot
341 if (queryMode <= 2) {
342 result.display = lastDisplay.display(result);
343 result.resize(result.display.size());
344 result.paintAll(result.getGraphics());
345 }
346
347 enablePreviousAndNext();
348 }
349 }
350
351
352 // Look up a phrase (or symbol) on the server
353 //
354 // Arguments are the source of the query (a ResultBox, or null if the
355 // query comes from hitting the search button), the key to search for
356 // (the text of a phrase or a symbol number), the phrase as a string,
357 // and the query mode.
358 // Query modes are:
359 // 0 = obsolete
360 // 1 = obsolete
361 // 2 = get first N phrases and URLs,
362 // 3 = get another N phrases into same window
363 // 4 = get another N documents into same window
364 // 5 = get another N thesaurus links into same window
365
366 ResultBox lookupPhraseOnServer(ResultBox source,
367 boolean keyKnown, String key, String phrase,
368 int queryMode) {
369 disableSearchButton();
370 mode = searchMode;
371 ResultBox r = null;
372
373 if (queryMode <= 2) {
374 r = new ResultBox(this, collection, key, phrase, source);
375 } else if ((queryMode == 3) || (queryMode == 4) || (queryMode == 5)) {
376 r = source;
377 }
378
379 try {
380 queryServer(keyKnown, key, queryMode, r);
381 } catch (Exception e) {
382 System.out.println("Phind query error: " + e.toString());
383 setStatus("Query error: " + e.toString());
384 mode = idleMode;
385 enableSearchButton();
386 return null;
387 }
388
389 // The query is finished
390 setStatus(r.c.numberOfItems + " results for \"" + phrase + "\"");
391 mode = idleMode;
392 enableSearchButton();
393 lastQueryEndTime = new Date();
394
395 return r;
396 }
397
398
399 // Query the phindcgi program
400 //
401 // Send a query (a word or symbol number) to the server
402 // and pass the response to a ResultBox.
403
404 void queryServer(boolean keyKnown, String word, int queryMode, ResultBox area)
405 throws IOException {
406
407 // Build the query
408 String query = phindcgi_address + "pxml=1&c=" + collection + "&pc=" + classifier;
409
410 if (keyKnown) {
411 query = query + "&ppnum=" + word;
412 } else {
413 query = query + "&pptext=" + word;
414 }
415
416
417 // Specify the set of results to return
418 int first_e = 0;
419 int last_e = 0;
420 int first_d = 0;
421 int last_d = 0;
422 int first_l = 0;
423 int last_l = 0;
424
425 // the initial query
426 if (queryMode <= 2) {
427 last_e = phraseBlockSize;
428 last_d = phraseBlockSize;
429 last_l = phraseBlockSize;
430 }
431
432 // add phrases to an existing result set
433 else if (queryMode == 3) {
434 first_e = area.nextPhraseBlock * phraseBlockSize;
435 area.nextPhraseBlock++;
436 last_e = area.nextPhraseBlock * phraseBlockSize;
437 }
438
439 // add documents to existing result set
440 else if (queryMode == 4) {
441 first_d = area.nextDocumentBlock * phraseBlockSize;
442 area.nextDocumentBlock++;
443 last_d = area.nextDocumentBlock * phraseBlockSize;
444 }
445
446 // add thesaurus links to existing result set
447 else if (queryMode == 5) {
448 first_l = area.nextThesaurusLinkBlock * phraseBlockSize;
449 area.nextThesaurusLinkBlock++;
450 last_l = area.nextThesaurusLinkBlock * phraseBlockSize;
451 }
452
453 query = query + "&pfe=" + first_e + "&ple=" + last_e
454 + "&pfd=" + first_d + "&pld=" + last_d
455 + "&pfl=" + first_l + "&pll=" + last_l;
456
457 // Send the query to the phindcgi program
458 System.out.println("sending query: " + query);
459 try {
460 URL phindcgi = new URL(query);
461 DataInputStream in = new DataInputStream(phindcgi.openStream());
462 byte[] buffer;
463 int availableBytes = 0;
464
465 while (!area.finished) {
466 availableBytes = in.available();
467 if (availableBytes == 0) {
468 // if i had threads i'd do a wait here for 1 second
469 } else {
470 buffer = new byte[availableBytes];
471 in.read(buffer);
472 area.parseBytes(buffer);
473 }
474 }
475
476 in.close();
477 } catch (Exception e) {
478 System.err.println( "Error sending query to phindcgi: " + e);
479 }
480 area.repaint();
481 }
482
483
484 // Tidy up URLs
485 //
486 // Ensure a URL address (as string) has a protocol, host, and file.
487 //
488 // If the URL is a CGI script URL, it should be tidied up so that it is
489 // appropriate to tage attrib=value pairs on the end. This means it
490 // must either end with a "?" or (if it contains a question-mark
491 // internally) end with a "&".
492 String tidy_URL(String address, boolean isCGI) {
493
494 // System.err.println("tidy URL: " + address);
495
496 // make sure the URL has protocol, host, and file
497 if (address.startsWith("http")) {
498 // the address has all the necessary components
499 } else if (address.startsWith("/")) {
500 // there is not protocol and host
501 URL document = getDocumentBase();
502 String port = "";
503 if (document.getPort()!=-1) {
504 port = ":" + document.getPort();
505 }
506 address = "http://" + document.getHost() + port + address;
507 } else {
508 // this URL is relative to the directory the document is in
509 URL document = getDocumentBase();
510 String directory = document.getFile();
511 int end = directory.lastIndexOf('/');
512 String port = "";
513 if (document.getPort()!=-1) {
514 port = ":" + document.getPort();
515 }
516 directory = directory.substring(0,end + 1);
517 address = "http://" + document.getHost() + port + directory + address;
518
519 }
520
521 // if the URL is a cgi script, make sure it has a "?" in ti,
522 // and that it ends with a "?" or "&"
523 if (isCGI) {
524 if (address.indexOf((int) '?') == -1) {
525 address = address + "?";
526 } else if (!address.endsWith("?")) {
527 address = address + "&";
528 }
529 }
530
531 return address;
532 }
533
534
535
536 // Open an arbitrary web page
537 void displayWebPage(String address, String window) {
538 try {
539 URL url= new URL(address);
540 if (window.length() > 0) {
541 getAppletContext().showDocument(url, window);
542 } else {
543 getAppletContext().showDocument(url);
544 }
545 } catch (Exception e) {
546 System.out.println("Cannot open web page: " + e.toString());
547 }
548 }
549
550
551 // Get the applet parameters
552 void getParameters() {
553
554 // What is this collection called?
555 collection = parameterValue("collection");
556 System.out.println("Phind collection: " + collection);
557
558 // Which of the collection's classifiers are we using?
559 classifier = parameterValue("classifier", "1");
560 System.out.println("Phind classifier: " + classifier);
561
562 // Where is the phind CGI script
563 phindcgi_address = parameterValue("phindcgi");
564 phindcgi_address = tidy_URL(phindcgi_address, true);
565 System.out.println("Phind phindcgi: " + phindcgi_address);
566
567 // Where is the Greenstone library
568 library_address = parameterValue("library");
569 library_address = tidy_URL(library_address, true);
570 System.out.println("Phind library: " + library_address);
571
572 // Is there a default search term?
573 initialSearch = parameterValue("initial_search", "");
574
575 // Should we display the control panel
576 showControlPanel = true;
577 if (parameterValue("control_panel", "show").toLowerCase().equals("hide")) {
578 showControlPanel = false;
579 }
580
581 // Should we show a background image?
582 backdrop_address = parameterValue("backdrop", "");
583 if (backdrop_address.length() > 0) {
584 backdrop_address = tidy_URL(backdrop_address, false);
585 System.out.println("Phind backdrop URL: " + backdrop_address);
586
587 try {
588 URL backdrop_url = new URL(backdrop_address);
589 backgroundImage = getImage(backdrop_url);
590 showImage = true;
591 } catch (Exception e) {
592 System.out.println("Phind could not load " + backdrop_address);
593 showImage = false;
594 }
595 }
596
597 // Should we draw a border?
598 showBorder = parameterValue("border", "on").equals("off");
599
600 // Are the windows arranged vertically or horizontally
601 if (parameterValue("orientation", "vertical").toLowerCase().startsWith("hori")) {
602 vertical = false;
603 } else {
604 vertical = true;
605 }
606
607 // How many phind windows are there?
608 depth = parameterValue("depth", 3);
609
610 // Result sort order
611 // Standard is "LlEeDd", expansion-first is "EeLlDd"
612 String order = parameterValue("resultorder", "standard");
613 if (!order.equals("standard")) {
614 int next = 20;
615 ResultItem.sortMessage = next;
616 for (int x = 0; x < order.length(); x++) {
617 if (order.charAt(x) == ',') {
618 next--;
619 } else if (order.charAt(x) == 'L') {
620 ResultItem.sortLinkItem = next;
621 } else if (order.charAt(x) == 'l') {
622 ResultItem.sortMoreLinks = next;
623 } else if (order.charAt(x) == 'E') {
624 ResultItem.sortPhraseItem = next;
625 } else if (order.charAt(x) == 'e') {
626 ResultItem.sortMorePhrases = next;
627 } else if (order.charAt(x) == 'D') {
628 ResultItem.sortDocumentItem = next;
629 } else if (order.charAt(x) == 'd') {
630 ResultItem.sortMoreDocuments = next;
631 }
632 }
633 System.out.println("link: " + ResultItem.sortLinkItem);
634 System.out.println("exps: " + ResultItem.sortPhraseItem);
635 System.out.println("docs: " + ResultItem.sortDocumentItem);
636
637 }
638
639 // How many phrases should we fetch at any given time?
640 phraseBlockSize = parameterValue("blocksize", 10);
641
642 // What font should we use?
643 fontSize = parameterValue("fontsize", 10);
644 fontName = parameterValue("fontname", "Helvetica");
645
646 // Column dimensions
647 column_1_width = parameterValue("first_column_width", 6);
648 column_2_width = parameterValue("second_column_width", column_1_width);
649
650 // Where do we open new windows
651 searchWindowName = parameterValue("search_window", "phindsearch");
652 documentWindowName = parameterValue("document_window", "phinddoc");
653
654 // Colours
655 panel_fg = parameterValue("panel_fg", Color.black);
656 panel_bg = parameterValue("panel_bg", Color.white);
657
658 highlight_bg = parameterValue("highlight_bg", Color.yellow);
659
660 expansion_fg = parameterValue("expansion_fg", Color.black);
661 thesaurus_fg = parameterValue("thesaurus_fg", new Color(0, 100, 0));
662 document_fg = parameterValue("document_fg", Color.blue);
663
664 thesaurus_bar_fg = parameterValue("thesaurus_bar_fg", Color.black);
665 expansion_bar_fg = parameterValue("expansion_bar_fg", Color.black);
666 document_bar_fg = parameterValue("document_bar_fg", Color.black);
667
668 thesaurus_bar_bg = parameterValue("thesaurus_bar_bg", new Color(160, 160, 190));
669 expansion_bar_bg = parameterValue("expansion_bar_bg", new Color(255, 200, 200));
670 document_bar_bg = parameterValue("document_bar_bg", new Color(150, 193, 156));
671
672 column_1_fg = parameterValue("first_column_fg", Color.black);
673 column_1_bg = parameterValue("first_column_bg", new Color(235, 245, 235));
674 column_2_fg = parameterValue("second_column_fg", Color.black);
675 column_2_bg = parameterValue("second_column_bg", new Color(200, 220, 200));
676
677 message_fg = parameterValue("message_fg", Color.black);
678 message_bg = parameterValue("message_bg", Color.white);
679
680 // Colours I don't use, yet
681 // thesaurus_bg = parameterValue("thesaurus_bg", Color.white);
682 // expansion_bg = parameterValue("expansion_bg", Color.white);
683 // document_bg = parameterValue("document_bg", Color.white);
684 }
685
686 // Get the value of a parameter given its name.
687 // There are many types of parameters, hence the variety of functions.
688
689 // Get a REQUIRED string. Stop the applet if we cannot.
690 String parameterValue(String name) {
691 try {
692 return getParameter(name);
693 } catch (Exception e) {
694 System.err.println("Phind: you must give a parameter for \""
695 + name + "\". Stopping.");
696 stop();
697 }
698 return "";
699 }
700
701 // Get an optional parameter. Return a default if we cannot.
702 String parameterValue(String name, String defaultValue) {
703 String text = getParameter(name);
704 if (text == null) {
705 return defaultValue;
706 }
707 System.out.println("Phind " + name + ": " + text);
708 return text;
709 }
710
711 int parameterValue(String name, int defaultValue) {
712 int value;
713 try {
714 value = Integer.parseInt(getParameter(name));
715 } catch (Exception e) {
716 return defaultValue;
717 }
718 System.out.println("Phind " + name + ": " + value);
719 return value;
720 }
721
722 Color parameterValue(String name, Color defaultValue) {
723
724 String text = getParameter(name);
725 if (text == null) {
726 return defaultValue;
727 }
728 text = text.toLowerCase();
729
730 // a number of the form "#ddffee"
731 if (text.startsWith("#") && (text.length() == 7)) {
732 text = text.substring(1);
733 int r, g, b;
734 try {
735 r = Integer.parseInt(text.substring(0,2), 16);
736 g = Integer.parseInt(text.substring(2,4), 16);
737 b = Integer.parseInt(text.substring(4), 16);
738 return new Color(r, g, b);
739 } catch (Exception e) {
740 return defaultValue;
741 }
742 }
743
744 // a known Java colour string
745 else if (text.equals("black")) { return Color.black; }
746 else if (text.equals("blue")) { return Color.blue; }
747 else if (text.equals("cyan")) { return Color.cyan; }
748 else if (text.equals("darkgray")) { return Color.darkGray; }
749 else if (text.equals("gray")) { return Color.gray; }
750 else if (text.equals("green")) { return Color.green; }
751 else if (text.equals("lightgray")) { return Color.lightGray; }
752 else if (text.equals("magenta")) { return Color.magenta; }
753 else if (text.equals("orange")) { return Color.orange; }
754 else if (text.equals("pink")) { return Color.pink; }
755 else if (text.equals("red")) { return Color.red; }
756 else if (text.equals("white")) { return Color.white; }
757 else if (text.equals("yellow")) { return Color.yellow; }
758
759 return defaultValue;
760 }
761
762
763 // Control panel operations
764
765 // Initialise the control panel
766 void initialiseControlPanel() {
767
768 if (showControlPanel) {
769 Panel p1 = new Panel();
770 add("North", p1);
771 p1.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
772
773 searchButton = new Button("Search");
774 searchButton.setFont(boldFont);
775 p1.add(searchButton);
776
777 Label tempLabel = new Label(" for");
778 tempLabel.setFont(boldFont);
779 p1.add(tempLabel);
780
781 wordField = new TextField(12);
782 wordField.setFont(boldFont);
783 p1.add(wordField);
784
785 Label temp2 = new Label(" ");
786 p1.add(temp2);
787
788 prevButton = new Button("Previous");
789 prevButton.setFont(boldFont);
790 prevButton.disable();
791
792 p1.add(prevButton);
793
794 nextButton = new Button(" Next ");
795 nextButton.setFont(boldFont);
796 nextButton.disable();
797 p1.add(nextButton);
798
799 }
800 }
801
802 // Button and field functionality
803
804 // Enable and disable the word field
805 void enableSearchButton() {
806 if (showControlPanel) {
807 searchButton.enable();
808 }
809 }
810 void disableSearchButton() {
811 if (showControlPanel) {
812 searchButton.disable();
813 }
814 }
815
816 // Get and set the search text in the wordField
817 String getSearchTerm() {
818 if (showControlPanel) {
819 return wordField.getText();
820 } else {
821 return initialSearch;
822 }
823 }
824 void setSearchTerm(String word) {
825 if (showControlPanel) {
826 wordField.setText(word);
827 }
828 }
829
830 // Enable or disable the "Previous" and "Next" buttons
831 void enablePreviousAndNext() {
832 if (showControlPanel) {
833 Component c = firstDisplay.current;
834 if (c.getClass().getName().endsWith("ResultBox")) {
835 if (((ResultBox) c).prevBoxExists()) {
836 prevButton.enable();
837 } else {
838 prevButton.disable();
839 }
840 }
841
842 c = lastDisplay.current;
843 if (c.getClass().getName().endsWith("ResultBox")) {
844 if (((ResultBox) c).nextBoxExists()) {
845 nextButton.enable();
846 } else {
847 nextButton.disable();
848 }
849 }
850 }
851 }
852
853 // Shift to previous box
854 //
855 // If the user clicks "Previous" then scroll up.
856 void shiftPrevious() {
857
858 Component c = firstDisplay.current;
859 if (c.getClass().getName().endsWith("ResultBox")) {
860
861 ResultBox b = (ResultBox) c;
862 if (b.prevBoxExists()) {
863 b = b.prev;
864
865 // empty all the displays
866 firstDisplay.emptyContents();
867
868 // add as many result boxes as there are displays
869 for (int i = 1 ; ((i <= depth) && (b != null)); i++) {
870 lastDisplay.display(b);
871 b.resize(b.display.size());
872 b.paintAll(b.getGraphics());
873 b = b.next;
874 }
875 }
876 }
877 enablePreviousAndNext();
878 }
879
880 // Shift to next box
881 //
882 // If the user clicks "Next" then scroll down if possible
883 void shiftNext() {
884
885 Component c = lastDisplay.current;
886 if (c.getClass().getName().endsWith("ResultBox")) {
887
888 ResultBox b = (ResultBox) c;
889 if (b.nextBoxExists()) {
890
891 // find the new "first" displayed box
892 c = firstDisplay.current;
893 b = (ResultBox) c;
894 b = b.next;
895
896 // empty all the displays
897 firstDisplay.emptyContents();
898
899 // add as many result boxes as there are displays
900 for (int i = 1 ; ((i <= depth) && (b != null)); i++) {
901 lastDisplay.display(b);
902 b.resize(b.display.size());
903 b.paintAll(b.getGraphics());
904 b = b.next;
905 }
906 }
907 }
908 enablePreviousAndNext();
909 }
910
911
912
913
914
915}
Note: See TracBrowser for help on using the repository browser.