Link to home
Start Free TrialLog in
Avatar of snowplank
snowplank

asked on

Ammending JTextAreas by clicking JButtons - again if CEHJ is watching ;o)

I have 6 JButtons - btnTblPay[6].  When they are clicked I want the bill from the JTextAreas - btnTblPay[6] to total and display in the Jlabel - lblTillReceiptTotal (it should keep running total as more orders are cleared).  When these buttons (btnTblPay) are pressed, I also want the JTextAreas (btnTblPay) to clear contents and the JButtons - btnTables to revert back to White (unnoccupied).  I have written a method called  clearTblOrder for this purpose but do not know quite how to utilise it.

My code is listed below.

Any help greatly appreciated....

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;

public class CourseWorkTest extends JApplet implements ActionListener{
   
   
   // declare panels
   JPanel pnlMain = new JPanel();
   JPanel pnlOrder = new JPanel();
   JPanel pnlOrderTop = new JPanel();
   JPanel pnlOrderBott = new JPanel();
   JPanel pnlOrderBottLeft = new JPanel();
   JPanel pnlOrderBottRight = new JPanel();
   JPanel pnlTables = new JPanel();
   JPanel pnlBill = new JPanel();
   JPanel pnlBillTop = new JPanel();
   JPanel pnlBillBott = new JPanel();
   JPanel pnlManager = new JPanel();
   JPanel pnlManagerTop = new JPanel();
   JPanel pnlManagerBott = new JPanel();
         
   //pnlOrder objects
   JLabel lblStarter = new JLabel("Starter",JLabel.CENTER);
   JLabel lblMainCourse = new JLabel("Main Course",JLabel.CENTER);
   JLabel lblDessert = new JLabel("Dessert",JLabel.CENTER);
   JLabel lblDrinks = new JLabel("Drinks",JLabel.CENTER);
   JComboBox myStarter = new JComboBox();
   JComboBox myMainCourse = new JComboBox();
   JComboBox myDessert = new JComboBox();
   JComboBox myDrinks = new JComboBox();
   JButton btnReset = new JButton("Clear Order");
   JButton btnRemoveItem = new JButton("Remove Item");
   JTextArea myOrderBox = new JTextArea(15,15);
   JScrollPane myScrollPane = new JScrollPane(myOrderBox);
   Basket myBasket = new Basket();
   boolean remv = false;
   //String order = new String();
   String descStarters[]= new String[6];
   String descMainCourses[]= new String[6];
   String descDesserts[]= new String[6];
   String descDrinks[]= new String[6];
   float myStarterCosts[]= new float[6];
   float myMainCourseCosts[]= new float[6];
   float myDessertCosts[]= new float[6];
   float myDrinksCosts[]= new float[6];

   // pnlTables objects
   JButton btnTables[] = new JButton[6];
           
   //pnlBill objects
   JLabel lblBillTitle = new JLabel("Tables Currently Occupied And Their Bills",JLabel.CENTER);
   JTextArea tblOrders[] = new JTextArea[6];
   
   //pnlManager objects
   JButton btnTblPay[] = new JButton[6];
   JLabel lblTillReceipt = new JLabel("This Evening's Till Receipts: ",JLabel.CENTER);
   JLabel lblTillReceiptTotal = new JLabel("       £0.00",JLabel.CENTER);

   public void init(){

      //Add objects to main panel - pnlMain
      pnlMain.setLayout(new GridLayout(2,2));
      pnlMain.setBackground(Color.WHITE);
      pnlMain.add(pnlOrder);
      pnlMain.add(pnlTables);
      pnlMain.add(pnlBill);
      pnlMain.add(pnlManager);

      //Add Objects to pnlOrder
      pnlOrder.setLayout(new BorderLayout());
      pnlOrder.add(pnlOrderTop, BorderLayout.NORTH);
      pnlOrder.add(pnlOrderBott, BorderLayout.CENTER);
     
      //Add objects to pnlOrderTop
      pnlOrderTop.setLayout(new GridLayout(2,4));
      pnlOrderTop.add(lblStarter);
      pnlOrderTop.add(lblMainCourse);
      pnlOrderTop.add(lblDessert);
      pnlOrderTop.add(lblDrinks);
      pnlOrderTop.add(myStarter);
      pnlOrderTop.add(myMainCourse);
      pnlOrderTop.add(myDessert);
      pnlOrderTop.add(myDrinks);

      //Starters array
      descStarters[0]= "Haddock Chowder";
         descStarters[1]= "French Onion Soup";
         descStarters[2]= "Eggs Florentine";
         descStarters[3]= "Ardennes Pate";
         descStarters[4]= "Quail Salad";
         descStarters[5]= "Thai Tiger Prawns";
      for (int i=0;i<6;i++){
         myStarter.addItem(descStarters[i]);
      }
        
      //Main course array
            descMainCourses[0]= "Breast of Chicken";
         descMainCourses[1]= "Shredded Chilli Beef";
         descMainCourses[2]= "Roast Duck";
         descMainCourses[3]= "Tofu Delight";
         descMainCourses[4]= "Bi Bim Bap";
         descMainCourses[5]= "Spaghetti Bolognaise";
      for (int i=0;i<6;i++){
         myMainCourse.addItem(descMainCourses[i]);
      }
     
      //Dessert array
            descDesserts[0]= "Ice Cream";
         descDesserts[1]= "Fruit Cocktail";
         descDesserts[2]= "Chocolate Gateaux";
         descDesserts[3]= "Lemon Cheesecake";
         descDesserts[4]= "Cheese and Biscuits";
         descDesserts[5]= "Baclava";
      for (int i=0;i<6;i++){
         myDessert.addItem(descDesserts[i]);
      }

      //Drinks array
            descDrinks[0]= "Asahi";
         descDrinks[1]= "Becks";
         descDrinks[2]= "Gin & Tonic";
         descDrinks[3]= "Orange Juice";
         descDrinks[4]= "Remi Martin";
         descDrinks[5]= "Rum & Pineapple";
      for (int i=0;i<6;i++){
         myDrinks.addItem(descDrinks[i]);
      }

      //add objects to pnlOrderBott
      pnlOrderBott.setLayout(new GridLayout(0,2));
      pnlOrderBott.add(pnlOrderBottLeft);
      pnlOrderBott.add(pnlOrderBottRight);
      myOrderBox = new JTextArea(15,15);
      myOrderBox.setLineWrap(true);
      myScrollPane = new JScrollPane(myOrderBox);
      pnlOrderBottRight.add(myScrollPane);
      pnlOrderBottLeft.add(btnReset);
      pnlOrderBottLeft.add(btnRemoveItem);

      //Add objects to pnlTables
      pnlTables.setLayout(new GridLayout(3,2,20,20));
      pnlTables.setBackground(Color.WHITE);
      for (int i=0;i<6;i++){
         btnTables[i]=new JButton("Table "+ (i+1));
         pnlTables.add(btnTables[i]);
         btnTables[i].setBackground(Color.WHITE);
         btnTables[i].setActionCommand("" + i);
         btnTables[i].addActionListener(this);
      }
     
      //Add panels to Bill panel
      pnlBill.setLayout(new BorderLayout());
      pnlBill.add(pnlBillTop, BorderLayout.NORTH);
      pnlBill.add(pnlBillBott, BorderLayout.CENTER);

      //Add label to BillTop
      pnlBillTop.add(lblBillTitle);

      //Add table order/bill text areas to BillBott panel
      pnlBillBott.setLayout(new GridLayout(2,3,2,2));
      for (int i=0;i<6;i++){
         tblOrders[i]=new JTextArea(5,10);
         pnlBillBott.add(tblOrders[i]);
      }

      //Manager Panel
      pnlManager.setLayout(new GridLayout(2,1));
      pnlManager.add(pnlManagerTop);
      pnlManager.add(pnlManagerBott);

      //Manager Top panel
      pnlManagerTop.setLayout(new GridLayout(2,3,5,5));
      for (int k=0;k<6;k++){
         btnTblPay[k]=new JButton("Clear Table "+ (k+1));
         pnlManagerTop.add(btnTblPay[k]);
         btnTblPay[k].setBackground(Color.WHITE);
         btnTblPay[k].setActionCommand("" + k);
         btnTblPay[k].addActionListener(this);
      }

      //Manager Bottom Panel
      pnlManagerBott.setLayout(new GridLayout(2,1,5,5));
      pnlManagerBott.add(lblTillReceipt);
      pnlManagerBott.add(lblTillReceiptTotal);

      //Starter Costs array
      myStarterCosts[0]= 5.00F;
      myStarterCosts[1]= 4.50F;
      myStarterCosts[2]= 6.00F;
      myStarterCosts[3]= 6.00F;
      myStarterCosts[4]= 6.50F;
      myStarterCosts[5]= 7.00F;

      //Main Course Costs array
      myMainCourseCosts[0]= 9.00F;
      myMainCourseCosts[1]= 9.50F;
      myMainCourseCosts[2]= 10.00F;
      myMainCourseCosts[3]= 6.50F;
      myMainCourseCosts[4]= 8.50F;
      myMainCourseCosts[5]= 8.00F;

      //Dessert Costs array
      myDessertCosts[0]= 3.50F;
      myDessertCosts[1]= 4.50F;
      myDessertCosts[2]= 5.00F;
      myDessertCosts[3]= 5.00F;
      myDessertCosts[4]= 4.50F;
      myDessertCosts[5]= 4.00F;

      //Drinks Costs array
      myDrinksCosts[0]= 2.50F;
      myDrinksCosts[1]= 2.50F;
      myDrinksCosts[2]= 3.00F;
      myDrinksCosts[3]= 2.00F;
      myDrinksCosts[4]= 5.00F;
      myDrinksCosts[5]= 3.00F;
         
      // puts the JPanel on the JApplet
      setContentPane(pnlMain);

      //add actionListener
      btnReset.addActionListener(this);
      btnRemoveItem.addActionListener(this);
      myStarter.addActionListener(this);
      myMainCourse.addActionListener(this);
      myDessert.addActionListener(this);
      myDrinks.addActionListener(this);


   }//end init

   
   public void actionPerformed(ActionEvent e){     // ((JButton) e.getSource()).setVisible(false);
     
      //Gather order to myOrderBox and calculate total
      if (e.getSource()==myStarter){
         //set color to black if Clear order button has been pressed
         myOrderBox.setForeground(Color.BLACK);
         int j = myStarter.getSelectedIndex();
         OrderLine line = new OrderLine(j,descStarters[j],myStarterCosts[j]);
         if (remv){
            myBasket.removeOrderLine(line);
            remv=false;
         }else{
            myBasket.addOrderLine(line);
         }
         myOrderBox.setText(myBasket.showContents());
         
      }
      if (e.getSource()==myMainCourse){
         int j = myMainCourse.getSelectedIndex();
         OrderLine line = new OrderLine(j,descMainCourses[j],myMainCourseCosts[j]);
         if (remv){
            myBasket.removeOrderLine(line);
            remv=false;
         }else{
            myBasket.addOrderLine(line);
         }
         myOrderBox.setText(myBasket.showContents());
         
      }
      if (e.getSource()==myDessert){
         int j = myDessert.getSelectedIndex();
         OrderLine line = new OrderLine(j,descDesserts[j],myDessertCosts[j]);
         if (remv){
            myBasket.removeOrderLine(line);
            remv=false;
         }else{
            myBasket.addOrderLine(line);
         }
         myOrderBox.setText(myBasket.showContents());
      }
      if (e.getSource()==myDrinks){
         int j = myDrinks.getSelectedIndex();
         OrderLine line = new OrderLine(j,descDrinks[j],myDrinksCosts[j]);
         if (remv){
            myBasket.removeOrderLine(line);
            remv=false;
         }else{
            myBasket.addOrderLine(line);
         }
         myOrderBox.setText(myBasket.showContents());
      }

      // Clear the order box if Reset button is pressed
      if (e.getSource()==btnReset){
         myBasket.clearIt();
         myOrderBox.setForeground(Color.RED);
         myOrderBox.setText("The order is empty");
      }
     
      // Assign order to Bill Panel for Kitchen staff and
      Object o = e.getSource();
      if (o instanceof JButton){
         String sIndex = ((JButton)o).getActionCommand();
         int index = Integer.parseInt(sIndex);
         updateTblOrder(index);
      }
     
           
   }// end actionPerformed

   // method to update table orders in text areas of Bill panel and show table as occupied (turn button orange)
   public void updateTblOrder(int index){
     
      tblOrders[index].setText(myBasket.showContents());
      btnTables[index].setBackground(Color.ORANGE);
   
   }//end updateTblOrder method

   //method to clear table order from tblOrder Text Areas and show table as unoccupied (turn button back to white)
   public void clearTblOrder(int index){

      tblOrders[index].setText("Table Empty");
      btnTables[index].setBackground(Color.WHITE);
   
   }//end clearTblOrder method

}//end class def


class OrderLine{
   public int id;
   public String description;
   public int quantity;
   public double price;

   public OrderLine(int i,String des,double p){
      this.id = i;
      this.description = des;
      this .price =p;
      this.quantity = 1;
   }
}// end of OrderLine class def

class Basket{
   ArrayList Order= new ArrayList();

   public void clearIt(){
      Order.clear();
   }// end of clearIt method
   
   public void addOrderLine(OrderLine line){
      boolean there = false;
      for(int j =0;j<Order.size();j++){
         OrderLine read = (OrderLine)Order.get(j);

         //the code below which updates quantity of orderlines has been commented out because very
         //often waiters take orders in a certain pattern in order to know where the dishes are  
         //going.  If the quantity is added to, the waiter will have no idea as to which customer
         //ordered which dish

         //if(read.id == line.id){
         //   there = true;
         //   read.quantity++;//if it's there already update its quantity
         //}
      }//end loop
      if(!there){Order.add(line);}// add another instance
   }//end addOrderLine method

   public void removeOrderLine(OrderLine line){
      for(int j =0;j<Order.size();j++){
         OrderLine read = (OrderLine)Order.get(j);
         if(read.id == line.id)read.quantity--;
         if(read.quantity<1){Order.remove(read);}
      }//end loop
   }//end removeOrderLine

   public String showContents(){
      String contents = new String();
      double bill = 0;
     
      for(int j =0;j<Order.size();j++){
         OrderLine read = (OrderLine)Order.get(j);
         contents+=read.quantity+" "+read.description;
         contents+="\n";
         bill+=read.price*read.quantity;
      }
      if(bill>0){
         contents+="\nTotal cost = £"+bill;
         return contents;
      }else{
         return "No order"  ;
      }
   }//end showContents

}//end Basket class def
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

There's nothing wrong with your clearing method. It works fine. There is something wrong with your logic in conjunction with the code i gave you before - if you want code to react only at the appropriate moments, the following will get you out of exception difficulties:

            // Assign order to Bill Panel for Kitchen staff and
            Object o = e.getSource();
            if (o instanceof JButton) {
                  String sIndex = ((JButton) o).getActionCommand();
                  try {
                        int index = Integer.parseInt(sIndex);
                        updateTblOrder(index);
                  }
                  catch (NumberFormatException ex) {
                        /*
                         *  ignore - it will have been caused by one of the wrong buttons being pressed
                         */
                  }

            }


(although strictly speaking you should either check that the right buttons have been clicked, or add a separate ActionListener
Avatar of snowplank
snowplank

ASKER

Thanks.

I didn't realise that I can ad more than one ActionListener.  The next question is how do I do that?  I have written all my code using examples from elsewhere, which is why I am not very creative with Java ;o)
Oh yes you can. In fact the 'modern' Swing way to do things is not to use ActionListeners, but to use Actions. You can do this:

// in your loop for table-clearing buttons
buttons[i].setAction(new ClearTableAction(i));

.......

// This is a named *inner* class
class ClearTableAction extends AbstractAction {
      private int index;
      
      public ClearTableAction(int index) {
            this.index = index;
      }
      
      public void actionPerformed(ActionEvent e) {
            tblOrders[index].setText("Table Empty");
            btnTables[index].setBackground(Color.white);
      }
}
I would definitely recommend you do things that way. You'll find your code much easier to implement and maintain (sooner or later using just one ActionListener is going to get messy - if it hasn't already)
you can codeuse the following technique to have each of your buttons call its own methods instead of having everything in one actionPerformed:

clearButton.addActionListener(new ActionListener()
{
   public void actionPerformed(ActionEvent event)
   {
      doClear();
   }
});
totalButton.addActionListener(new ActionListener()
{
   public void actionPerformed(ActionEvent event)
   {
      doTotal();
   }
});


then have seperate methods to handle each action:

private void doClear()
{
   // handle clear here
}

private void doTotal()
{
   // handle total here
}
Thank you both.

CEHJ, where do I put the "named *inner* class"?  Underneath the btnTblPay[k] in init?  Or in ActionPerformed?
It doesn't matter where you place it as long as it's inside the main class
I get the following error when I compile.

CourseWorkTest.java:185: cannot resolve symbol
symbol  : class ClearTableAction
location: class CourseWorkTest
         btnTblPay[i].setAction(new ClearTableAction(i));
                                                ^
That suggests you *haven't* placed ClearTableAction inside your main class (CourseWorkTest)
Here are 2 snippets where I made the changes you suggested.

//within init

//Manager Top panel
      pnlManagerTop.setLayout(new GridLayout(2,3,5,5));
      for (int i=0;i<6;i++){
         btnTblPay[i]=new JButton("Clear Table "+ (i+1));
         pnlManagerTop.add(btnTblPay[i]);
         btnTblPay[i].setBackground(Color.WHITE);
         btnTblPay[i].setActionCommand("" + i);
         btnTblPay[i].addActionListener(this);
         btnTblPay[i].setAction(new ClearTableAction(i));
      }
--------------------------------------------------------------------
//just after end of actionPerformed

// This is a named *inner* class
   class ClearTableAction extends AbstractAction {
      private int index;
     
      public ClearTableAction(int index) {
          this.index = index;
      }
     
      public void actionPerformed(ActionEvent e) {
          tblOrders[index].setText("Table Empty");
          btnTables[index].setBackground(Color.white);
      }
   }//end of inner class
Place the inner class right after the closing brace of init
My mistake.  I was being a dummer and pasted it into a method.  

Many thanks.

How would you update the "lblTillReceiptTotal" on "pnlManagerBott" with each bill total as the table is cleared?  Would you add code to the inner class or would this require something separate?

 
If it's going to happen as a result of clearing the table, i'd put a method call into the Action. The method should do the totals
I am not sure how to go about turning the text on the "total label" e.g. £340:00 into a double for the purposes of a calculation (i.e. adding another cleared table's bill to this total) and then redisplaying it.

Added another 50 points for this last question :o)
You can use a DecimalFormat for this

DecimalFormat df = new DecimalFormat("0.00");
// convert between double and String
double d = 1.09;
String s = df.format(d);
double x = df.parse("8.67");
Sorry

double x = df.parse("8.67");

should be

double x = df.parse("8.67").doubleValue();
class ClearTableAction extends AbstractAction {
      private int index;
     
      public ClearTableAction(int index) {
          this.index = index;
      }
     
      public void actionPerformed(ActionEvent e) {
          tblOrders[index].setText("Table Empty");
          btnTables[index].setBackground(Color.white);
      }

// this is the method I've written
      public void totalTillReceipt(double tilltotal, double bill) {
         String strtilltotal = lblTillReceiptTotal.getText();
         tilltotal = Integer.parseInt(strtilltotal);
         bill = //how do I get the order total (bill) of the table before I clear it?
         tilltotal = tilltotal + bill;
         lblTillReceiptTotal.setText("£"+tilltotal);
      }

   }//end of ClearTableAction inner class


Once I've done this, how do I invoke the method.  Actuall perhas O mean where do I invoke the method?

 
Sorry just read what I wrote.  Should read "Actually perhaps I mean where do I invoke the method?"  

It's getting late and I've been at work all day ;o)
I would make a separate class perhaps 'Till' with an addToTotal method. You can then call this when you clear a table. You should use the DecimalFormat methods i showed you above. You can use this for getting amounts from labels and putting them back in:

DecimalFormat df = new DecimalFormat("'£'0.00");
For another 100 points can you show me how?
> How would you update the "lblTillReceiptTotal" on "pnlManagerBott" with each bill total
> as the table is cleared?  Would you add code to the inner class or would this require
> something separate?

No you wouldn't do that in your ActionListener, it should be handled seperately by code that maintains the total whenever any changes occur to values being totalled.
Have you thought about using a JTable to display the values?
I would use something like:

      class Till {

            private DecimalFormat df;
            private double total;


            /**
             *Constructor for the Till object
             */
            public Till() {
                  df = new DecimalFormat("'£'0.00");
            }


            /**
             *  Add a table's bill to the total
             *
             * @param  bill  The bill incurred
             */
            public void addToTotal(double bill) {
                  total += bull;
            }


            /**
             *  Gets the total formatted for use in labels
             *
             * @return    The totalFormatted value
             */
            public String getTotalFormatted() {
                  return df.format(total);
            }

      }

A seperate class just to format the total is a little redundant, that would be better handled when the actual update of the field is performed.
That's in the expectation that there will be other till-related operations required later. There in any case should probably be a class that represents this business entity.
I have very limited knowledge of Java I'm afraid.  This little restaurant/menu/ordering GUI is a piece of coursework that I have to hand in tomorrow.  I have already learnt more over the past 2 days from you guys on this site than I had previously over the past 3 months (the length of my java career).  But I am still wandering around in the dark and not really understanding how to implement the ideas you give me.  I only wrote my first class yesterday under the supervision of CEHJ - and that was because he/she pretty much wrote it for me. Backward engineering is my way of learning this stuff.  Like I said previosuly onthis thread, I am not creative with the language.

What I am trying to say is; I don't know what a JTable is; how/where to implement DecimalFormat df; how to write classes that do anything other than the ones I have examples of etc.

> and that was because he/she pretty much wrote it for me.

Thats actually violates the EE member policy on doing homework :)
Fortunately snowplank is being modest - he/she is exaggerating my contribution ;-)
> That's in the expectation that there will be other till-related operations required later.
> There in any case should probably be a class that represents this business entity.

Thats just overcompilicating a simple problem.
Which are the fields being totalled?
>>Thats just overcompilicating a simple problem.

No it isn't - it's just applying standard OO design techniques
>  it's just applying standard OO design techniques

actually it's mixing the data logic with presentation logic which is a no-no :)
I've used the class Till that CEHJ posted.   I am assuming it isn't an inner class (new term I learnt today;o) and therefore I have placed it outside the main class (CourseWorkTest). Is this correct?

Having compiled it, it doesn't like "class DecimalFormat".  Do I need to import something up top?
>>actually it's mixing the data logic with presentation logic

A single method to return a formatted String won't hurt
>>Do I need to import something up top?

import java.text.DecimalFormat;
"Which are the fields being totalled?"

Fields being totalled are "bill+=read.price*read.quantity;" from the basket class near the bottom of the code listed in my original post.
>>Is this correct?

Yes, that's OK
ASKER CERTIFIED SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Ok so I've added the bottom line to this:

//Manager Top panel
      pnlManagerTop.setLayout(new GridLayout(2,3,5,5));
      for (int i=0;i<6;i++){
         btnTblPay[i]=new JButton("Clear Table "+ (i+1));
         pnlManagerTop.add(btnTblPay[i]);
         btnTblPay[i].setBackground(Color.WHITE);
         btnTblPay[i].setForeground(Color.RED);
         btnTblPay[i].setActionCommand("" + i);
         btnTblPay[i].addActionListener(this);
         btnTblPay[i].setAction(new ClearTableAction(i));

So I am calling this class:

class ClearTableAction extends AbstractAction {
      private int index;
     
      public ClearTableAction(int index) {
          this.index = index;
      }
     
      public void actionPerformed(ActionEvent e) {
          tblOrders[index].setText("Table Empty");
          btnTables[index].setBackground(Color.white);
      }
}

And I now have my Till Class:

class Till {
   private DecimalFormat df;
   private double total;
   
   //Constructor for the Till object  
   public Till() {
      df = new DecimalFormat("'£'0.00");
   }

   //Add a table's bill to the total @param  bill  The bill incurred
   
   public void addToTotal(double bill) {
      total += bill;
   }

   //Gets the total formatted for use in labels @return The totalFormatted value
    public String getTotalFormatted() {
      return df.format(total);
    }
}

So how does the order total "bill" (from the class Basket) get used by the ClearTableAction class to add the bill to the label lblTillReceiptTotal?

This OO stuff is really confusing me!
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Today is deadline day unfortunately so I think I'm going to have to leave it as it is.  I'd need more time to get my head around what you guys are suggesting I think.  Thanks both for your help.  I'll spilt the points now.  

Objects, I'd like to see the example that handles totalling automatically if I may?  I wish I'd known about your swing examples a few weeks back when I began this course!

:-)