
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;



public class MLP_Applet extends Applet implements Runnable, ActionListener {
    //private members

    //Threads
    Thread myThread;

    //panels
    private Panel ap0, ap1, ap2, ap3, ap4;
    private Panel p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
    private Panel p11, p12, p13, p14, p15, p16, p17;

    //frames
    private Frame mainFrame, paramFrame, featureFrame, targetFrame, valFrame;
    private Frame gFrame1, gFrame2, helpFrame;


    //labels
    private Label title1, title2, title3, title4;
    private Label l1, l2, l3, l4, l5, l6, l7;

    //buttons
    private Button MLP_Param;
    private Button testVec, trainVec, valVec;
    private Button Default_Param, submit, submit1, submit2, submit3;
    private Button train, test, validate, clear, errorStat;
    private Button param, graph1, graph2;
    private Button close1, close2, stopBtn, close3, clear1, clear2, clear3;

    //text fields
    private TextField tf1, tf2, tf3, tf4, tf5, tf6, tf7, tf8, tf9, tf10;
    private TextField tf11, tf12, tf13, tf14, tf15, tf16;

    //text area
    private TextArea featureArea, featureArea1, targetArea, targetArea1, errorArea;
    private TextArea valFeatureArea, valTargetArea, helpArea;

    //radio buttons
    private CheckboxGroup sigmoid, range;
    private Checkbox unipolar, bipolar, rmin, rmax;

    //Menu bars
    private MenuBar main, fmbar1, fmbar2, fmbar3, fmbar4;
    private Menu fileMenu, helpMenu, fm1, fm2, fm3, fm4, hm1, hm2, hm3, hm4;
    private MenuItem i1, i2, i3, i4, i4a, i5, i6, i7, i7a, i8, i9, i10, i11;
    private MenuItem i12, i13, i14, i15;

    //File dialogues
    private FileDialog fileLoader, fileSaver;



    //variables - strings
    private String N, M, J, Q, valQ, testQ, a1, a2, da1, da2, b1, b2, e1, e2, mu, num;
    private String featureVectors, featureVectors1, targetVectors, targetVectors1;
    private String valFeatureVectors, valTargetVectors;
    private String iteStr, errStr;

    //variables string tokenizers
    private StringTokenizer fv, fv1, tv, tv1, val1, val2;

    //variables boolean
    private boolean frozen, valFlag, grph1Flag, grph2Flag;


    //variables - integers
    private int vN, vM, vJ, vQ, vtestQ, vvalQ, vnum;
    private int iteration;


                 
    //variables - double
    private double va1, va2, vda1, vda2, vah, vb1, vb2, ve1, ve2, vmu;
    private double dgds, dhdr, sumW;
    private double oldErr, newErr, ssErr, oldValErr, newValErr, verErr;


    //variables - double arrays
    private double X[][], testX[][], valX[][], T[][], testT[][], valT[][];
    private double W[][], U[][], Y[][], testY[][], valY[][], Z[][], testZ[][], valZ[][];
    private double delW[][], ndelW[][], delU[][], ndelU[][];
    private double rSum[][], testrSum[][], valrSum[][], sSum[][], testsSum[][], valsSum[][];
    private double Err[], temp[], Zgrph[], Tgrph[];


    //graph instances
    Graph1 G1;
    Graph2 G2;
    Graphics grph1, grph2;


    //Graph vaiables
    String g1str1, g2str1;
    int g1px1, g2px1, g1px2, g2px2, g1py1, g2py1, g1py2, g2py2;
    int g1lastx, g1lasty, g2lastx, g2lasty;
    double g1ymax, g1ymin, g2ymax, g2ymin;

    //Get min and max x-axis( iterations )/y-axis ( error )
    double g1xmin, g2xmin;
    double g1xmax, g2xmax;
    double g2ymin1;
    double g2ymax1;
    double g2ymin2;
    double g2ymax2; 

    //determine x-axis tick marks
    double g1xtic1, g1xtic2, g1xtic3, g1xtic4;
    double g2xtic1, g2xtic2, g2xtic3, g2xtic4;


    //determine y-axis tick marks
    double g1ytic1, g1ytic2, g1ytic3, g1ytic4;
    double g2ytic1, g2ytic2, g2ytic3, g2ytic4;




  public void init() {
    

    valFlag = true;
    grph1Flag = false;
    grph2Flag = false;

    //Create a parent frame to hold applet widgets

    mainFrame = new Frame( "Welcome to my MLPs Applet" );
    mainFrame.setLayout( new FlowLayout() );

    //MENU stuff... for main frame
    main = new MenuBar();
    fileMenu = new Menu( "File" );
    helpMenu = new Menu( "Help" );

    i1 = new MenuItem( "Save" );
    fileMenu.add( i1 );
    i1.addActionListener( this );
    i2 = new MenuItem( "Quit" );
    fileMenu.add( i2 );
    i2.addActionListener( this );
    main.add( fileMenu );

    helpMenu = new Menu( "Help" );
    i3 = new MenuItem( "Using this applet" );
    helpMenu.add( i3 );
    i3.addActionListener( this );
    main.add( helpMenu );
    mainFrame.setMenuBar( main );

                 
    //Add a button for input parameters
    ap0 = new Panel();
    ap0.setLayout( new FlowLayout() );
    MLP_Param = new Button( "Input MLPs Parameters" );
    MLP_Param.addActionListener( this );
    ap0.add( MLP_Param );
    mainFrame.add( ap0 );


    //Add buttons for input vectors for training, testing, and validation
    ap1 = new Panel();
    ap1.setLayout( new FlowLayout() );
    trainVec = new Button( "Input Vectors for Training" );
    trainVec.addActionListener( this );
    ap1.add( trainVec );
    testVec = new Button( "Input Vectors for Testing" );
    testVec.addActionListener( this );
    ap1.add( testVec );
    valVec = new Button( "Input Vectors for Validation" );
    valVec.addActionListener( this );
    ap1.add( valVec );
    mainFrame.add( ap1 );

    //Add error text area in this applet panel
    ap2 = new Panel();
    ap2.setLayout( new FlowLayout() );
    errorArea = new TextArea();
    ap2.add( errorArea );
    mainFrame.add( ap2 );

    //Add training/testing/view  buttons in this applet panel
    ap3 = new Panel();
    ap3.setLayout( new FlowLayout() );
    train = new Button( "Start Training" );
    train.addActionListener( this );
    ap3.add( train );
    stopBtn = new Button( "Stop" );
    stopBtn.addActionListener( this );
    ap3.add( stopBtn );
    validate = new Button( "Validate NN" );
    validate.addActionListener( this );
    ap3.add( validate );
    test = new Button( "Start Testing" );
    test.addActionListener( this );
    ap3.add( test );
    errorStat = new Button( "View Error Statistics" );
    errorStat.addActionListener( this );
    ap3.add( errorStat );
    clear = new Button( "Refresh" );
    clear.addActionListener( this );
    ap3.add( clear );
    mainFrame.add( ap3 );


    //Add graph buttons here
    ap4 = new Panel();
    ap4.setLayout( new FlowLayout() );
    param = new Button( "View Learned Parameters" );
    param.addActionListener( this );
    ap4.add( param );
    graph1 = new Button( "View Error Graph" );
    graph1.addActionListener( this );
    ap4.add( graph1 );
    graph2 = new Button( "View Prediction Graph" );
    graph2.addActionListener( this );
    ap4.add( graph2 );
    mainFrame.add( ap4 );


    mainFrame.setSize( 530, 425 );
    mainFrame.setVisible( true );





    //Create a frame to hold input parameters
    paramFrame = new Frame( "MLPs Parameter" );
    paramFrame.setLayout( new GridLayout( 14, 1 ) );
    helpFrame = new Frame( "MLPs Parameter Help" );
    helpFrame.setLayout( new FlowLayout() );



    //Create a frame to hold feature and target vectors for training
    featureFrame = new Frame( "Input Vectors for Training" );
    featureFrame.setLayout( new GridLayout( 1, 1 ) );

    //Create a frame to hold feature and target vectors for testing
    targetFrame = new Frame( "Input Vectors for Testing" );
    targetFrame.setLayout( new GridLayout( 1, 1 ) );

    //Create a frame to hold feature and target vectors for testing
    valFrame = new Frame( "Input Vectors for Validation" );
    valFrame.setLayout( new GridLayout( 1, 1 ) );

    


    //Panel for N
    p1 = new Panel();
    p1.setLayout( new FlowLayout() );
    p1.add( new Label( "Number of Input Nodes ( N )         " ) );
    tf1 = new TextField( 3 );
    tf1.addActionListener( this );
    p1.add( tf1 );
    paramFrame.add( p1 );


    //Panel for M
    p2 = new Panel();
    p2.setLayout( new FlowLayout() );
    p2.add( new Label( "Number of Middle Neurodes ( M )" ) );
    tf2 = new TextField( 3 );
    tf2.addActionListener( this );
    p2.add( tf2 );
    paramFrame.add( p2 );

    //Panel for J
    p3 = new Panel();
    p3.setLayout( new FlowLayout() );
    p3.add( new Label( "Number of Output Neurodes ( J ) " ) );
    tf3 = new TextField( 3 );
    tf3.addActionListener( this );
    p3.add( tf3 );
    paramFrame.add( p3 );

    //Panel for Q
    p4 = new Panel();
    p4.setLayout( new FlowLayout() );
    p4.add( new Label( "Number of Exemplar Vectors ( Q )" ) );
    tf4 = new TextField( 3 );
    tf4.addActionListener( this );
    p4.add( tf4 );
    paramFrame.add( p4 );


    //Panel for sigmoid function label
    p5 = new Panel();
    p5.setLayout( new FlowLayout() );
    title1 = new Label( "Select one of the sigmoid functions" );
    title1.setFont( new Font( "TimesRoman", Font.BOLD, 14 ) );
    p5.add( title1 );
    paramFrame.add( "Center", p5 );


    //Panel for sigmoid function radio buttons
    p6 = new Panel();
    p6.setLayout( new FlowLayout() );
    sigmoid = new CheckboxGroup();
    unipolar = new Checkbox( "Unipolar Sigmoid", sigmoid, false );
    bipolar = new Checkbox( "Bipolar Sigmoid", sigmoid, false );
    p6.add( unipolar );
    p6.add( bipolar );
    paramFrame.add( "Center", p6 );

    //Panel for sigmoid parameters label
    p7 = new Panel();
    p7.setLayout( new FlowLayout() );
    title2 = new Label( "Sigmoid Parameters" );
    title2.setFont( new Font( "TimesRoman", Font.BOLD, 14 ) );
    p7.add( title2 );
    paramFrame.add( "Center", p7 );

    //Panel for sigmoid parameters alpha1, alpha2, and deltas
    p8 = new Panel();
    p8.setLayout( new FlowLayout() );
    p8.add( new Label( "alpha1" ) );
    tf5 = new TextField( 3 );
    tf5.addActionListener( this );
    p8.add( tf5 );
    p8.add( new Label( "delta_alpha1" ) );
    tf6 = new TextField( 3 );
    tf6.addActionListener( this );
    p8.add( tf6 );
    p8.add( new Label( "bias1 =    N/" ) );
    tf7 = new TextField( 3 );
    tf7.addActionListener( this );
    p8.add( tf7 );
    paramFrame.add( "Center", p8 );

    //Panel for sigmoid parameters bias1 and bias2
    p9 = new Panel();
    p9.setLayout( new FlowLayout() );
    p9.add( new Label( "alpha2" ) );
    tf8 = new TextField( 3 );
    tf8.addActionListener( this );
    p9.add( tf8 );
    p9.add( new Label( "delta_alpha2" ) );
    tf9 = new TextField( 3 );
    tf9.addActionListener( this );
    p9.add( tf9 );
    p9.add( new Label( "bias2 =    M/" ) );
    tf10 = new TextField( 3 );
    tf10.addActionListener( this );
    p9.add( tf10 );
    paramFrame.add( "Center", p9 );

    //Panel for step gain and momentum label
    p10 = new Panel();
    p10.setLayout( new FlowLayout() );
    title3 = new Label( "Step gain and momentum parameters" );
    title3.setFont( new Font( "TimesRoman", Font.BOLD, 14 ) );
    p10.add( title3 );
    paramFrame.add( "Center", p10 );

    //Panel for step gain and momentum parameters
    p11 = new Panel();
    p11.setLayout( new FlowLayout() );
    p11.add( new Label( "eta1" ) );
    tf11 = new TextField( 3 );
    tf11.addActionListener( this );
    p11.add( tf11 );
    p11.add( new Label( "eta2" ) );
    tf12 = new TextField( 3 );
    tf12.addActionListener( this );
    p11.add( tf12 );
    p11.add( new Label( "momentum" ) );
    tf13 = new TextField( 3 );
    tf13.addActionListener( this );
    p11.add( tf13 );
    paramFrame.add( "Center", p11 );

    //Panel for number of iterations
    p12 = new Panel();
    p12.setLayout( new FlowLayout() );
    title4 = new Label( "Number of Iterations" );
    title4.setFont( new Font( "TimesRoman", Font.BOLD, 14 ) );
    p12.add( title4 );
    tf14 = new TextField( 3 );
    tf14.addActionListener( this );
    p12.add( tf14 );
    paramFrame.add( "Center", p12 );


    //panel for default and previous parameter buttons
    p13 = new Panel();
    p13.setLayout( new FlowLayout() );
    Default_Param = new Button( "View Default Parameters" );
    Default_Param.addActionListener( this );
    p13.add( Default_Param );
    paramFrame.add( "Center", p13 );
    
    //panel for submit parameter button
    p14 = new Panel();
    p14.setLayout( new FlowLayout() );
    submit = new Button( "Submit" );
    submit.addActionListener( this );
    p14.add( submit );
    paramFrame.add( "Center", p14 );

    fmbar3 = new MenuBar();
    fm3 = new Menu( "File" );

    i10 = new MenuItem( "Close" );
    fm3.add( i10 );
    i10.addActionListener( this );
    fmbar3.add( fm3 );

    hm3 = new Menu( "Help" );
    i11 = new MenuItem( "Using this window" );
    hm3.add( i11 );
    i11.addActionListener( this );
    fmbar3.add( hm3 );
    paramFrame.setMenuBar( fmbar3 );



    //panel for feature/target vectors for training and submit1 button
    p15 = new Panel();
    p15.setLayout( new FlowLayout() );

    fmbar1 = new MenuBar();
    fm1 = new Menu( "File" );

    i4 = new MenuItem( "Feature Vectors" );
    fm1.add( i4 );
    i4.addActionListener( this );
    i4a = new MenuItem( "Target Vectors" );
    fm1.add( i4a );
    i4a.addActionListener( this );
    i5 = new MenuItem( "Close" );
    fm1.add( i5 );
    i5.addActionListener( this );
    fmbar1.add( fm1 );

    hm1 = new Menu( "Help" );
    i6 = new MenuItem( "Using this window" );
    hm1.add( i6 );
    i6.addActionListener( this );
    fmbar1.add( hm1 );
    featureFrame.setMenuBar( fmbar1 );


    // range = new CheckboxGroup();
    // rmin = new Checkbox( "Map data from 0.1 to 0.9", range, false );
    // rmax = new Checkbox( "Map data from -0.9 to 0.9", range, false );
    // p15.add( rmin );
    // p15.add( rmax );
    l1 = new Label( "Enter Input Feature and Target Vectors" );
    p15.add( l1 );
    featureArea = new TextArea();
    p15.add( featureArea );
    //l2 = new Label( "Enter Input Target Vectors" );
    //p15.add( l2 );
    featureArea1 = new TextArea();
    p15.add( featureArea1 );
    submit1 = new Button( "Submit Vectors for Training" );
    submit1.addActionListener( this );
    p15.add( submit1 );
    clear1 = new Button( "Clear" );
    clear1.addActionListener( this );
    p15.add( clear1 );
    featureFrame.add( "Center", p15 );

    //panel for target/feature vectors for testing and submit2 button
    p16 = new Panel();
    p16.setLayout( new FlowLayout() );

    fmbar2 = new MenuBar();
    fm2 = new Menu( "File" );

    i7 = new MenuItem( "Feature Vectors" );
    fm2.add( i7 );
    i7.addActionListener( this );
    i7a = new MenuItem( "Target Vectors" );
    fm2.add( i7a );
    i7a.addActionListener( this );
    i8 = new MenuItem( "Close" );
    fm2.add( i8 );
    i8.addActionListener( this );
    fmbar2.add( fm2 );

    hm2 = new Menu( "Help" );
    i9 = new MenuItem( "Using this window" );
    hm2.add( i9 );
    i9.addActionListener( this );
    fmbar2.add( hm2 );
    targetFrame.setMenuBar( fmbar2 );



    p16.add( new Label( "Enter Number of Exemplar Vectors ( Q )               " ) );
    tf15 = new TextField( 3 );
    tf15.addActionListener( this );
    p16.add( tf15 );
    l3 = new Label( "Enter Input Feature and Target Vectors" );
    p16.add( l3 );
    targetArea = new TextArea();
    p16.add( targetArea );
    //l4 = new Label( "Enter Input Target Vectors" );
    //p16.add( l4 );
    targetArea1 = new TextArea();
    p16.add( targetArea1 );
    submit2 = new Button( "Submit Vectors for Testing" );
    submit2.addActionListener( this );
    p16.add( submit2 );
    clear2 = new Button( "Clear" );
    clear2.addActionListener( this );
    p16.add( clear2 );
    targetFrame.add( "Center", p16 );


    //panel for target/feature vectors for validation and submit3 button
    p17 = new Panel();
    p17.setLayout( new FlowLayout() );

    fmbar4 = new MenuBar();
    fm4 = new Menu( "File" );

    i12 = new MenuItem( "Feature Vectors" );
    fm4.add( i12 );
    i12.addActionListener( this );
    i13 = new MenuItem( "Target Vectors" );
    fm4.add( i13 );
    i13.addActionListener( this );
    i14 = new MenuItem( "Close" );
    fm4.add( i14 );
    i14.addActionListener( this );
    fmbar4.add( fm4 );

    hm4 = new Menu( "Help" );
    i15 = new MenuItem( "Using this window" );
    hm4.add( i15 );
    i15.addActionListener( this );
    fmbar4.add( hm4 );
    valFrame.setMenuBar( fmbar4 );



    p17.add( new Label( "Enter Number of Exemplar Vectors ( Q )               " ) );
    tf16 = new TextField( 3 );
    tf16.addActionListener( this );
    p17.add( tf16 );
    l4 = new Label( "Enter Input Feature and Target Vectors" );
    p17.add( l4 );
    valFeatureArea = new TextArea();
    p17.add( valFeatureArea );
    valTargetArea = new TextArea();
    p17.add( valTargetArea );
    submit3 = new Button( "Submit Vectors for Validation" );
    submit3.addActionListener( this );
    p17.add( submit3 );
    clear3 = new Button( "Clear" );
    clear3.addActionListener( this );
    p17.add( clear3 );
    valFrame.add( "Center", p17 );

    //paramFrame help section
    helpArea = new TextArea();
    helpFrame.add( helpArea );
    close3 = new Button( "Close" );
    close3.addActionListener( this );
    helpFrame.add( close3 );

    //Graphs
    gFrame1 = new Frame( "Error Graph" );
    gFrame1.setLayout( new FlowLayout() );
    G1 = new Graph1( Color.lightGray, 350, 350 );                
    close1 = new Button( "Close" );
    close1.addActionListener( this );
    gFrame1.add( G1 );
    gFrame1.add( close1 );



    gFrame2 = new Frame( "Prediction Graph" );
    gFrame2.setLayout( new FlowLayout() );


    G2 = new Graph2( Color.lightGray, 350, 350 );
    close2 = new Button( "Close" );
    close2.addActionListener( this );
    gFrame2.add( G2 );
    gFrame2.add( close2 );


    

  }





  //Event Handling
  public void actionPerformed( ActionEvent event ) {
    if( event.getSource() == MLP_Param ){
        paramFrame.setSize( 475, 475 );
        paramFrame.setVisible( true );
    }
    else if( event.getSource() == i10 ){

        paramFrame.setVisible( false );
    }
    else if( event.getSource() == i11 ){

        //Display help on using paramFrame
        helpFrame.setSize( 475, 275 );
        helpFrame.setVisible( true );

        paramFrameHelp();
    }
    else if( event.getSource() == close3 ){

        helpFrame.setVisible( false );
    }
    else if( event.getSource() == clear1 ){

        featureArea.setText( "" );
        featureArea1.setText( "" );
    }
    else if( event.getSource() == clear2 ){

        targetArea.setText( "" );
        targetArea1.setText( "" );
    }
    else if( event.getSource() == clear3 ){

        valFeatureArea.setText( "" );
        valTargetArea.setText( "" );
    }
    else if( event.getSource() == i1 ){

        try{
                fileSaver = new FileDialog( mainFrame, "Browse", FileDialog.SAVE );
                fileSaver.show();
                saveFile( fileSaver.getFile() );

        } catch( SecurityException se3 ){

            errorArea.setText( "Sorry Could open file dialog box. You may want to copy\nthe text area content and paste it in a text file.\n" + se3 );
          

        }


    }
    else if( event.getSource() == i2 )
    {
        mainFrame.setVisible( false );
    }
    else if( event.getSource() == i3 ){
        
        //Display help using this applet
        MainHelp();

    }
    else if( event.getSource() == i4 ){

        try{
                fileLoader = new FileDialog( mainFrame, "Browse", FileDialog.LOAD );
                fileLoader.show();
                loadFile( fileLoader.getFile(), "i4" );

        } catch( SecurityException se4 ){

            errorArea.setText( "Sorry Could open file dialog box. You may want to copy the\nfeature vectors for training and paste it in the text area.\n" + se4 );
          

        }


    }
    else if( event.getSource() == i4a ){

        try{

                fileLoader = new FileDialog( mainFrame, "Browse", FileDialog.LOAD );
                fileLoader.show();
                loadFile( fileLoader.getFile(), "i4a" );

        } catch( SecurityException se5 ){

            errorArea.setText( "Sorry Could open file dialog box. You may want to copy the\ntarget vectors for training and paste it in the text area.\n" + se5 );
        

        }
        


    }

    else if( event.getSource() == i5 ){

        featureFrame.setVisible( false );

    }
    else if( event.getSource() == i6 ){

        //Display help using featureFrame ( training vectors )
        trainVecHelp();

    }
    else if( event.getSource() == i7 ){

         try{

                fileLoader = new FileDialog( mainFrame, "Browse", FileDialog.LOAD );
                fileLoader.show();
                loadFile( fileLoader.getFile(), "i7" );

        } catch( SecurityException se6 ){

            errorArea.setText( "Sorry Could open file dialog box. You may want to copy the\nfeature vectors for testing and paste it in the text area.\n" + se6 );
       

        }


    }
    else if( event.getSource() == i7a ){


        try{

                fileLoader = new FileDialog( mainFrame, "Browse", FileDialog.LOAD );
                fileLoader.show();
                loadFile( fileLoader.getFile(), "i7a" );

        } catch( SecurityException se7 ){

            errorArea.setText( "Sorry Could open file dialog box. You may want to copy the\ntarget vectors for testing and paste it in the text area.\n" + se7 );
          

        }


    }

    else if( event.getSource() == i8 ){

         targetFrame.setVisible( false );

    }
    else if( event.getSource() == i9 ){

         //Display help using targetFrame ( testing vectors )
         testVecHelp();

    }
    else if( event.getSource() == i12 ){


        try{

                fileLoader = new FileDialog( mainFrame, "Browse", FileDialog.LOAD );
                fileLoader.show();
                loadFile( fileLoader.getFile(), "i12" );

        } catch( SecurityException se8 ){

            errorArea.setText( "Sorry Could open file dialog box. You may want to copy the\nfeature vectors for validation and paste it in the text area.\n" + se8 );
         

        }

    }
    else if( event.getSource() == i13 ){


        try{

                fileLoader = new FileDialog( mainFrame, "Browse", FileDialog.LOAD );
                fileLoader.show();
                loadFile( fileLoader.getFile(), "i13" );

        } catch( SecurityException se9 ){

            errorArea.setText( "Sorry Could open file dialog box. You may want to copy the\ntarget vectors for validation and paste it in the text area.\n" + se9 );
   

        }

    }
    else if( event.getSource() == i14 ){

        valFrame.setVisible( false );

    }
    else if( event.getSource() == i15 ){

        //Display help using valFrame ( validation vectors )
        valVecHelp();

    }
    else if( event.getSource() == Default_Param )
    {
        tf1.setText( "" );
        tf2.setText( "" );
        tf3.setText( "" );
        tf4.setText( "" );
        sigmoid.setSelectedCheckbox( unipolar );
        tf5.setText( "1.82" );
        tf6.setText( "0.04" );
        tf7.setText( "2.0" );
        tf8.setText( "1.82" );
        tf9.setText( "0.04" );
        tf10.setText( "2.0" );
        tf11.setText( "0.6" );
        tf12.setText( "1.0" );
        tf13.setText( "0.1" );
        tf14.setText( "" );
    }
    else if( event.getSource() == submit ){

      try{

        N = tf1.getText();
        M = tf2.getText();
        J = tf3.getText();
        Q = tf4.getText();
        a1 = tf5.getText();
        da1 = tf6.getText();
        b1 = tf7.getText();
        a2 = tf8.getText();
        da2 = tf9.getText();
        b2 = tf10.getText();
        e1 = tf11.getText();
        e2 = tf12.getText();
        mu = tf13.getText();
        num = tf14.getText();
        

        vN = Integer.valueOf( N ).intValue();
        vM = Integer.valueOf( M ).intValue();
        vJ = Integer.valueOf( J ).intValue();
        vQ = Integer.valueOf( Q ).intValue();
        vnum = Integer.valueOf( num ).intValue();
        va1 = Double.valueOf( a1 ).doubleValue();
        va2 = Double.valueOf( a2 ).doubleValue();
        vda1 = Double.valueOf( da1 ).doubleValue();
        vda2 = Double.valueOf( da2 ).doubleValue();
        vb1 = (double)vN/( Double.valueOf( b1 ).doubleValue() );
        vb2 = (double)vM/( Double.valueOf( b2 ).doubleValue() );
        ve1 = Double.valueOf( e1 ).doubleValue();
        ve2 = Double.valueOf( e2 ).doubleValue();
        vmu = Double.valueOf( mu ).doubleValue();

        //allocate arrays for weights
        W = new double[vN][vM];
        delW = new double[vN][vM];
        ndelW = new double[vN][vM];

        U = new double[vM][vJ];
        delU = new double[vM][vJ];
        ndelW = new double[vM][vJ];

        rSum = new double[vQ][vM];
        sSum = new double[vQ][vJ];

        Y = new double[vQ][vM];
        Z = new double[vQ][vJ];

        Err = new double[vnum];
        temp = new double[vnum];


        paramFrame.setVisible( false );


      } catch ( NumberFormatException nfe ){

            errorArea.setText( "Sorry, you have entered an incorrect input:\n" + nfe );
      }

      
      try{
          if( unipolar == sigmoid.getSelectedCheckbox() ){
          }
          else if( bipolar == sigmoid.getSelectedCheckbox() ){
          }
          else
              throw new CheckBoxNotSelectedException( "Radio button not selected" );

      } catch( CheckBoxNotSelectedException cb1 ){

          errorArea.setText( "You must select a sigmoid function:\n" + cb1 );
      }




    }
    else if( event.getSource() == trainVec ){
        featureFrame.setSize( 475, 575 );
        featureFrame.setVisible( true );
    }
    else if( event.getSource() == valVec ){
        valFrame.setSize( 475, 575 );
        valFrame.setVisible( true );
    }
    else if( event.getSource() == submit1 ){

      try{

        if( ( vQ == 0 && vN == 0 && vJ == 0 ) )
            throw new ZeroInitializedDataException( "Input data missing" );

        featureVectors = featureArea.getText();
        fv = new StringTokenizer( featureVectors );
        X = new double[vQ][vN];



        //Scan the input feature vectors for training
        for( int i = 0; i < vQ; i++ ){
            for( int j = 0; j < vN; j++ ){
                X[i][j] = Double.valueOf( fv.nextToken() ).doubleValue();
            }
        }


        featureVectors1 = featureArea1.getText();
        fv1 = new StringTokenizer( featureVectors1 );
        T = new double[vQ][vJ];

        //Scan the input target vectors for training
        for( int i = 0; i < vQ; i++ ){
            for( int j = 0; j < vJ; j++ ){
                T[i][j] = Double.valueOf( fv1.nextToken() ).doubleValue();
            }
        }


        featureFrame.setVisible( false );

      } catch( NoSuchElementException nse1 ){

          errorArea.setText( "You must enter the input vectors for training:\n" + nse1 );

      } catch( ZeroInitializedDataException zide5 ){

          errorArea.setText( "You must either enter the input vectors for training:\nOr close the window and input the network parameters.:\n" + zide5 );
 

      } catch( NumberFormatException nfe5 ){

          errorArea.setText( "Sorry. Input format is incorrect:\n" + nfe5 );
      }

        
    }
    else if( event.getSource() == testVec ){
        targetFrame.setSize( 475, 575 );
        targetFrame.setVisible( true );
    }
    else if( event.getSource() == submit2 ){

      try{


        testQ = tf15.getText();
        vtestQ = Integer.valueOf( testQ ).intValue();

        if( vJ == 0 )
            throw new NoSuchElementException();


        targetVectors = targetArea.getText();
        tv = new StringTokenizer( targetVectors );
        testX = new double[vtestQ][vN];

        //Scan the input feature vectors for testing
        for( int i = 0; i < vtestQ; i++ ){
            for( int j = 0; j < vN; j++ ){
                testX[i][j] = Double.valueOf( tv.nextToken() ).doubleValue();
            }
        }

        targetVectors1 = targetArea1.getText();
        tv1 = new StringTokenizer( targetVectors1 );
        testT = new double[vtestQ][vJ];

        //Scan the input target vectors for testing
        for( int i = 0; i < vtestQ; i++ ){
            for( int j = 0; j < vJ; j++ ){
                testT[i][j] = Double.valueOf( tv1.nextToken() ).doubleValue();
            }
        }

        testrSum = new double[vtestQ][vM];
        testsSum = new double[vtestQ][vJ];

        testY = new double[vtestQ][vM];
        testZ = new double[vtestQ][vJ];
        
       
        targetFrame.setVisible( false );

      } catch( NoSuchElementException nse2 ){

          errorArea.setText( "You must enter the input vectors for testing:\nOr you have not entered all the network parameters:\n" + nse2 );
          

      } catch( NumberFormatException nfe6 ){

          errorArea.setText( "Sorry. Input format is incorrect:\n" + nfe6 );
      }


    }
    else if( event.getSource() == train ){

      try{

        if( vnum == 0 )
            throw new ZeroInitializedDataException( "No parameters entered to train the network" );

        frozen = true;
        iteration = 0;
        start();


      } catch( ZeroInitializedDataException zie3 ){

          errorArea.setText( "You must enter all the network parameters to train the network:\n" + zie3 );
      }
       

    }
    else if( event.getSource() == stopBtn ){
    
	frozen = false;
	stop();
    }
    else if( event.getSource() == clear ){

        //Clear the error text area
        errorArea.setText( "" );
    }
    else if( event.getSource() == errorStat ){

      try{

        double minErr = temp[0];
        double maxErr = temp[vnum-1];
        int minIte = 0;
        int maxIte = vnum - 1;
        boolean minFlag = true;
        boolean maxFlag = true;

        for( int i = 0; i < vnum; i++ ){

            if( ( minErr == Err[i] ) && minFlag ){
                minIte = i;
                minIte++;
                minFlag = false;
            }

            if( ( maxErr == Err[i] ) && maxFlag ){
                maxIte = i;
                maxIte++;
                maxFlag = false;
            }

        }

        errorArea.append( "MAXIMUM Total Errors at Iteration = " );
        errorArea.append( iteStr.valueOf( maxIte ) );
        errorArea.append( ":\n" );
        errorArea.append( "Sum-Squared Error            " );
        errorArea.append( errStr.valueOf( maxErr ) );
        errorArea.append( "\n" );
        errorArea.append( "Root Sum-Squared Error     " );
        errorArea.append( errStr.valueOf( Math.sqrt( maxErr ) ) );
        errorArea.append( "\n" );
        errorArea.append( "Mean-Squared Error           " );
        errorArea.append( errStr.valueOf( maxErr/(double)vQ ) );
        errorArea.append( "\n" );
        errorArea.append( "Root Mean-Squared Error    " );
        errorArea.append( errStr.valueOf( Math.sqrt( maxErr/(double)vQ ) ) );
        errorArea.append( "\n\n" );

        errorArea.append( "MINIMUM Total Errors at Iteration = " );
        errorArea.append( iteStr.valueOf( minIte ) );
        errorArea.append( ":\n" );
        errorArea.append( "Sum-Squared Error            " );
        errorArea.append( errStr.valueOf( minErr ) );
        errorArea.append( "\n" );
        errorArea.append( "Root Sum-Squared Error     " );
        errorArea.append( errStr.valueOf( Math.sqrt( minErr ) ) );
        errorArea.append( "\n" );
        errorArea.append( "Mean-Squared Error           " );
        errorArea.append( errStr.valueOf( minErr/(double)vQ ) );
        errorArea.append( "\n" );
        errorArea.append( "Root Mean-Squared Error    " );
        errorArea.append( errStr.valueOf( Math.sqrt( minErr/(double)vQ ) ) );
        errorArea.append( "\n\n" );

      } catch( NullPointerException np2 ){

          errorArea.setText( "There are no errors to report:\n" + np2 );
      }



    }
    else if( event.getSource() == param ){

      try{

        if( (va1 == 0 ) || (va2 == 0 ) )
            throw new ZeroInitializedDataException( "No learned parameters available" );

        errorArea.append( "Exponential Rates:\n" );
        errorArea.append( "alpha1:      " );
        errorArea.append( iteStr.valueOf( va1 ) );
        errorArea.append( "     alpha2:      " );
        errorArea.append( iteStr.valueOf( va2 ) );
        errorArea.append( "\n\n" );

        errorArea.append( "Learning Rates:\n" );
        errorArea.append( "eta1:      " );
        errorArea.append( iteStr.valueOf( ve1 ) );
        errorArea.append( "     eta2:      " );
        errorArea.append( iteStr.valueOf( ve2 ) );
        errorArea.append( "\n\n" );

        if( unipolar == sigmoid.getSelectedCheckbox() ){

            errorArea.append( "Biases:\n" );
            errorArea.append( "bias1:      " );
            errorArea.append( iteStr.valueOf( vb1 ) );
            errorArea.append( "         bias2:      " );
            errorArea.append( iteStr.valueOf( vb2 ) );
            errorArea.append( "\n\n" );
        }

        errorArea.append( "Learned weights for middle neurodes ( Wnm ):\n" );

        for( int i = 0; i < vN; i++ ){
            for( int j = 0; j < vM; j++ ){
                errorArea.append( iteStr.valueOf( W[i][j] ) );
                errorArea.append( " " );
            }
            errorArea.append( "\n" );

        }

        errorArea.append( "\n" );

        errorArea.append( "Learned weights for output neurodes ( Umj ):\n" );

        for( int i = 0; i < vM; i++ ){
            for( int j = 0; j < vJ; j++ ){
                errorArea.append( iteStr.valueOf( U[i][j] ) );
                errorArea.append( " " );
            }
            errorArea.append( "\n" );

        }

      } catch( ZeroInitializedDataException zid2 ){

          errorArea.setText( "The network has no learned parameters at this time:\n" + zid2 );
      }


    }
    else if( event.getSource() == test ){

      try{

        verErr = TestPredict_NN();

        //Display target and predicted vectors
        errorArea.append( "Target output        " );
        errorArea.append( "Predicted output\n" );

        errorArea.append( "----------------------------------------\n" );


        for( int i = 0; i < vtestQ; i++ ){
            for( int j = 0; j < vJ; j++ ){
                errorArea.append( iteStr.valueOf( testT[i][j] ) );
                errorArea.append( "     " );
                errorArea.append( iteStr.valueOf( testZ[i][j] ) );
                errorArea.append( "\n" );
            }

            errorArea.append( "----------------------------------------\n" );
        }                

        errorArea.append( "\n" );
        errorArea.append( "Mean-Square Errors:\n" );
        errorArea.append( "Error on the last training iteration         " );
        errorArea.append( iteStr.valueOf( Err[vnum-1]/(double)vQ ) );
        errorArea.append( "\n" );
        errorArea.append( "Error in the testing phase         " );
        errorArea.append( iteStr.valueOf( verErr/(double)vtestQ ) );
        errorArea.append( "\n\n" );


        if( ( verErr/(double)vtestQ ) <  2.0*( Err[vnum-1]/(double)vQ ) )
            errorArea.append( "Training of the network is acceptable\n" );
        else
            errorArea.append( "Training of the network is NOT acceptable\n" );

	Zgrph = new double[vtestQ];
	Tgrph = new double[vtestQ];
	
	//Sort the temporary arrays Zgrph and Tgrph
	for( int i = 0; i < vtestQ; i++ ){
		for( int j = 0; j < vJ; j++ ){
            		Zgrph[i] = testZ[i][j];
	    		Tgrph[i] = testT[i][j];
		}
	}

	QuickSort( Zgrph, 0, ( vtestQ - 1 ) );
	QuickSort( Tgrph, 0, ( vtestQ - 1 ) );

        G2Init();



      } catch( NullPointerException np3 ){

          errorArea.setText( "You must first train the network to test it:\n" + np3 );
      }



    }
    else if( event.getSource() == submit3 ){

      try{


        valQ = tf16.getText();
        vvalQ = Integer.valueOf( valQ ).intValue();

        if( vJ == 0 )
            throw new NoSuchElementException();


        valFeatureVectors = valFeatureArea.getText();
        val1 = new StringTokenizer( valFeatureVectors );
        valX = new double[vvalQ][vN];

        //Scan the input feature vectors for testing
        for( int i = 0; i < vvalQ; i++ ){
            for( int j = 0; j < vN; j++ ){
                valX[i][j] = Double.valueOf( val1.nextToken() ).doubleValue();
            }
        }

        valTargetVectors = valTargetArea.getText();
        val2 = new StringTokenizer( valTargetVectors );
        valT = new double[vvalQ][vJ];

        //Scan the input target vectors for testing
        for( int i = 0; i < vvalQ; i++ ){
            for( int j = 0; j < vJ; j++ ){
                valT[i][j] = Double.valueOf( val2.nextToken() ).doubleValue();
            }
        }

        valrSum = new double[vvalQ][vM];
        valsSum = new double[vvalQ][vJ];

        valY = new double[vvalQ][vM];
        valZ = new double[vvalQ][vJ];
        
       
        valFrame.setVisible( false );

      } catch( NoSuchElementException nse3 ){

          errorArea.setText( "You must enter the input vectors for validation:\nOr you have not entered all the network parameters:\n" + nse3 );          

      } catch( NumberFormatException nfe7 ){

          errorArea.setText( "Sorry. Input format is incorrect:\n" + nfe7 );
      }


    }
    else if( event.getSource() == validate ){

      try{

        if( ( oldValErr == 0.0 ) || ( newValErr == 0.0 ) )
            throw new ZeroInitializedDataException( "No validation error data available" );

        if( valFlag ){

            oldValErr = ValidatePredict_NN();
            newValErr = oldValErr;
            valFlag = false;
        }
        else
            newValErr = ValidatePredict_NN();

        //Display old and new validation errors
        errorArea.append( "Total Sum-Squared Errors for Validation:\n" );
        errorArea.append( "Previous Error       " );
        errorArea.append( iteStr.valueOf( oldValErr ) );
        errorArea.append( "\n" );
        errorArea.append( "Current Error       " );
        errorArea.append( iteStr.valueOf( newValErr ) );
        errorArea.append( "\n\n" );


        if( newValErr <= oldValErr )
            errorArea.append( "Must continue training the network\n" );
        else
            errorArea.append( "The network is ready for testing\n" );

      } catch( ZeroInitializedDataException zid1 ){

          errorArea.setText( "You must first train the network in order to perform validation:\n" + zid1 );
      }
      

          
    }
    else if( event.getSource() == graph1 ){

      try{

        if( vnum == 0 )
            throw new NullPointerException();

        gFrame1.setSize( 400, 450 );
        gFrame1.setVisible( true );

      } catch( NullPointerException np8 ){

          errorArea.setText( "Data not available to draw the Error Graph:\n" + np8 );
      }


    }
    else if( event.getSource() == close1 ){

        gFrame1.setVisible( false );
    }
    else if( event.getSource() == graph2 ){

      try{

        if( vtestQ == 0 )
            throw new NullPointerException();


        gFrame2.setSize( 400, 450 );
        gFrame2.setVisible( true );

      } catch( NullPointerException np5 ){

          errorArea.setText( "Data not available to draw the Prediction Graph:\n" + np5 );
      }


    }
    else if( event.getSource() == close2 ){

        gFrame2.setVisible( false );
    }


   
  }//END Event handling
        

  public void paint( Graphics g ) {

      

  }





  //NN training methods ----

  public void InitializeWeights(){

      //Local variables
      double beta;
            
      //initialize weights between 0.1 and 0.9 for unipolar sigmoid
      //initialize weights between -0.9 and 0.9 for bipolar sigmoid
      for( int i = 0; i < vN; i++ ){
          for( int j = 0; j < vM; j++ ){

              if( unipolar == sigmoid.getSelectedCheckbox() )
                  W[i][j] = ( Math.random() )*0.8 + 0.1;
              else
                  W[i][j] = ( Math.random() )*1.8 - 0.9; 

              //sum weights at hidden neurodes
              sumW = sumW + W[i][j];

          }
      }

      for( int i = 0; i < vM; i++ ){
          for( int j = 0; j < vJ; j++ ){

              if( unipolar == sigmoid.getSelectedCheckbox() )
                  U[i][j] = ( Math.random() )*0.8 + 0.1;
              else
                  U[i][j] = ( Math.random() )*1.8 - 0.9; 

              //Russo adjustment of initial weights
                U[i][j] = U[i][j]*( 2.4/(double)vM );
          }
      }

      //compute Nguyen-Widrow factor
      beta = ( 0.7*( Math.exp( (Math.log((double)vM))/((double)vN) ) ) )/sumW;

      //Nguyen-Widrow adjustment
      for( int i = 0; i < vN; i++ ){
          for( int j = 0; j < vM; j++ ){
              W[i][j] = beta*W[i][j];
          }
      }

      //compute new SSE, MLP outputs
      oldErr = Update_NN();

      //make the first time flag false
      //initFlag = false;


  } //END InitializeWeights()         
         




  public void AdjustWeights(){

      //Local variables
      double umjSum, wnmSum;

      for( int i = 0; i < vM; i++ ){
          for( int j = 0; j < vJ; j++ ){
              umjSum = 0.0;
              for( int k = 0; k < vQ; k++ ){
                  if( unipolar == sigmoid.getSelectedCheckbox() )
                      dgds = va2*Z[k][j]*( 1.0 - Z[k][j] );
                  else
                      dgds = ( va2*( 1.0 + Z[k][j] )*( 1.0 - Z[k][j] ) )/2.0;

                  if( dgds < 0.1 )
                      dgds = 0.1;
                  umjSum = umjSum + ( T[k][j] - Z[k][j] )*dgds*Y[k][i];
              }

              delU[i][j] = ve2*umjSum;

              U[i][j] = U[i][j] + delU[i][j];
          }
      }

      newErr = Update_NN();

      StepGain_Adjust( ve2, true );


      for( int i = 0; i < vN; i++ ){
          for( int j = 0; j < vM; j++ ){
              wnmSum = 0.0;
              for( int k = 0; k < vQ; k++ ){
                  for( int l = 0; l < vJ; l++ ){
                      if( unipolar == sigmoid.getSelectedCheckbox() )
                          dhdr = va1*Y[k][j]*( 1.0 - Y[k][j] );
                      else
                          dhdr = ( va1*( 1.0 + Y[k][j] )*( 1.0 - Y[k][j] ) )/2.0;

                      if( dhdr < 0.1 )
                          dhdr = 0.1;
                      wnmSum = wnmSum + ( T[k][l] - Z[k][l] )*dhdr*U[j][l]*dgds*X[k][i];
                  }
              }

              delW[i][j] = ve1*wnmSum;

              W[i][j] = W[i][j] + delW[i][j];
          }
      }

      newErr = Update_NN();

      StepGain_Adjust( ve1, false );


  }//END AdjustWeights()





  public double Update_NN(){

      for( int i = 0; i < vQ; i++ ){
          for( int j = 0; j < vM; j++ ){
              rSum[i][j] = 0.0;
              for( int k = 0; k < vN; k++ ){
                  rSum[i][j] = rSum[i][j] + W[k][j]*X[i][k];
              }

              if( unipolar == sigmoid.getSelectedCheckbox() )
                  Y[i][j] = 1.0/( 1.0 + Math.exp( ( -va1*rSum[i][j] + vb1 ) ) );
              else
                  Y[i][j] = ( 1.0 + Math.exp( -va1*rSum[i][j] ) )/( 1.0 - Math.exp( -va1*rSum[i][j] ) );
          }

          for( int l = 0; l < vJ; l++ ){
              sSum[i][l] = 0.0;
              for( int m = 0; m < vM; m++ ){
                  sSum[i][l] = sSum[i][l] + U[m][l]*Y[i][m];
              }

              if( unipolar == sigmoid.getSelectedCheckbox() )
                  Z[i][l] = 1.0/( 1.0 + Math.exp( ( -va2*sSum[i][l] + vb2 ) ) );
              else
                  Z[i][l] = ( 1.0 + Math.exp( -va2*sSum[i][l] ) )/( 1.0 - Math.exp( -va2*sSum[i][l] ) );
          }
      }

      ssErr = 0.0;

      for( int i = 0; i < vQ; i++ ){
          for( int j = 0; j < vJ; j++ ){
              ssErr = ssErr + ( T[i][j] - Z[i][j] )*( T[i][j] - Z[i][j] );
          }
      }

      return ssErr;
      

  }//END Update_NN()




  public void StepGain_Adjust( double eta, boolean key ){

      if( newErr < oldErr )
          eta = 1.024*eta;
      else
          eta = 0.92*eta;

      if( key )
          ve2 = eta;
      else
          ve1 = eta;

  }//END StepGain_Adjust()




  public void AdjustAlphas(){

        if( ( iteration%5 == 0 ) && ( iteration < vnum/2 ) )
        {
            vah = va1;
            va1 = va1 + vda1;
        }

        newErr = Update_NN();

        if( newErr < oldErr )
        {
            oldErr = newErr;
            vda1 = vda1*1.1;
        }
        else
        {
            va1 = vah - vda1;
        }

        newErr = Update_NN();

        if( newErr < oldErr )
        {
            oldErr = newErr;
            vda1 = vda1*1.1;
        }
        else
        {
            va1 = vah;
            vda1 = vda1*0.9;
        }

        vah = va2;
        va2 = va2 + vda2;

        newErr = Update_NN();

        if( newErr < oldErr )
        {
            oldErr = newErr;
            vda2 = vda2*1.1;
        }
        else
        {
            va2 = vah - vda2;
        }

        newErr = Update_NN();

        if( newErr < oldErr )
        {
            oldErr = newErr;
            vda2 = vda2*1.1;
        }
        else
        {
            va2 = vah;
            vda2 = vda2*0.9;
        }

  }//END AdjustAlphas()





  public void QuickSort( double temp1[], int p, int r ){

      if( p < r ){
          int q = Split( temp1, p, r );
          QuickSort( temp1, p, q );
          QuickSort( temp1, q+1, r );
      }

  }//END QuickSort

  public int Split( double temp1[], int p, int r ){

      double x = temp1[p];
      int i = p - 1;
      int j = r + 1;

      while( i < j ){
          j = j - 1;
          while( temp1[j] > x ){
              j = j - 1;
          }
          i = i + 1;
          while( temp1[i] < x ){
              i = i + 1;
          }
          if( i < j ){
              double tmp = temp1[j];
              temp1[j] = temp1[i];
              temp1[i] = tmp;
          }
          else
              return j;
      }
      return i;

  }//END Split




  public void loadFile( String filename, String flag ) throws SecurityException{

      try{
          File file = new File( filename );

          FileInputStream in = new FileInputStream( file );
          int fileLen = (int)file.length();
          byte[] fileContent = new byte[ fileLen ];
          in.read( fileContent );

          String fileContentStr = new String( fileContent );

          if( flag.equals( "i4" ) )
              featureArea.setText( fileContentStr );
          else if( flag.equals( "i4a" ) )
              featureArea1.setText( fileContentStr );
          else if( flag.equals( "i7" ) )
              targetArea.setText( fileContentStr );
          else if( flag.equals( "i7a" ) )
              targetArea1.setText( fileContentStr );
          else if( flag.equals( "i12" ) )
              valFeatureArea.setText( fileContentStr );
          else
              valTargetArea.setText( fileContentStr );

              

      } catch( IOException ioe1 ){

             if( flag.equals( "i4" ) )
                 featureArea.setText( "File IOError: " + ioe1 );
             else if( flag.equals( "i4a" ) )
                 featureArea1.setText( "File IOError: " + ioe1 );
             else if( flag.equals( "i7" ) )
                 targetArea.setText( "File IOError: " + ioe1 );
             else if( flag.equals( "i7a" ) )
                 targetArea1.setText( "File IOError: " + ioe1 );
             else if( flag.equals( "i12" ) )
                 valFeatureArea.setText( "File IOError: " + ioe1 );
             else
                 valTargetArea.setText( "File IOError: " + ioe1 );




      } catch( SecurityException se1 ){

             if( flag.equals( "i4" ) )
                 featureArea.setText( "Sorry Could not open file..." + filename + ": " + se1 );
             else if( flag.equals( "i4a" ) )
                 featureArea1.setText( "Sorry Could not open file..." + filename + ": " + se1 );
             else if( flag.equals( "i7" ) )
                 targetArea.setText( "Sorry Could not open file..." + filename + ": " + se1 );
             else if( flag.equals( "i7a" ) )
                 valFeatureArea.setText( "Sorry Could not open file..." + filename + ": " + se1 );
             else
                 valTargetArea.setText( "Sorry Could not open file..." + filename + ": " + se1 );



      }



  }


  public void saveFile( String filename ) throws SecurityException{

      try{
          File file = new File( filename );

          FileOutputStream out = new FileOutputStream( file );

          byte[] fileContent = errorArea.getText().getBytes();
          out.write( fileContent );

      } catch( IOException ioe2 ){

            errorArea.setText( "File IOError: " + ioe2 );

      } catch( SecurityException se2 ){

            errorArea.setText( "Sorry Could not save file..." + filename + ": " + se2 );
      }


  }



  public double TestPredict_NN(){

      for( int i = 0; i < vtestQ; i++ ){
          for( int j = 0; j < vM; j++ ){
              testrSum[i][j] = 0.0;
              for( int k = 0; k < vN; k++ ){
                  testrSum[i][j] = testrSum[i][j] + W[k][j]*testX[i][k];
              }

              if( unipolar == sigmoid.getSelectedCheckbox() )
                  testY[i][j] = 1.0/( 1.0 + Math.exp( ( -va1*testrSum[i][j] + vb1 ) ) );
              else
                  testY[i][j] = ( 1.0 + Math.exp( -va1*testrSum[i][j] ) )/( 1.0 - Math.exp( -va1*testrSum[i][j] ) );
          }

          for( int l = 0; l < vJ; l++ ){
              testsSum[i][l] = 0.0;
              for( int m = 0; m < vM; m++ ){
                  testsSum[i][l] = testsSum[i][l] + U[m][l]*testY[i][m];
              }

              if( unipolar == sigmoid.getSelectedCheckbox() )
                  testZ[i][l] = 1.0/( 1.0 + Math.exp( ( -va2*testsSum[i][l] + vb2 ) ) );
              else
                  testZ[i][l] = ( 1.0 + Math.exp( -va2*testsSum[i][l] ) )/( 1.0 - Math.exp( -va2*testsSum[i][l] ) );
          }
      }

      ssErr = 0.0;

      for( int i = 0; i < vtestQ; i++ ){
          for( int j = 0; j < vJ; j++ ){
              ssErr = ssErr + ( testT[i][j] - testZ[i][j] )*( testT[i][j] - testZ[i][j] );
          }
      }

      return ssErr;



  }//END TestPredict_NN()



  public double ValidatePredict_NN(){

      for( int i = 0; i < vvalQ; i++ ){
          for( int j = 0; j < vM; j++ ){
              valrSum[i][j] = 0.0;
              for( int k = 0; k < vN; k++ ){
                  valrSum[i][j] = valrSum[i][j] + W[k][j]*valX[i][k];
              }

              if( unipolar == sigmoid.getSelectedCheckbox() )
                  valY[i][j] = 1.0/( 1.0 + Math.exp( ( -va1*valrSum[i][j] + vb1 ) ) );
              else
                  valY[i][j] = ( 1.0 + Math.exp( -va1*valrSum[i][j] ) )/( 1.0 - Math.exp( -va1*valrSum[i][j] ) );
          }

          for( int l = 0; l < vJ; l++ ){
              valsSum[i][l] = 0.0;
              for( int m = 0; m < vM; m++ ){
                  valsSum[i][l] = valsSum[i][l] + U[m][l]*valY[i][m];
              }

              if( unipolar == sigmoid.getSelectedCheckbox() )
                  valZ[i][l] = 1.0/( 1.0 + Math.exp( ( -va2*valsSum[i][l] + vb2 ) ) );
              else
                  valZ[i][l] = ( 1.0 + Math.exp( -va2*valsSum[i][l] ) )/( 1.0 - Math.exp( -va2*valsSum[i][l] ) );
          }
      }

      ssErr = 0.0;

      for( int i = 0; i < vvalQ; i++ ){
          for( int j = 0; j < vJ; j++ ){
              ssErr = ssErr + ( valT[i][j] - valZ[i][j] )*( valT[i][j] - valZ[i][j] );
          }
      }

      return ssErr;



  }//END ValidatePredict_NN()


  //Thread Methods
  public void start(){


	if(frozen){
            //Start the loop!
            if (myThread == null) {
                myThread = new Thread(this);
            }
            myThread.start();
        }
    
    }//end start

    public void stop(){

      try{

        if( myThread == null && vnum == 0 )
            throw new NoThreadsStartedException( "Network training is not in progress" );

	//Stop iterating.
        myThread = null;
        errorArea.append( "\nStop. Training...Done.\n" );

      } catch( NoThreadsStartedException nts1 ){

            errorArea.setText( "No threads are currently running:\n" + nts1 );
      }



    }


    public void run(){

 
	//Just to be nice, lower this thread's priority
        //so it can't interfere with other processing going on.
        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);

        //Remember which thread we are.
        Thread currentThread = Thread.currentThread();

        //This is the iterative loop.
	errorArea.append( "\nStart trainining...\n" );
        
	Date begin = new Date();

        InitializeWeights();	

	while (currentThread == myThread) {
            
	    //Call NN training methods here

            //Adjust weights via Newton's linear approximation method
            AdjustWeights();

            //Update the dacay rate parameter in the sigmoids
            AdjustAlphas();

            if( iteration >= vnum ){

                //Copy error array to temp array
                for( int i = 0; i < vnum; i++ )
                    temp[i] = Err[i];

                //Sort the error array
                QuickSort( temp, 0, ( vnum - 1 ) );


                G1Init();


                stop();
		break;
	    }
            else
            
                Err[iteration++] = oldErr;

            if( iteration == ( vnum/2 ) )
                vmu = 0.0;


            if( iteration%10 == 0 ){

                if( iteration == 10 ){
                    errorArea.append( "Iteration" );
                    errorArea.append( "         " );
                    errorArea.append( "Total Sum-Squared Error" );
                    errorArea.append( "\n" );
                }

                errorArea.append( iteStr.valueOf( iteration ) );
                errorArea.append( "         " );
                errorArea.append( errStr.valueOf( oldErr ) );
                errorArea.append( "\n" );

            }

	}

        
        Date end = new Date();

        errorArea.append( "\nTotal time taken for training:     " );
        errorArea.append( errStr.valueOf( (end.getTime() - begin.getTime())/1000.00 ) );
        errorArea.append( "  seconds\n" );


                       
    }//end run


      public void G1Init(){
        //Get min and max x-axis( iterations )/y-axis ( error )
        g1xmin = 0.0;
        g1xmax = (double)( vnum );
        g1ymin = temp[0];
        g1ymax = temp[vnum-1];

        //determine x-axis tick marks
        g1xtic1 = g1xmax/2.0;
        g1xtic2 = g1xtic1/2.0;
        g1xtic3 = g1xtic1 + g1xtic2;
        g1xtic4 = g1xmax;

        //determine y-axis tick marks
        g1ytic1 = g1ymax/2.0;
        g1ytic2 = g1ytic1/2.0;
        g1ytic3 = g1ytic1 + g1ytic2;
        g1ytic4 = g1ymax;
      }


     public void G2Init(){

        //Get min and max x-axis( iterations )/y-axis ( error )
        g2xmin = 0.0;
        g2xmax = (double)( vtestQ );
        g2ymin1 = Zgrph[0];
        g2ymax1 = Zgrph[vtestQ-1];
        g2ymin2 = Tgrph[0];
        g2ymax2 = Tgrph[vtestQ-1]; 

        //determine x-axis tick marks
        g2xtic1 = g2xmax/2.0;
        g2xtic2 = g2xtic1/2.0;
        g2xtic3 = g2xtic1 + g2xtic2;
        g2xtic4 = g2xmax;
     }   




  //To draw the error graph
  public class Graph1 extends Canvas{

        public Graph1( Color bg, int width, int height ){

                setBackground( bg );
                setSize( width, height );
        }

        public void paint( Graphics g ){

            //x and y axis lines
            drawLine( g, 70, 50, 70, 250, Color.black );
            drawLine( g, 70, 250, 270, 250, Color.black );

            //draw x-axis tics and labels
            g.drawString( "|", tX( g1xtic1 ), 255 );
            g.drawString( "|", tX( g1xtic2 ), 255 );
            g.drawString( "|", tX( g1xtic3 ), 255 );
            g.drawString( "|", tX( g1xtic4 ), 255 );

            g.drawString( g1str1.valueOf( (int)g1xtic1 ), tX( g1xtic1 ) - 10, 265 );
            g.drawString( g1str1.valueOf( (int)g1xtic2 ), tX( g1xtic2 ) - 10, 265 );
            g.drawString( g1str1.valueOf( (int)g1xtic3 ), tX( g1xtic3 ) - 10, 265 );
            g.drawString( g1str1.valueOf( (int)g1xtic4 ), tX( g1xtic4 ) - 10, 265 );

            g.drawString( "Iterations", 160, 300 );

            //draw y-axis tics and labels
            g.drawString( "-", 67, tY( g1ytic1 ) );
            g.drawString( "-", 67, tY( g1ytic2 ) );
            g.drawString( "-", 67, tY( g1ytic3 ) );
            g.drawString( "-", 67, tY( g1ytic4 ) );
	    
            g.drawString( g1str1.valueOf( g1ytic1 ).substring(0,6), 25, tY( g1ytic1 ) );
            g.drawString( g1str1.valueOf( g1ytic2 ).substring(0,6), 25, tY( g1ytic2 ) );
            g.drawString( g1str1.valueOf( g1ytic3 ).substring(0,6), 25, tY( g1ytic3 ) );
            g.drawString( g1str1.valueOf( g1ytic4 ).substring(0,6), 25, tY( g1ytic4 ) );

            g.drawString( "Error", 45, 30 );

            //draw the graph
            g1lastx = tX( g1xmin );
            g1lasty = tY( Err[0] );

            for( int i = 1; i < vnum; i++ ){

                g1px1 = g1lastx;
                g1py1 = g1lasty;
                g1px2 = tX( (double)i );
                g1py2 = tY( Err[i] );
                drawLine( g, g1px1, g1py1, g1px2, g1py2, Color.red );
                g1lastx = g1px2;
                g1lasty = g1py2;

            }

        }

        public void drawLine( Graphics g, int x1, int y1, int x2, int y2, Color c ){

            Color origColor = g.getColor();
            g.setColor( c );
            g.drawLine( x1, y1, x2, y2 );
            g.setColor( origColor );
        }


        public int tX( double val1 ){

            return (int)( 200.00*( val1 - g1xmin )/( g1xmax - g1xmin ) + 70.00 );
        }

        public int tY( double val2 ){

            return (int)( -200.00*( val2 - g1ymin )/( g1ymax - g1ymin ) + 250.00 );
        }

  }//END Graph1


  //To draw the prediction graph
  public class Graph2 extends Canvas{        

        public Graph2( Color bg, int width, int height ){

                setBackground( bg );
                setSize( width, height );
        }

        public void paint( Graphics g ){

            if( g2ymax1 > g2ymax2 )
                g2ymax = g2ymax1;
	    else
                g2ymax = g2ymax2;

            if( g2ymin1 < g2ymin2 )
                g2ymin = g2ymin1;
	    else
                g2ymin = g2ymin2;

	    //determine y-axis tick marks
            g2ytic1 = g2ymax/2.0;
            g2ytic2 = g2ytic1/2.0;
            g2ytic3 = g2ytic1 + g2ytic2;
            g2ytic4 = g2ymax;

            //x and y axis lines
            drawLine( g, 70, 50, 70, 250, Color.black );
            drawLine( g, 70, 250, 270, 250, Color.black );

	    //Legends
            drawLine( g, 50, 325, 100, 325, Color.blue );
            g.drawString( "Target", 105, 325 );
            drawLine( g, 200, 325, 250, 325, Color.red );
            g.drawString( "Predicted", 255, 325 );
	    	    

            //draw x-axis tics and labels
            g.drawString( "|", tX( g2xtic1 ), 255 );
            g.drawString( "|", tX( g2xtic2 ), 255 );
            g.drawString( "|", tX( g2xtic3 ), 255 );
            g.drawString( "|", tX( g2xtic4 ), 255 );

            g.drawString( g2str1.valueOf( g2xtic1 ), tX( g2xtic1 ) - 7, 265 );
            g.drawString( g2str1.valueOf( g2xtic2 ), tX( g2xtic2 ) - 7, 265 );
            g.drawString( g2str1.valueOf( g2xtic3 ), tX( g2xtic3 ) - 7, 265 );
            g.drawString( g2str1.valueOf( g2xtic4 ), tX( g2xtic4 ) - 7, 265 );

            g.drawString( "Number of Exemplar Vectors", 120, 295 );

            //draw y-axis tics and labels
            g.drawString( "-", 67, tY( g2ytic1 ) );
            g.drawString( "-", 67, tY( g2ytic2 ) );
            g.drawString( "-", 67, tY( g2ytic3 ) );
            g.drawString( "-", 67, tY( g2ytic4 ) );
	    
            if( g2str1.valueOf( g2ytic1 ).length() > 4 )
                g.drawString( g2str1.valueOf( g2ytic1 ).substring(0, 3), 45, tY( g2ytic1 ) );
	    else
                g.drawString( g2str1.valueOf( g2ytic1 ), 45, tY( g2ytic1 ) );
         
            if( g2str1.valueOf( g2ytic2 ).length() > 4 )
                g.drawString( g2str1.valueOf( g2ytic2 ).substring(0, 3), 45, tY( g2ytic2 ) );
	    else
                g.drawString( g2str1.valueOf( g2ytic2 ), 45, tY( g2ytic2 ) );

            if( g2str1.valueOf( g2ytic3 ).length() > 4 )
                g.drawString( g2str1.valueOf( g2ytic3 ).substring(0, 3), 45, tY( g2ytic3 ) );
	    else
                g.drawString( g2str1.valueOf( g2ytic3 ), 45, tY( g2ytic3 ) );

            if( g2str1.valueOf( g2ytic4 ).length() > 4 )
                g.drawString( g2str1.valueOf( g2ytic4 ).substring(0, 3), 45, tY( g2ytic4 ) );
	    else
                g.drawString( g2str1.valueOf( g2ytic4 ), 45, tY( g2ytic4 ) );

            g.drawString( "Output", 45, 30 );

            //draw the graph
            g2lastx = tX( g2xmin );
            g2lasty = tY( Zgrph[0] );

            for( int i = 1; i < vtestQ; i++ ){

                g2px1 = g2lastx;
                g2py1 = g2lasty;
                g2px2 = tX( (double)i );
                g2py2 = tY( Zgrph[i] );
                drawLine( g, g2px1, g2py1, g2px2, g2py2, Color.red );
                g2lastx = g2px2;
                g2lasty = g2py2;

            }

            g2lastx = tX( g2xmin );
            g2lasty = tY( Tgrph[0] );         
	
	    for( int i = 1; i < vtestQ; i++ ){

                g2px1 = g2lastx;
                g2py1 = g2lasty;
                g2px2 = tX( (double)i );
                g2py2 = tY( Tgrph[i] );
                drawLine( g, g2px1, g2py1, g2px2, g2py2, Color.blue );
                g2lastx = g2px2;
                g2lasty = g2py2;

            }    

        }

        public void drawLine( Graphics g, int x1, int y1, int x2, int y2, Color c ){

            Color origColor = g.getColor();
            g.setColor( c );
            g.drawLine( x1, y1, x2, y2 );
            g.setColor( origColor );
        }


        public int tX( double val1 ){

            return (int)( 200.00*( val1 - g2xmin )/( g2xmax - g2xmin ) + 70.00 );
        }

        public int tY( double val2 ){

            return (int)( -200.00*( val2 - g2ymin )/( g2ymax - g2ymin ) + 250.00 );
        }

  }//END Graph2


  public void MainHelp(){

      errorArea.append( "Multiple-Layered Perceptrons( MLPs ) Applet Help:\n\n" );   


      errorArea.append( "Multiple-layered perceptrons are feedforward artificial\n" );
      errorArea.append( "neural networks widely used for pattern classification.\n" );
      errorArea.append( "This applet uses the method of cross-validation in which\n" );
      errorArea.append( "the data set is broken into three disjoint sets: a training\n" );
      errorArea.append( "set, a validation set and a testing set. Network's performance\n" );
      errorArea.append( "on the validation set is used to determine when to stop training.\n" );
      errorArea.append( "This applet uses the full propagation algorithm to train the\n" );
      errorArea.append( "network.\n\n" );


      errorArea.append( "Please follow these steps to get going!!:\n\n" );
      errorArea.append( "1.  Click on the 'Input MLPs Parameters' button to\n" );
      errorArea.append( "     input all the preliminary network parameters.\n\n" );

      errorArea.append( "2.  Click on the 'Input Vectors for Training' button to\n" );
      errorArea.append( "     input all the feature and target vectors for training.\n\n" );
     
      errorArea.append( "3.  Click on the 'Input Vectors for Validation' button to\n" );
      errorArea.append( "     input all the feature and target vectors for validation.\n\n" );

      errorArea.append( "4.  Click on the 'Input Vectors for Testing' button to\n" );
      errorArea.append( "     input all the feature and target vectors for testing.\n\n" );

      errorArea.append( "5.  Now you are ready to train, validate, and test the network.\n" );
      errorArea.append( "     To train the network click on the 'Start Training' button.\n" );
      errorArea.append( "     While the network is being trained, Total Sum-Squared Error\n" );
      errorArea.append( "     at every 10 iterations is displayed in this text area. You can\n" );
      errorArea.append( "     stop training the network anytime by pressing the 'Stop' button.\n" );
      errorArea.append( "     The training will automatically stop when number of iterations are\n" );
      errorArea.append( "     exhausted.\n\n" );

      errorArea.append( "6.  Click on the 'View Error Graph' button to graphically visualize\n" );
      errorArea.append( "     the errors. Press 'Close' button to quit the graph.\n\n" );

      errorArea.append( "7.  Click on the 'View Error Statistics' button to view total minimum\n" );
      errorArea.append( "     and maximum Sum-Squared Error, Root Sum-Squared Error,\n" );
      errorArea.append( "     Mean-Square error, and Root Mean-Squared Error.\n\n" );
    

      errorArea.append( "8.  To Validate the network press 'Validate NN' button.\n" );
      errorArea.append( "     The previous and current Total Mean-Square Errors are displayed\n" );
      errorArea.append( "     in this text area. If the current error is greater than the previous\n" );
      errorArea.append( "     error then go on with the testing else repeat the training and the\n" );
      errorArea.append( "     the validation steps.\n\n" );
    
      errorArea.append( "9.  Once the network is cross-validated, click on the 'Start Testing'\n" );
      errorArea.append( "     button to test the network performance. The target and the predicted\n" );
      errorArea.append( "     network output is displayed in this text area. To visualize the results\n" );
      errorArea.append( "     graphically, click on the 'View Prediction Graph' button.\n\n" );

      errorArea.append( "10. Click on the 'View Learned Parameters' to view exponential rates,\n" );
      errorArea.append( "     learning rates, biases, and the weights at the hidden and the output\n" );
      errorArea.append( "     neurodes.\n\n" );


      errorArea.append( "11. To save the contents of the text area, select 'Save' option from the 'File'\n" );
      errorArea.append( "     menu. Due to some serious security considerations, some browsers\n" );
      errorArea.append( "     may not be able to save the contents. However, you may copy or cut\n" );
      errorArea.append( "     the contents and paste it in your Word or Notepad application file.\n\n" );

      errorArea.append( "12. All the exceptions are caught and displayed in this text area\n\n" );

      errorArea.append( "13. To exit the applet, select 'Quit' option from the 'File' menu.\n\n" );

      errorArea.append( "14. To launch the applet again, press 'Reload' button on your browser.\n\n" );

      errorArea.append( "15. To clear this text area, click on the 'Refresh' button.\n\n" );


  }



  public void paramFrameHelp(){

      
      helpArea.append( "1.  First click on the 'View Default Parameters' button to\n" );
      helpArea.append( "     view default sigmoid function, exponential rates and the\n" );
      helpArea.append( "     increments, learning rates, biases, and momentum parameters.\n\n" );

      helpArea.append( "2.  Enter number of input nodes, output layer neurodes, middle\n" );
      helpArea.append( "     layer neurodes, exemplar vector, and iterations in the\n" );
      helpArea.append( "     respective text fields.\n\n" );

      helpArea.append( "3.  Select one of the sigmoid functions. The defaul is unipolar\n" );
      helpArea.append( "     sigmoid. The biases are ignored when bipolar sigmoid is selected.\n\n" );


      helpArea.append( "4.  Click on the 'Submit' button to input the parameters.\n" );
      helpArea.append( "     If any of the text field is empty, the NumberFormatException\n" );
      helpArea.append( "     is thrown and displayed in the main applet's text area.\n\n" );


      helpArea.append( "5.  After submitting the parameters, proceed to enter feature and\n" );
      helpArea.append( "     target vectors for training, validation, and testing.\n\n" );

      helpArea.append( "6.  To quit the 'MLPs Parameters' window, select 'Close' option\n" );
      helpArea.append( "     from the 'File' menu.\n\n" );

      helpArea.append( "7.  To quit the help window, click on the 'Close' button.\n" );


  }
  
  public void trainVecHelp(){

      featureArea.append( "Input Vectors for Training Help:\n\n" );


      featureArea.append( "1.  First select 'Feature Vectors' option from the 'File' menu.\n" );
      featureArea.append( "     A file dialog box will be displayed on your screen. Select\n" );
      featureArea.append( "     the file. The contents will be displayed in the first text\n" );
      featureArea.append( "     area.\n\n" );

      featureArea.append( "2.  Then select 'Target Vectors' option from the 'File' menu.\n" );
      featureArea.append( "     A file dialog box will be displayed on your screen. Select\n" );
      featureArea.append( "     the file. The contents will be displayed in the second text\n" );
      featureArea.append( "     area.\n\n" );

      featureArea.append( "3.  On some browsers you may not be able to bring up the file\n" );
      featureArea.append( "     dialog box for securiry reasons. In this case just copy the\n" );
      featureArea.append( "     data from your file and paste it in the respective text areas.\n\n" );
  

      featureArea.append( "4.  Click on 'Submit Vectors for Training' button to input feature and\n" );
      featureArea.append( "     target vectors.\n\n" );

      featureArea.append( "5.  Click on 'Clear' button to clear the contents of the text areas.\n\n" );


      featureArea.append( "6.  To quit the 'Input Vectors fot Training' window, select 'Close'\n" );
      featureArea.append( "     option from the 'File' menu.\n\n" );


  }


  public void testVecHelp(){

      targetArea.append( "Input Vectors for Testing Help:\n\n" );

      targetArea.append( "1.  Enter the number of exemplar vectors ( Q ) for testing\n" );
      targetArea.append( "     in the text field.\n\n" );

     

      targetArea.append( "2.  First select 'Feature Vectors' option from the 'File' menu.\n" );
      targetArea.append( "     A file dialog box will be displayed on your screen. Select\n" );
      targetArea.append( "     the file. The contents will be displayed in the first text\n" );
      targetArea.append( "     area.\n\n" );

      targetArea.append( "3.  Then select 'Target Vectors' option from the 'File' menu.\n" );
      targetArea.append( "     A file dialog box will be displayed on your screen. Select\n" );
      targetArea.append( "     the file. The contents will be displayed in the second text\n" );
      targetArea.append( "     area.\n\n" );

      targetArea.append( "4.  On some browsers you may not be able to bring up the file\n" );
      targetArea.append( "     dialog box for securiry reasons. In this case just copy the\n" );
      targetArea.append( "     data from your file and paste it in the respective text areas.\n\n" );
  

      targetArea.append( "5.  Click on 'Submit Vectors for Testing' button to input feature and\n" );
      targetArea.append( "     target vectors.\n\n" );

      targetArea.append( "6.  Click on 'Clear' button to clear the contents of the text areas.\n\n" );


      targetArea.append( "7.  To quit the 'Input Vectors for Testing' window, select 'Close'\n" );
      targetArea.append( "     option from the 'File' menu.\n\n" );


  }

  public void valVecHelp(){

      valFeatureArea.append( "Input Vectors for Validation Help:\n\n" );

      valFeatureArea.append( "1.  Enter the number of exemplar vectors ( Q ) for validation\n" );
      valFeatureArea.append( "     in the text field.\n\n" );

     

      valFeatureArea.append( "2.  First select 'Feature Vectors' option from the 'File' menu.\n" );
      valFeatureArea.append( "     A file dialog box will be displayed on your screen. Select\n" );
      valFeatureArea.append( "     the file. The contents will be displayed in the first text\n" );
      valFeatureArea.append( "     area.\n\n" );

      valFeatureArea.append( "3.  Then select 'Target Vectors' option from the 'File' menu.\n" );
      valFeatureArea.append( "     A file dialog box will be displayed on your screen. Select\n" );
      valFeatureArea.append( "     the file. The contents will be displayed in the second text\n" );
      valFeatureArea.append( "     area.\n\n" );

      valFeatureArea.append( "4.  On some browsers you may not be able to bring up the file\n" );
      valFeatureArea.append( "     dialog box for securiry reasons. In this case just copy the\n" );
      valFeatureArea.append( "     data from your file and paste it in the respective text areas.\n\n" );
  

      valFeatureArea.append( "5.  Click on 'Submit Vectors for Validation' button to input feature and\n" );
      valFeatureArea.append( "     target vectors.\n\n" );

      valFeatureArea.append( "6.  Click on 'Clear' button to clear the contents of the text areas.\n\n" );


      valFeatureArea.append( "7.  To quit the 'Input Vectors for Validation' window, select 'Close'\n" );
      valFeatureArea.append( "     option from the 'File' menu.\n\n" );


  }


  //handle radio button exception
  public class CheckBoxNotSelectedException extends Exception{

      public CheckBoxNotSelectedException(String message){

          super(message);
      }
  }

  //handle uninitialized data exception
  public class ZeroInitializedDataException extends Exception{

      public ZeroInitializedDataException(String message){

          super(message);
      }
  }

  //handle null thread exception
  public class NoThreadsStartedException extends Exception{

      public NoThreadsStartedException(String message){

          super(message);
      }
  }






}//END main applet
