B2 Interface Documentation

Laura Menke and Wendy Miller
August 1997

Contents

  • ReadMe.txt
  • B2Client
  • b2.class
  • StreamListener.class
  • b2Scenario.class
  • saveDeleteScenario.class
  • MiscInfo.class
  • messageFrame.class
  • B2Server
  • Introduction
  • Setting Pathnames
  • getDirectory() method
  • B2Server.class
  • Connection.class
  • LispListener.class


  • ReadMe.txt

    The B2 Interface and Server was created by Laura Menke and Wendy Miller during 
    the summer of 1997 at the University of Wisconsin-Milwaukee. For any 
    questions or comments please email: menke_ll@cslab.uwlax.edu or 
    wmiller@cornell-iowa.edu.
    
    To Install the B2 Interface and Server
    	1.  Unzip B2.zip in any directory. 
       		(NOTE: If you want the B2 software to be reached from a 
       		web site, create a directory for the B2 software in you 
       		public HTML directory.)
    	
    	2. You must change the path name in three places in the B2Server.java
    	   file. 
    		A. The first two places are at the top of the B2Server class
    		   The two lines of code are shown below.
    
    			String defaults = new String("C:\\InetPub\\wwwroot\\B2\\B2\\scenarioChoice.txt");
               	 	String directory = new String("C:\\InetPub\\wwwroot\\B2\\B2\\");
    		
    		B. The last path name that must be change is the path name to
    		   the Lisp program that works with the interface.
    		CHANGE!!
        			lisppr = lisprt.exec("E:\\Programs\\clisp-win32\\lisp.exe -q -M E:\\Programs\\sneps-2.3.1\\lispinit.mem -i C:\\InetPub\\wwwroot\\B2\\B2\\mmio.lisp");
    
    		YOU MUST RECOMPILE THE B2Server.java FILE!!!
    
    		C. The location of files for the lisp process must be
    		   changed in the file mmio.lisp in the B2 directory.
    			(defvar *path* "C:/InetPub/wwwroot/B2/Discourse-latest/")
    	
    To Run the B2 Interface and Server.:
    
    1. You must start the java Server.
    	A.) From a MS-dos window, you must be in the directory where you installed the B2 Interface.  
    	    Then at the promt type:> java B2Server
    	B.) From Windows, you can just double click on the startb2.bat file.
     	C.) From a Unix or Lynix, you must be in the directory where you installed the B2 Interface.
    	    Then at the promt type:> java B2Server
    
    Return to B2 Documentation Contents

    B2 Client Side Documentation

    1. Introduction

    2.  b2.class
        This class extends Applet. It creates a socket to communicate with the server.  It creates all the panels that contain all the GUI components. It handles the events of the components in this class. Below we will discuss the important methods of this class starting with the init() method.
        I. init() method
        To initialize the applet the method init() is called.  This is where the b2.class creates the socket to communicate with the server. Below is the section of code that creates the socket and grabs the input and output stream from the socket.  This is done  within a try/catch block to catch and exceptions.     Also within the try/catch block, the init() method creates three instances of b2Scenario objects; historyScenario, physicalScenario, and testScenario. It creates them within the try/catch block because the b2Scenario objects need to know what the socket's input and outstreams are so that it can communicate with the server and if an exception occurs.
       Next the init() method sets the layout of the applet to GridBagLayout.  It then calls three methods that create the main input panel of the b2 interface.  The methods are listed below with their descriptions.       The init() method then calls three more methods that create the Summary area of the B2 interface.  The methods and their description are listed below.
          Next the init()  method calls two methods that create  the Scenario area of the B2 interface.  The methods and their descriptions are listed below.
          Next the init() method create a panel that houses all of the b2Scenario objects and add the historyScenario object to it. Then the init() method calls the setPanelConstraints() method to set the constraints of all the panels and add them to the applet.
    Finally, the init() method creates a streamlistener object which will just loop while listening for input from the server.

       II. start() method
        The start() method is called after the b2 applet has been initialized, when a user comes back to the page after leaving, or after the user resizes the page.  In the B2 applet, we defined the start() method to send a message to the server requesting it to restart the Lisp process, only if the applet has been stopped by the stop() method. Besides having it send a message to the server, we also clear the two dialog areas and the identifier TextField.

     
        III. stop() method
        The stop() method is called every time the user leaves the page or the user resizes the page. In the B2 applet we define the stop() method to send a message to the server to stop the Lisp process. It also sets the stopped variable to true.
          IV. buildChoice() method
        The method buildChoice() sends a message to the server requesting information from a file whose name was passed to buildChoice() along with a Choice component.  The information in the file  will be the items for the choice component. The server will first send over the start flag "!!", to tell the buildChoice() method that the next items that will be coming over the stream will be the items to add to the Choice component.  The buildChoice() method will continue to loop and add Choice components until the server sends null. The purpose of this method is to add items to a new Choice component.  However, if this method is called for an existing choice component, then it will add more items to the existing list.     If the "!!" wasn't the first message from the server an error has occurred and a messageFrame object is created with an error message saying there was a error in tranferring data to the buildChoice() method..
        The contents of the Choice files that are use for dynamically adding items to the Choice components must be arranged in a certain form. each file must start with a "!!" on the first line.  Any item that you want to be added to  the choice component must be on it's own line. Do not included any blank spaces (at the end) or blank lines. If you would open up the file it would look something like the example below.
                            Example:       When the server side reads null, that is the end of file marker. The server  then sends  null to the client side. However when you send null to the client side, it must be treated as a string and tested for with  stringVariablename.equals("null").

         V. set_Constraints() method
        The method set_Constraints() method sets the contraints for the GridBagLayout and adds the items to their containers.
     
        VI. handleEvent() method
          The event-handling code in the B2 software is a single long switch statement within the handleEvent() method.  The handleEvent() method is invoked by the system when an event is generated. For example it can be anything from a keyPress to ACTION_EVENT.  You can find a list of the different types of events in the book Java in a Nutshell, ORielly & Associates, Inc..
            This is the area of the code that needs to be changed in the event of switching to Java 1.1.
            One case in the switch statement that is handled, is the ACTION_EVENT.   Buttons, choice, and checkboxes, all  generate ACTION_EVENT events.
            Another case in the switch statement is for KEY_PRESS events. When the user is in the dialog area and presses return, this event is captured and handled by the handleEvent() method. If either one of the cases in the switch statement handled the event the function will return true.  Otherwise the function will return false and then the operating system will take over and try to handle the event. Below are the events that we defined.
     

          VII. rebuildScenarioChoice() method
              This method is only called from within the StreamListener class. It removes the old scenarioChoice Choice component from the selectionPanel. Then it creates a new scenarioChoice component. The server sends rebuildScenarioChoice() the items to add to scenarioChoice.  Next it sets the constraints of scenarioChoice component and adds scenarioChoice to the selectionPanel.  Finally the validate() method is called on selectionPanel to update it in the applet. 3. StreamListener.class
         This class extends Thread.  Its job is to loop forever waiting for inputs from the server. Once it receives input, it checks to see if the input is one of the following cases and then does the described action.     This is the class that must be changed if to handle another token or flag from the server.

    4. b2Scenario.class
         This is a generic class that extends Panel.  It gets the information that it needs to create its components from the file that was passed to it in its constructor. Besides the file, b2Scenario is also passed: a connection to a b2 object, a string  that will be the title of the panel, and the input and output streams to communicate with the server.
        The b2Scenario() constructor first sets the layout of the b2Scenario panel to BorderLayout. Then it grabs all of the information that was passed to it. Next it creates the titlePanel Panel for the titleLabel.  Then it creates the titleLabel with the title it was passed and adds it to the titlePanel.  Next it creates the componentPanel to house all of the components that were created.  The componentPanel has a GridLayout layout and a Helvetica font. Next the callToServer() method is called.  Below is a description of the method callToServer() and important methods that callToServer() calls.
     

        Another important method is the submit() method.  This method gathers all of the information from all of the components and returns the information as a string in the form of a Lisp expression. First it loops through the textString[] and text[] arrays in parallel gathering the TextField information.  Then it loops through choiceString[]  and choice[] arrays in parallel gathering all the information from the Choice components. An example of the string that the submit() function returns is shown below.
                Example"      A string is passed to the submit() method and is used as a title for that section of information.  In this example, the string that was passed to submit() was "history".
      4. saveDeleteScenario.class
          This class is used for saving or deleting scenarios. It extends Frame.
           In addion to Labels, Choice, and TextArea components, this class creates an Okay Button and a Cancel Button. The Cancel Button, when clicked on, hides and disposes of the frame.  The Okay Button, when clicked on, checks whether the flag is equal to "Save" or "Delete" and sends the appropriate message  to the server in the form of a Lisp expression.  Below is the code for an Okay Button click.                     Example output to server: 5. MiscInfo.class
            This is a generic frame class that has a TextField for information input.  At creation you pass it a frame title, which is used for the frames flag, a message to tell the user what to do, and a message to label the TextField.  You also pass it the b2 object so that MiscInfo will have access to the servers input and output streams. This class also creates two Buttons: Okay and Cancel.  When the Okay Button is clicked, the frame does what the flag specifies it to.  An example of what types of flags are defined in this class is shown below.    As you can see the "Request" flag has not been defined yet. You may also define more flags in this section of code. After the flag has been handled, the frame is then  hidden and disposed of.  The Cancel Button hides and disposes of the frame.
     
    6. messageFrame.class
       

    This is a generic messageFrame class that extends frame.  When you create an instance of this class, you pass it a string that will be the title and then you pass it a string that will be the message.  This frame will automatically pack itself to fit the size of the message. It also creates an Okay button.  Below is the part of the constructor that shows the way you should pass the title and the message
                                                Example:
                                                                public messageFrame(String title, String message){
     
    When the user clicks on the Okay button,  the frame hides and disposes of itself.

    Return to B2Client Documentation Contents
    Return to B2 Documentation Contents

    B2 Server Documentation

    Contents

  • Introduction
  • Setting Pathnames
  • getDirectory() method
  • B2Server.class
  • Connection.class
  • LispListener.class

  • Introduction

    This documentation describes the implementation of the server side of the B2 front-end software. There are three main classes in the server side implementation.

    An important method included in two of the classes is getDirectory(). This method will be discussed first and then each class.

    In this implementation of a server, a lisp process is created for each client and communication is accomplished through streams.


    Setting Pathnames

    You may set pathnames by making two changes in the B2Server class. The lines occur early in the code and are marked by comments. The constant defaults is used to dynamically allocated the scenario choice box. It sets the default file which is to be read. The constant directory sets the pathname where all the file are located. The lines which you must modify are the following:

    	String defaults = new String("C:\\InetPub\\wwwroot\\B2\\B2\\scenarioChoice.txt");
    	String directory = new String("C:\\InetPub\\wwwroot\\B2\\B2\\");
    
    You will also need to make one change in the Connection class. The code occurs in the startLisp() method. Since the server starts up and communicates with a lisp process, you will need to change the directory of the lisp file which you will be running. The line looks similar to the following:
    	lisppr = lisprt.exec("C:\\InetPub\\wwwroot\\B2\\B2\\b2-run.bat");
    
    After you change the path name you must save and recompile B2Server.java.


    getDirectory()

    The getDirectory() method is responsible for setting the path names of all the files that are used by the server. To use this method you just pass it the file name and it attaches the directory to it. Currently, the code is set up to read the directory String constant which you can change in the B2Server class and is described in the section Setting Pathnames. Below is the getDirectory() method that is used in the classes B2Server and Connection.

    	private String getDirectory(String file) {
    	  // The line of code below is the path name that must be changed.
    	  StringBuffer filepath = new StringBuffer(directory);
    	  filepath.append(file);
    	  return filepath.toString();
    	}
    


    B2Server.class

    The server is a thread that uses the ServerSocket class to listen to a port. Once a connection is accepted, the server then creates a new socket object at a different port which will communicate with the client at that new port. The the ServerSocket will go back to listening for additional clients.

    The B2Server constructor is responsible for creating the ServerSocket at a given port. The thread is then started to allow the server to begin listening for connections.

    The main body of the server thread is the run() method. It loops forever, listening for and accepting connections from clients. For each connection, the server creates a connection object to handle communication through the new socket. The connection object is passed the new socket and the server.


    Connection.class

    The connection class is the thread that handles all communication with the client. Like the server, this class just listens at a given port for the client to do anything. Once the client speaks this thread takes and processes that information by either handling it itself to dynamically allocate the interface or sending it on for lisp to process.

    The connection constructor is responsible for starting the thread and calling the startLisp() method.

    The startLisp() method opens the streams which communicate with the client and the streams which communicate with lisp. It also is responsible for starting up the lisp process. The method waits to open the stream, a print stream, which sends data to lisp until after it has received the "*start*" token from lisp.

    The other task belonging to startLisp() is to start the lisplistener thread. The connection, data input stream from lisp, and the print stream to lisp are sent to the lisplistener constructor.

    The body of the connection class is the run() method. The run() method provides the service to the client. Like the server class' run() method, the connection class' run method continuously loops listening to a given port waiting for data from the client. Once the run() method receives a message from the client in the form of a string, it then processes that information. If the method reads the tokens "*component*", "*stop*", or "*start*", then it calls the appropriate method to handle the command. The token "*component*" initalizes a call to the openBuildComponents method, "*stop*" causes a call to the stopLisp() method, and "*start*" calls the startLisp() and openBuildComponents() methods. Everything else is sent to lisp using the sendToLisp() method.

    The sendToLisp method prints the line which is its parameter to the lisp process. A new line character is also printed and then the stream is flushed.

    The openBuildComponents() method sends the options for the choice interface. It opens a file and for each line, reads the line and sends it to the client, until the end of the file is reached.

    The last method in the connection class is stopList(). It calls openBuildComponents() to reload the default scenarios in the choice component of the interface. It stops the lisplistener thread and kill the lisp process.


    LispListener.class

    The LispListener class is the thread which handles the data which lisp sends to the client. Everything is sent to the client to handle, unless a token, "*selectscenario*" or "*default*", is received. If one of the two possible tokens are received then openBuildComponents() in the connection class is called.


    Return to B2Server Documentation Contents
    Return to B2 Documentation Contents