The CommandLineTuttle constructor is comparable to the other tuttle interface constructors, creating, configuring and installing an instance of the TextTuttle class, the CommandLineTuttleInterface class and a feedbackPanel into the interface. The ActionListener instance passed as an argument to the CommandLineTuttleInterface constructor is the instance of the CommandLineTuttle currently being initialised. Consequently this class has to implement the ActionListener interface and so an actionPerformed() method. The implementation of the class, presented without comment, as far as the end of its init() method, is as follows.
0001 // Filename CommandLineTuttle.java. 0002 // Supplies the command line translation for 0003 // the Tuttle class. 0004 // 0005 // Written for Java Interface book chapter 7. 0006 // Fintan Culwin, v 0.2, August 1997. 0007 0008 package CommandLineTuttle; 0009 0010 import java.awt.*; 0011 import java.awt.event.*; 0012 import java.applet.*; 0013 0014 import java.util.StringTokenizer; 0015 0016 import Tuttles.TextTuttle; 0017 import CommandLineTuttle.CommandLineTuttleInterface; 0018 0019 0020 public class CommandLineTuttle extends Applet 0021 implements ActionListener { 0022 0023 private TextTuttle theTuttle; 0024 private CommandLineTuttleInterface theInterface; 0025 0026 private Panel feedbackPanel; 0027 private Label feedbackLabel; 0028 0029 public void init() { 0030 0031 Panel tuttlePanel = new Panel(); 0032 0033 this.setLayout( new BorderLayout()); 0034 this.setFont( new Font( "TimesRoman", Font.BOLD, 14)); 0035 this.setBackground( Color.white); 0036 0037 theTuttle = new TextTuttle( this, 400, 400); 0038 tuttlePanel.add( theTuttle); 0039 0040 theInterface = new CommandLineTuttleInterface( this); 0041 0042 feedbackPanel = new Panel(); 0043 feedbackPanel.setBackground( Color.white); 0044 feedbackLabel = new Label(); 0045 feedbackPanel.add( feedbackLabel); 0046 0047 this.add( feedbackPanel, "North"); 0048 this.add( tuttlePanel, "Center"); 0049 this.add( theInterface, "South"); 0050 0051 this.feedback(); 0052 } // End init.
As this class has been registered as the actionListener attribute of the single line commandArea shown the user its' actionPerformed() method will be called every time the user presses the <ENTER> key in the command area of the interface. The actionCommand attribute of the event passed as an argument to the actionPerformed() method will contain the entire line of text from the commandArea.
The basis of the actionPerformed() method is to pass the command line, extracted from the ActionEvent argument of the method, to theTuttle instance. The method concludes by echoing the command, and any response received from theTuttle, in the feedback area before clearing the command area and updating the tuttle's feedback Panel. This outline is complicated by the need to process the help and exit commands separately. The implementation of the actionPerformed() method is as follows.
0055 public void actionPerformed( ActionEvent event) { 0056 0057 String theCommand = event.getActionCommand(); 0058 StringTokenizer tokenizer = new StringTokenizer( theCommand); 0059 String firstTerm = tokenizer.nextToken().toLowerCase(); 0060 String theResponse; 0061 0062 if ( firstTerm.equals( "help")) { 0063 theResponse = obtainHelp( tokenizer); 0064 } else if ( firstTerm.equals( "exit")) { 0065 theResponse = checkExit( tokenizer); 0066 } else { 0067 theResponse = theTuttle.doCommand( theCommand); 0068 } // End if 0069 0070 theInterface.appendFeedback( "\n> " + theCommand); 0071 if ( theResponse.length() > 0 ) { 0072 theInterface.appendFeedback("\n" + theResponse); 0073 } // End if. 0074 theInterface.clearCommandArea(); 0075 this.feedback(); 0076 } // End actionPerformed.
Lines 0057 to 0059 prepare a StringTokenizer instance, called tokenizer, initialized to parse the command extracted from the event argument, using its getActionCommand() method, and extracts the first term of the command into the local String firstTerm. Line 0060 declares a String instance called theResponse ready to receive any reply from theTuttle.
Lines 0062 and 0063 deal with a help command by using the obtainHelp() method which will be described below, likewise lines 0064 to 0065 deal with an exit command by using the checkExit() method. All other commands are passed to theTuttle on line 0067, by calling its' doCommand() method passing the entire command line retrieved from the event as its argument. As explained above the doCommand() method will attempt to interpret the command and, if it is valid, instruct the tuttle to obey it. If it cannot be interpreted as a valid tuttle command the doCommand() method will return an explanation which will be stored in theResponse.
Line 0070 echoes theCommand to the feedback area on theInterface, preceded by a chevron ('>'), by using its appendFeedback() method. Lines 0071 to 0073 follow this by the contents of theResponse, if any. The method concludes, on lines 0074 and 0075, by clearing the command area on theInterface, ready for the next command and updating the feedbackPanel as usual.
As indicated on Figure 7.5 the command "help" by itself will provide a list of recognized commands, "help" followed by one of the possible tuttle commands will provide specific help for that command and anything else will be reported as an unknown command with the further advice to try "help" by itself. The obtainHelp() method, implemented as follows, will be called from the actionPerformed() method when "help" is identified in the first term of the user's command, and will return a suitable response to be subsequently displayed in the text feedback area.
0090 private String obtainHelp( StringTokenizer tokenizer) { 0091 0092 StringBuffer theHelp = new StringBuffer( ""); 0093 String secondTerm; 0094 int helpFor; 0095 0096 if ( ! tokenizer.hasMoreTokens()) { 0097 theHelp.append( "help is available for fd, bd, tr, tl " + 0098 "fg bg pu pd cl rs cr and exit"); 0099 } else { 0100 secondTerm = tokenizer.nextToken().toLowerCase(); 0101 helpFor = theTuttle.identifyCommand( secondTerm); 0102 0103 switch ( helpFor) { 0104 case theTuttle.FORWARD: 0105 theHelp.append("fd is ForwarD, it must be followed by a number, " + 0106 "\nthe tuttle will move that many steps in its " + 0107 "current direction."); 0108 break; ---- // Other branches omitted. 0187 case theTuttle.UNKNOWN: 0188 theHelp.append("Sorry! The command '" + secondTerm + 0189 "' is not known \n Try 'help' by itself for " + 0190 "a list of commands which are known."); 0191 break; 0192 0193 } // End switch. 0194 } // End if. 0195 return theHelp.toString(); 0196 } // End obtainHelp.
The command "help" by itself will be detected on line 0096, by the absence of a second term in the StringTokenizer tokenizer argument, and causes a suitable message to be placed in theHelp StringBuffer on lines 0097 to 0098. Otherwise, on line 0100, the second term is extracted from the tokenizer and passed to the TextTuttle identifyCommand() method on line 0101. A fourteen way switch structure, starting on line 0103, contains a branch for each recognized command placing a suitable message for each into theHelp. The last branch of the switch structure, on lines 0187 to 0191, provides help if the second term of the command was not recognized by the TextTuttle as a valid command. The method concludes, on line 0195, by returning the String contained in theHelp.
Figure 7.5 illustrates the operation of this method. The "help fd" command was typed in by the user and the help obtained, from lines 0105 to 0107 of the obtainHelp() method, is shown following the command in the feedback area. This was followed by a "help me" request which causes the UNKNOWN branch to be taken and the resulting message is shown.
The remaining checkExit() method is somewhat similar and is implemented as follows.
0078 private String checkExit( StringTokenizer tokenizer) { 0079 if ( (tokenizer.countTokens() == 1) && 0080 (tokenizer.nextToken().toLowerCase().equals( "please")) ){ 0081 System.exit( 0); 0082 return ""; 0083 } else { 0084 return new String( "To exit from this application you have to " + 0085 "type 'exit', followed by 'please'!"); 0086 } // End if. 0087 } // End checkExit.
Lines 0079 and 0080 check to see if there is a second term following the exit command and, if so, if it is "please". Only if both these conditions are satisfied will the applet terminate on line 0081; a more complete applet might have to perform some housekeeping at this stage before exiting. Otherwise if the command was not given as exit please, on lines 0084 and 0085 advice on how to exit from the applet is returned to be displayed in theInterface's feedback area.
CommandLineTuttle.java
CommandLineTuttle
7.8 Evaluating the interfaces
7.6 The CommandLineTuttleInterface class