source: trunk/gsdl3/src/java/org/greenstone/applet/phind/Phind.java@ 3658

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

tried to get the applet working on Mozilla, Netscape, and IE. It works fine on all apart from the buttons. All buttons work in Netscape. Search works in IE, but not Mozilla. Previous and Next dont work in IE or Mozilla.
Had to compile with 1.3 instead of 1.4. Have also removed all the deprecated method calls.
phindcgi variable now prepends the library variable (assumes will always use it through greenstone)

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