1 import java.applet.*;
    2 import java.awt.*;
    3 import java.awt.event.*;
    4 import java.lang.Integer;
    5 import java.util.Vector;
    6 
    7 /**
    8  * Applet to demonstrate Peter's Convenience Store Problem
    9  * Creation date: (02/25/2002 10:07:02 AM)
   10  * Modified date: (04/15/2002 04:35:00 PM)
   11  * @author: Andrew Freed, arf132@psu.edu
   12  */
   13 
   14 /*
   15 Development of this applet was sponsored by the Penn State Fund for 
   16 Excellence in Learning and Teaching (FELT), project "Java-based 
   17 Teaching of Mathematics in Information Sciences and Technology",
   18 supervised by Frank Ritter and David Mudgett.
   19 */
   20 
   21 public class PetersProblemApplet extends Applet {
   22   private Button    btnGo      = new Button("Go!");
   23   private TextArea   txtOutput     = new TextArea("",11,80,TextArea.SCROLLBARS_VERTICAL_ONLY);
   24 
   25   private Label lblPtrChoice = new Label("Peter:");
   26   private Choice ptrChoice = new Choice();
   27 
   28   private Label lblTrainerChoice = new Label("Trainers:");
   29   private Choice trnTrainTrainerChoice = new Choice();
   30   private Choice trnTrainInstallerChoice = new Choice();
   31   private Choice trnInstallChoice = new Choice();
   32   private Label lblTrainingTrainers = new Label("Training Trainers");
   33   private Label lblTrainingInstallers = new Label("Training Installers");
   34   private Label lblInstallers = new Label("Installing");
   35 
   36   private Label lblInstallerChoice = new Label("Installers:");
   37   private Choice insChoice = new Choice();
   38 
   39   private Label lblTotalUnits = new Label("Total units:");
   40   private TextField txtTotalUnits = new TextField("10");
   41   private Label lblNumRemaining = new Label("Units remaining:");
   42   private TextField txtNumRemaining = new TextField("?");
   43 
   44   public  int numUnitsRemaining;     // Units left to be installed
   45   public  int TOTAL_UNITS_NEEDED;    // Initial number of units to install
   46   private int numWeek;               // Maintain running date
   47 
   48   private int numInstallers;         // Peter's workforce
   49   private int numTrainers;           // Peter's workforce
   50   private int numTrainersTrainingTrainers; // How many trainers started training a trainer last week
   51   
   52   private boolean   isPeterTrainingTrainer;  // Peter can not stop training a trainer to do something else
   53   private boolean   weekInProgress;          // boolean to determine current applet state
   54   private boolean   doReset;                 // boolean to determine current applet state
   55 
   56   //Keeps track of whether or not the applet has run.  
   57   //Else, every pass through init() will create ANOTHER actionListener on btnGo
   58   private boolean   active  = false; 
   59 
   60   private Vector myTrainers   = new Vector();
   61 
   62 // Training an installer involves updating the global count and inserting into choice box
   63 private void addInstaller()
   64 {
   65   numInstallers++;
   66   insChoice.removeAll();
   67   
   68   for( int idx = numInstallers; idx >= 0; idx-- )
   69     insChoice.add(new Integer(idx).toString());
   70 }
   71 
   72 // Peter training a trainer is a simplified case of a general trainer training a trainer
   73 private void addTrainerByPeter()
   74 {
   75   //If he isn't in the middle of the training process, it must be started
   76   if( !isPeterTrainingTrainer )
   77   {
   78     output("Peter began training a trainer");
   79     isPeterTrainingTrainer = true;
   80     ptrChoice.setEnabled(false);
   81   }
   82 
   83   //Otherwise finish the training process
   84   else
   85   {
   86     output("Peter finished training a trainer");
   87     myTrainers.addElement( new Trainer(++numTrainers) );
   88     isPeterTrainingTrainer = false;
   89     ptrChoice.setEnabled(true);
   90   }
   91 }
   92 
   93 //Accessor function to retrieve value from choice box
   94 private int getNumChosenInstallers()
   95 {
   96   return Integer.parseInt( insChoice.getSelectedItem() );
   97 }
   98 
   99 //Accessor function to retrieve value from choice box
  100 private int getNumChosenTrainingTrainers()
  101 {
  102   return Integer.parseInt( trnTrainTrainerChoice.getSelectedItem() );
  103 }
  104 
  105 //Accessor function to retrieve value from choice box
  106 private int getNumChosenTrainingInstallers()
  107 {
  108   return Integer.parseInt( trnTrainInstallerChoice.getSelectedItem() );
  109 }
  110 
  111 //Accessor function to retrieve value from choice box
  112 private int getNumChosenTrainerInstallers()
  113 {
  114   return Integer.parseInt( trnInstallChoice.getSelectedItem() );
  115 }
  116 
  117 //Sets available choices for the trainer boxes.  Note that trainers currently training
  118 // other trainers are NOT available to do new tasks the following week.
  119 private void setTrainerChoiceBoxes()
  120 {
  121   int numUnavailable = numTrainersTrainingTrainers; //getNumChosenTrainingTrainers(); 
  122   trnTrainTrainerChoice.removeAll();
  123   trnTrainInstallerChoice.removeAll();
  124   trnInstallChoice.removeAll();
  125 
  126   //This creates a list from the top down, the maximal number is the "default" choice
  127   for( int idx = numTrainers - numUnavailable; idx >= 0; idx-- )
  128   {
  129     
  130     trnTrainTrainerChoice.add(new Integer(idx).toString());
  131     trnTrainInstallerChoice.add(new Integer(idx).toString());
  132     trnInstallChoice.add(new Integer(idx).toString());
  133   }
  134     //Default all available trainers to install.
  135     trnTrainTrainerChoice.select("0");
  136     trnTrainInstallerChoice.select("0");
  137 }
  138 
  139 //Fix the choice boxes based on user input.  Input argument is which choice box to hold constant:
  140 // 1 - trnTrainTrainerChoice
  141 // 2 - trnTrainInstallerChoice
  142 // 3 - trnInstallChoice
  143 private void fixTrainerBoxes(int numOkChoice)
  144 {
  145 try
  146 {
  147   //Determine how many trainers are free
  148   int numAvailTrainers = numTrainers - numTrainersTrainingTrainers;
  149   int numTrainersUsed = 0;
  150 
  151   if( numOkChoice == 1 )
  152     numTrainersUsed += getNumChosenTrainingTrainers();
  153   else if (numOkChoice == 2)
  154     numTrainersUsed += getNumChosenTrainingInstallers();
  155   else
  156     numTrainersUsed += getNumChosenTrainerInstallers();
  157 
  158   if( numOkChoice != 3)
  159   {
  160     if(numAvailTrainers - numTrainersUsed <  getNumChosenTrainerInstallers())
  161       trnInstallChoice.select( new Integer(numAvailTrainers - numTrainersUsed).toString());
  162 
  163     numTrainersUsed += getNumChosenTrainerInstallers();
  164   }
  165   if( numOkChoice != 2)
  166   {
  167     if(numAvailTrainers - numTrainersUsed <  getNumChosenTrainingInstallers())
  168       trnTrainInstallerChoice.select( new Integer(numAvailTrainers - numTrainersUsed).toString());
  169 
  170     numTrainersUsed += getNumChosenTrainingInstallers();
  171   }
  172   if( numOkChoice != 1)
  173   {
  174     if(numAvailTrainers - numTrainersUsed <  getNumChosenTrainingTrainers());
  175       trnTrainTrainerChoice.select( new Integer(numAvailTrainers - numTrainersUsed).toString());
  176 
  177     numTrainersUsed += getNumChosenTrainingTrainers();
  178   }
  179 }
  180 catch( Exception e)
  181 {
  182   output(e.toString());
  183   output("Doh!!!");
  184 }
  185 }
  186 
  187 //Handles Peter's work. Based on selection in list box, routes work to appropriate function
  188 private void doPetersOptions()
  189 {
  190   boolean unitsRemaining = (numUnitsRemaining > 0);
  191   if( ptrChoice.getSelectedItem().equals("Install") )
  192   {
  193     if( unitsRemaining )
  194     {
  195       numUnitsRemaining--;
  196       output("Peter installed a unit");
  197     }
  198     else
  199     {
  200       output("Peter couldn't install -- All units installed");
  201     }
  202   }
  203   else if ( ptrChoice.getSelectedItem().equals("Train Installer") )
  204   {
  205     addInstaller();
  206     output("Peter trained an installer");
  207   }
  208   else //  ptrChoice.getSelectedItem.equals("Train Trainer") 
  209   {
  210     addTrainerByPeter();
  211   }
  212 }
  213 
  214 //Handles installer actions.  Essentially, the chosen number of installers either installs
  215 // a unit, or reports that all units are installed.
  216 private void doInstallersActions()
  217 {
  218   boolean unitsRemaining = (numUnitsRemaining > 0);
  219   int numWorkingInstallers = getNumChosenInstallers();
  220   int idx;
  221 
  222   //Install available units
  223   for( idx = 0; idx < numWorkingInstallers && unitsRemaining; idx++ )
  224   {
  225     numUnitsRemaining--;
  226     output("Installer #" + (idx+1) + " installed a unit");
  227     unitsRemaining = (numUnitsRemaining > 0);
  228   }
  229 
  230   //If job is completed, report failure to install
  231   if( !unitsRemaining )
  232   for( int i = idx; i < numWorkingInstallers; i++)
  233     output("Installer #" + (i+1) + " couldn't install -- All units installed");
  234   
  235 }
  236 
  237 //Process actions for trainers.  Based on selections from listbox.
  238 //Currently, if too many trainers are requested to do actions, the following priority is used:
  239 //  1) Train trainers
  240 //  2) Remaining trainers will train installers
  241 //  3) Remaining trainers will install units
  242 //
  243 //  For instance, if there are 5 trainers and the boxes read "4", "3", "2" respectively, 4 will begin
  244 //  training trainers, one will train and installer, and none will install units.
  245 //
  246 // The Trainer member variable "hasWorkedThisWeek" regulates this.  As a trainer is selected to perform 
  247 // an action, the "hasWorkedThisWeek" flag is set.  Given the order of operations, it may be the case
  248 // that all trainers have this flag set, before the requests to install units is processed.
  249 private void doTrainerOptions()
  250 {
  251   //Retrieve listbox values
  252   int trnTrainers = getNumChosenTrainingTrainers();
  253   int trnInstallers = getNumChosenTrainingInstallers();
  254   int trnInstalling = getNumChosenTrainerInstallers();
  255 
  256   int idx;
  257   int count;
  258   int countFinishedTrainers = 0;
  259   int countStartedTrainers = 0;
  260 
  261   //Handle trainers training trainers.  If a trainer is in the middle of training, allow them to finish.
  262   //Otherwise, note their progress.
  263   for( idx = 0; idx < numTrainers; idx++ )
  264   {
  265     Trainer temp = (Trainer) myTrainers.elementAt(idx);
  266     if( !temp.isTrainingATrainer )
  267     {
  268       if(countStartedTrainers < trnTrainers)
  269       {
  270       output("Trainer #" + (idx+1) + " began training a trainer");
  271       temp.isTrainingATrainer = true;
  272       temp.hasWorkedThisWeek = true;
  273       countStartedTrainers++;
  274       }
  275     }
  276     else //temp.IsTrainingTrainer
  277     {
  278       if( countFinishedTrainers < numTrainersTrainingTrainers)
  279       {
  280       output("Trainer #" + (idx+1) + " finished training a trainer");
  281       temp.isTrainingATrainer = false;
  282       temp.hasWorkedThisWeek = true;
  283       countFinishedTrainers++;    
  284       }
  285     }
  286   }
  287 
  288   //Train installers
  289   for( idx = 0, count = 0; idx < numTrainers && count < trnInstallers; idx++ )
  290   {
  291     Trainer temp = (Trainer) myTrainers.elementAt(idx);
  292     if( !temp.hasWorkedThisWeek )
  293     {
  294       addInstaller();
  295       output("Trainer #" + (idx+1) + " trained an installer");
  296       temp.hasWorkedThisWeek = true;
  297       count++;
  298     }
  299   }
  300 
  301   //Trainers who are installing units
  302   boolean unitsRemaining = ( numUnitsRemaining > 0 );
  303   for( idx = 0, count = 0; idx < numTrainers && count < trnInstalling && unitsRemaining; idx++ )
  304   {
  305     Trainer temp = (Trainer) myTrainers.elementAt(idx);
  306     if( !temp.hasWorkedThisWeek )
  307     {
  308       numUnitsRemaining--;
  309       output("Trainer #" + (idx+1) + " installed a unit");
  310       temp.hasWorkedThisWeek = true;
  311       count++;
  312     unitsRemaining = ( numUnitsRemaining > 0 );
  313     }
  314   }
  315 
  316   //If no work left, report the failure to install
  317   if( !unitsRemaining )
  318   for( int i = idx; i < numTrainers; i++)
  319   {
  320     Trainer temp = (Trainer) myTrainers.elementAt(idx);
  321     if( !temp.hasWorkedThisWeek )
  322     {
  323       output("Trainer #" + (i+1) + " couldn't install -- All units installed");
  324     }
  325   }
  326 
  327   //Actually add the new trainers... so that they can work NEXT week
  328   //If they are added before this point, they will be given work for THIS week
  329   for( idx=0; idx < numTrainersTrainingTrainers ; idx++ )
  330   {
  331     myTrainers.addElement( new Trainer(++numTrainers) );
  332   }
  333 
  334   //Advance one week
  335   numTrainersTrainingTrainers = trnTrainers; 
  336 
  337   //Reset 'hasWorkedThisWeek' flag
  338   for( idx=0; idx < numTrainers; idx++ )
  339   {
  340     Trainer temp = (Trainer) myTrainers.elementAt(idx);
  341     temp.hasWorkedThisWeek = false;
  342   }
  343 }
  344 
  345 private void printWeekHeader()
  346 {
  347   output("********** BEGIN WEEK " + numWeek + " **********");
  348   output("Peter has " + numUnitsRemaining + " units left to install");
  349   output("Workforce: " + numInstallers + " installers, " + numTrainers + " trainers");
  350   output("----------- WORK -----------");
  351 }
  352 
  353 private void printWeekFooter()
  354 {
  355   output("---------- RESULTS ----------");
  356   output("Peter has " + numUnitsRemaining + " units left to install");
  357   output("Workforce: " + numInstallers + " installers, " + numTrainers + " trainers");    
  358   output("********** END WEEK " + numWeek + " **********");
  359   numWeek++;
  360 
  361   if( numUnitsRemaining <= 0 )
  362   {
  363     output(">>> Done installing " + txtTotalUnits.getText() + " units!");
  364     output(">>> Change \"Total units\" and press Go! to reset simulation");
  365     weekInProgress = false;
  366     txtTotalUnits.setEnabled(true);
  367     doReset = true;
  368     return;  
  369   }
  370 }
  371 
  372 private void runWeek()
  373 {
  374   //Apparently, there is a problem when this function dispatches it's work to the other functions  
  375 
  376   printWeekHeader();
  377 
  378   //Installer actions
  379   doInstallersActions();
  380 
  381   //Trainer options  
  382   doTrainerOptions();
  383   
  384   //Peter's options
  385   doPetersOptions();
  386 
  387   //Reset certain boxes
  388   setTrainerChoiceBoxes();
  389 
  390   //Update results
  391   txtNumRemaining.setText( new Integer(numUnitsRemaining).toString()  );
  392 
  393   printWeekFooter();
  394 }
  395 
  396 /**
  397  * Initializes the applet.
  398  */
  399 public void init() {
  400   try {
  401     super.init();
  402     setName("PetersProblemApplet");
  403     setLayout(null);
  404     setSize(500, 400);
  405 
  406     btnGo.setBounds(0, 320, 50, 30);
  407 
  408     lblPtrChoice.setBounds(0,0,75,30);
  409     ptrChoice.setBounds(75,0,100,30);
  410 
  411     lblTrainerChoice.setBounds(0,50,75,30);
  412     trnTrainTrainerChoice.setBounds(75,50,100,30);
  413     trnTrainInstallerChoice.setBounds(200,50,100,30);
  414     trnInstallChoice.setBounds(325,50,100,30);
  415 
  416     lblTrainingTrainers.setBounds(75, 25, 125, 30);
  417     lblTrainingInstallers.setBounds(200, 25, 125, 30);
  418     lblInstallers.setBounds(325, 25, 100, 30);
  419 
  420     lblInstallerChoice.setBounds(0,80,75,30);
  421     insChoice.setBounds(75,80,100,30);
  422 
  423     lblTotalUnits.setBounds(100,320,100,30);
  424     txtTotalUnits.setBounds(200,320,30,30);
  425     lblNumRemaining.setBounds(250,320,100,30);
  426     txtNumRemaining.setBounds(350,320,30,30);
  427 
  428     txtTotalUnits.setEnabled(true);
  429     txtNumRemaining.setEditable(false);
  430 
  431     txtOutput.setBounds(0,120,495,200);
  432     txtOutput.setEditable(false);
  433 
  434     add(txtOutput);
  435     add(btnGo);
  436     add(lblPtrChoice);
  437     add(ptrChoice);  
  438     add(lblTrainerChoice);
  439     add(trnTrainTrainerChoice);
  440     add(trnTrainInstallerChoice);
  441     add(trnInstallChoice);
  442     add(lblTrainingTrainers);
  443     add(lblTrainingInstallers);
  444     add(lblInstallers);
  445     add(lblInstallerChoice);
  446     add(insChoice);
  447     add(lblTotalUnits);
  448     add(txtTotalUnits);
  449     add(lblNumRemaining);
  450     add(txtNumRemaining);
  451 
  452     trnTrainTrainerChoice.removeAll();
  453     trnTrainInstallerChoice.removeAll();
  454     trnInstallChoice.removeAll();
  455     insChoice.removeAll();
  456 
  457     trnTrainTrainerChoice.add("0");
  458     trnTrainInstallerChoice.add("0");
  459     trnInstallChoice.add("0");
  460     insChoice.add("0");
  461 
  462     ptrChoice.removeAll();
  463     ptrChoice.add("Install");
  464     ptrChoice.add("Train Installer");
  465     ptrChoice.add("Train Trainer");
  466     ptrChoice.setEnabled(true);
  467 
  468     numWeek = 1;
  469     isPeterTrainingTrainer = false;
  470     myTrainers   = new Vector();
  471     numInstallers = 0;
  472     numTrainers = 0;
  473     numTrainersTrainingTrainers = 0;
  474     weekInProgress = false; 
  475 
  476     btnGo.setActionCommand("btnGo");
  477 
  478     //Without this check, new ActionListeners are added on every Reset action
  479     if( !active )
  480     {
  481       //Identical ActionListener added to both btnGo and txtTotalUnits
  482 
  483       btnGo.addActionListener(new java.awt.event.ActionListener(){
  484       public void actionPerformed(java.awt.event.ActionEvent e)
  485       {
  486         //If called at end of simulation, need to reset values
  487         if( doReset )
  488         {
  489           doReset = false;
  490           init();
  491         }
  492 
  493         //If simulation is just beginning, need to load unit info
  494         if( !weekInProgress )
  495         {
  496           TOTAL_UNITS_NEEDED = Integer.parseInt( txtTotalUnits.getText() );
  497           numUnitsRemaining = TOTAL_UNITS_NEEDED;
  498           txtNumRemaining.setText( new Integer(numUnitsRemaining).toString() );
  499         }
  500 
  501         //Normal execution path
  502         if( numUnitsRemaining > 0 )
  503         {
  504           weekInProgress = true;
  505           txtTotalUnits.setEnabled(false);
  506           runWeek();
  507         }
  508       }
  509       });
  510 
  511       txtTotalUnits.addActionListener(new java.awt.event.ActionListener(){
  512       public void actionPerformed(java.awt.event.ActionEvent e)
  513       {
  514         //If called at end of simulation, need to reset values
  515         if( doReset )
  516         {
  517           doReset = false;
  518           init();
  519         }
  520 
  521         //If simulation is just beginning, need to load unit info
  522         if( !weekInProgress )
  523         {
  524           TOTAL_UNITS_NEEDED = Integer.parseInt( txtTotalUnits.getText() );
  525           numUnitsRemaining = TOTAL_UNITS_NEEDED;
  526           txtNumRemaining.setText( new Integer(numUnitsRemaining).toString() );
  527         }
  528 
  529         //Normal execution path
  530         if( numUnitsRemaining > 0 )
  531         {
  532           output("here");
  533           weekInProgress = true;
  534           txtTotalUnits.setEnabled(false);
  535           runWeek();
  536         }
  537       }
  538       });
  539 
  540       trnTrainTrainerChoice.addItemListener( new java.awt.event.ItemListener(){
  541       public void itemStateChanged(java.awt.event.ItemEvent e)
  542       {
  543         fixTrainerBoxes(1);
  544       }
  545       });
  546       trnTrainInstallerChoice.addItemListener( new java.awt.event.ItemListener(){
  547       public void itemStateChanged(java.awt.event.ItemEvent e)
  548       {
  549         fixTrainerBoxes(2);
  550       }
  551       });
  552       trnInstallChoice.addItemListener( new java.awt.event.ItemListener(){
  553       public void itemStateChanged(java.awt.event.ItemEvent e)
  554       {
  555         fixTrainerBoxes(3);
  556       }
  557       });
  558     }
  559 
  560     txtOutput.setText( "********** BEGIN SIMULATION **********\n"
  561           + "Peter has to install " + numUnitsRemaining + " units into "
  562           + " convenience stores.  He may either install a unit himself,"
  563           + " train another installer, or train a trainer.  Please choose"
  564           + " an action for Peter, and hit Go!\n\n");
  565 
  566     active = true;
  567 
  568   } catch (java.lang.Throwable Exc) {
  569     handleException(Exc);
  570   }
  571 }
  572 
  573 //Function to simplify output of messages
  574 private void output(String msg)
  575 {
  576   txtOutput.append(msg + "\n");
  577 }
  578     
  579 /**
  580  * Called whenever the part throws an exception.
  581  * @param exception java.lang.Throwable
  582  */
  583 private void handleException(java.lang.Throwable exception) {
  584   output(exception.toString());
  585 }
  586 
  587 //Main function allows you to run this applet as an application
  588 /**
  589  * main entrypoint - starts the part when it is run as an application
  590  * @param args java.lang.String[]
  591  */
  592 public static void main(java.lang.String[] args) {
  593   try {
  594     Frame frame = new java.awt.Frame();
  595     PetersProblemApplet aPetersProblemApplet;
  596     Class iiCls = Class.forName("PetersProblemApplet");
  597     ClassLoader iiClsLoader = iiCls.getClassLoader();
  598     aPetersProblemApplet = (PetersProblemApplet)java.beans.Beans.instantiate(iiClsLoader,"PetersProblemApplet");
  599     frame.add("Center", aPetersProblemApplet);
  600     frame.setSize(aPetersProblemApplet.getSize());
  601     frame.addWindowListener(new java.awt.event.WindowAdapter() {
  602       public void windowClosing(java.awt.event.WindowEvent e) {
  603         System.exit(0);
  604       };
  605     });
  606     frame.show();
  607     java.awt.Insets insets = frame.getInsets();
  608     frame.setSize(frame.getWidth() + insets.left + insets.right, frame.getHeight() + insets.top + insets.bottom);
  609     frame.setVisible(true);
  610   } catch (Throwable exception) {
  611     System.err.println("Exception occurred in main() of java.applet.Applet");
  612     exception.printStackTrace(System.out);
  613   }
  614 }
  615 
  616 public class Trainer
  617 {
  618   public Trainer(int _id)
  619   {
  620     trainerId = _id;
  621   }
  622 
  623   public boolean isTrainingATrainer = false;
  624   public boolean hasWorkedThisWeek = false;
  625   public int trainerId;
  626 }
  627 
  628 }
  629 
HTML generated by Java2Html, © 2000 Think Tank Ltd, Douglas, Isle Of Man. All rights reserved