1 /* A pizza-order example, based largely on the CGI example */ 2 /* by N.J. McCracken. This program by Ernest Sibert */ 3 4 import java.awt.*; 5 6 7 public class Pizza extends java.applet.Applet { 8 public static final int gsize = 16; /* General font size, font */ 9 public static final Font gfont = new Font("Helvetica", Font.PLAIN, gsize); 10 11 String address, city; /* Info. about the shop (from HTML) */ 12 double tax; /* Sales tax rate for locality */ 13 14 PizzaSML sml; /* Panel for pizza size */ 15 Toppings tops; /* Panel for topping selection */ 16 Name name; /* Panel for email address */ 17 String email = null; /* The email address */ 18 Button order; /* "Place Order" button */ 19 boolean hasBill; /* Have we made a bill already? */ 20 Bill bill; /* The bill */ 21 Button confirm; /* "Confirm Order" button */ 22 boolean hasConfirmation; /* Have we confirmed an order? */ 23 TextField message; /* Confirmation message, others */ 24 25 public void init() { 26 address = getParameter("address"); 27 city = getParameter("city"); 28 tax = (Double.valueOf(getParameter("tax"))).doubleValue(); 29 setLayout(new FlowLayout(FlowLayout.CENTER, 10, 4)); 30 Top top = new Top(36); /* Arg is font size */ 31 Loc loc = new Loc(address, city, gsize); 32 add(top); add(loc); 33 sml = new PizzaSML(gfont); add(sml); 34 add(new Label("--------------------- Toppings ---------------------")); 35 tops = new Toppings(gfont); 36 add(tops); 37 name = new Name(gfont); add(name); 38 order = new Button("Place Order"); add(order); 39 confirm = new Button("Confirm Order"); add(confirm); 40 hasBill = false; hasConfirmation = false; /* Neither yet */ 41 bill = new Bill(gfont); add(bill); 42 message = new TextField( 43 " Welcome to ECStasy Pizza", 44 60); 45 message.setEditable(false); add(message); 46 } 47 48 /* Deal with relevant events */ 49 50 public boolean action(Event evt, Object arg) { 51 Object tgt = evt.target; /* The target object */ 52 boolean result = false; /* result */ 53 if ( tgt instanceof Button ) { 54 if ( tgt == order ) { 55 result = handleOrder(); 56 } else { 57 if ( tgt == confirm ) { 58 result = handleConfirm(); 59 } else return false; 60 } 61 } else return false; 62 return result; 63 } 64 65 /* Place order */ 66 67 boolean handleOrder() { 68 email = name.getText(); /* We could check more carefully */ 69 try { 70 bill.enterPrice(this, sml.pSize(), tops.countTops()); 71 message.setText( 72 "Click Confirm or change order and click Place Order."); 73 hasBill = true; hasConfirmation = false; 74 } catch (/* StringIndexOutOfBounds */ Exception ex) { 75 message.setText("Sorry "+ex.toString()+"try again tomorrow."); 76 hasBill = false; 77 } 78 return true; 79 } 80 81 /* Confirm order */ 82 83 boolean handleConfirm() { 84 if ( hasConfirmation ) { 85 message.setText( 86 "Place another order, then click Confirm after you receive the bill."); 87 hasConfirmation = false; 88 } else if ( hasBill ) { 89 message.setText( 90 "Thank you for your order; your account has been debited."); 91 hasConfirmation = true; 92 } else { 93 message.setText( 94 "Place an order first; click Confirm after you receive the bill."); 95 } 96 return true; 97 } 98 99 } // end Pizza class 100 101 102 class Top extends Panel { /* Flashy top panel */ 103 Top(int size) { 104 setLayout(new FlowLayout()); 105 setFont(new Font("TimesRoman", Font.BOLD+Font.ITALIC, size)); 106 setForeground(Color.orange); setBackground(Color.blue); 107 add(new Label("ECStasy Pizza", Label.CENTER)); 108 } 109 } 110 111 112 class Loc extends Panel { /* Shop address, location, font size */ 113 Loc(String address, String city, int size) { 114 setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10)); 115 setFont(new Font("TimesRoman", Font.ITALIC, size)); 116 setForeground(Color.orange); setBackground(Color.blue); 117 add(new Label(address, Label.LEFT)); 118 add(new Label(city, Label.CENTER)); 119 } 120 } 121 122 123 class PizzaSML extends Panel { 124 public static final int SMALL = 1, MEDIUM = 2, LARGE = 3; 125 CheckboxGroup sizeBoxes; 126 127 PizzaSML(Font gfont) { 128 setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10)); 129 setFont(gfont); 130 /* Pizza size with a group of checkboxes */ 131 add(new Label("Size: ")); 132 sizeBoxes = new CheckboxGroup(); 133 add(new Checkbox("small", sizeBoxes, false)); 134 add(new Checkbox("medium", sizeBoxes, false)); 135 add(new Checkbox("large", sizeBoxes, true )); 136 } 137 138 int pSize() { 139 String clabel = sizeBoxes.getCurrent().getLabel(); 140 /* clabel is label of Currently selected button */ 141 if ( clabel.equals("small" )) return SMALL; else 142 if ( clabel.equals("medium")) return MEDIUM; else 143 return LARGE; 144 } 145 146 } // end PizzaSML class 147 148 149 class Toppings extends Panel { 150 private static int nTop = 6; /* Number of choices */ 151 Checkbox item[]; /* Topping selections */ 152 153 Toppings(Font gfont) { 154 setLayout(new GridLayout(2, 3, 10, 10)); setFont(gfont); 155 if ( nTop > 64 ) { /* Too many toppings for bitvector */ 156 add(new Label("TOO")); add(new Label(" MANY")); 157 add(new Label("TOPPINGS")); 158 } 159 item = new Checkbox[nTop]; 160 item[0] = new Checkbox("Pepperoni" ); add(item[0]); 161 item[1] = new Checkbox("Extra Cheese"); add(item[1]); 162 item[2] = new Checkbox("Sausage"); add(item[2]); 163 item[3] = new Checkbox("Onions"); add(item[3]); 164 item[4] = new Checkbox("Peppers"); add(item[4]); 165 item[5] = new Checkbox("Dead Fish"); add(item[5]); 166 } 167 168 int countTops() { /* Returns number of toppings chosen */ 169 int n = 0; 170 for ( int i = 0; i < nTop; i++ ) 171 if ( item[i].getState() ) n++; 172 return n; 173 } 174 175 /* Returns long viewed as bit vector - bit 2^i represents topping i */ 176 177 long topSelection() { 178 long bt = 0; 179 for ( int i = 0; i < nTop; i++ ) 180 if ( item[i].getState() ) bt |= 1<<i; 181 return bt; 182 } 183 184 } // end Toppings class 185 186 187 class Name extends Panel { 188 TextField name; 189 190 Name(Font gfont) { 191 setLayout(new FlowLayout()); setFont(gfont); 192 add(new Label("email address: ")); 193 name = new TextField(40); 194 name.setFont(gfont); add(name); 195 } 196 197 String getText() { return name.getText(); } 198 } 199 200 /********************************************************/ 201 /* Prices are recorded in pennies, printed as dollars */ 202 /********************************************************/ 203 204 class Bill extends Panel { 205 long pPrice, tPrice, subtotal, tax, total; /* Amounts */ 206 207 static final Label subl = new Label("Subtotal"); /* Fixed labels */ 208 static final Label taxl = new Label("Tax"); 209 static final Label totl = new Label("Total"); 210 211 static final int dchars = 8; /* Spaces for amounts */ 212 /* This is $dddd.dd */ 213 214 static final String blank = " "; /* dchars blanks */ 215 static final String dblank = "$ "; /* with $ */ 216 static final String errstr = "$ ERROR "; /* For errors */ 217 218 /* Adjustable labels */ 219 220 Label lPizza = new Label("Your pizza"); 221 Label lTops = new Label("Your toppings"); 222 Label lPPrice = new Label(dblank, Label.RIGHT); 223 Label lTPrice = new Label(blank, Label.RIGHT); 224 Label lSubt = new Label(blank, Label.RIGHT); 225 Label lTax = new Label(blank, Label.RIGHT); 226 Label lTotal = new Label(dblank, Label.RIGHT); 227 228 229 /* Create a blank bill */ 230 231 Bill (Font gfont) { 232 setLayout(new GridLayout(5, 2, 30, 5)); 233 setFont(gfont); setBackground(Color.green); 234 add(lPizza); add(lPPrice); 235 add(lTops); add(lTPrice); 236 add(subl); add(lSubt); 237 add(taxl); add(lTax); 238 add(totl); add(lTotal); 239 } 240 241 public Insets insets() { /* Specify small insets */ 242 return new Insets(10, 10, 10, 10); 243 } /* top, bot, lft rgt */ 244 245 246 /* Compute the bill. TaxRate is in percent, e.g., */ 247 /* 7.0 for a 7% tax */ 248 249 void enterPrice(Pizza pizza, int pSize, int nTops) 250 throws StringIndexOutOfBoundsException { 251 String plabel = (pSize == PizzaSML.SMALL ) ? "Small " : 252 (pSize == PizzaSML.MEDIUM) ? "Medium" : "Large " ; 253 lPizza.setText(plabel + " pizza"); 254 pPrice = 600 + pSize*100; 255 lPPrice.setText(dollar(pPrice, true)); 256 String tlabel = (nTops == 0) ? "No toppings" : 257 (nTops == 1) ? "1 topping" : 258 nTops + " toppings" ; 259 lTops.setText(tlabel); 260 tPrice = nTops*(50 + pSize*25); 261 lTPrice.setText(dollar(tPrice, false)); 262 subtotal = pPrice + tPrice; 263 lSubt.setText(dollar(subtotal, false)); 264 tax = Math.round(subtotal*pizza.tax/100.0D); 265 lTax.setText(dollar(tax, false)); 266 total = subtotal + tax; 267 lTotal.setText(dollar(total, true)); 268 } 269 270 /* Format long (pennies) as dollars, ( with $ ) */ 271 272 static String dollar(long amt, boolean dsign) 273 throws StringIndexOutOfBoundsException { 274 StringBuffer dbuff = new StringBuffer("$."); 275 int i; 276 if ( !dsign ) dbuff.setCharAt(0, ' '); /* Dollar sign */ 277 String ast = Long.toString(amt); 278 int slen = ast.length(); /* length of string */ 279 if ( slen > dchars - 2 ) return errstr; /* Too big */ 280 if ( slen == 1 ) { /* Very small value */ 281 ast = "0" + ast; slen = 2; } 282 int sfst = dchars - slen - 1; /* position of 1st char */ 283 /* Digits before decimal point */ 284 dbuff.insert(1, ast.substring(0, slen - 2)); 285 /* Initial blanks */ 286 for (i = 1; i < sfst; i++ ) dbuff.insert(1, ' '); 287 /* Last two digits */ 288 dbuff.append(ast.substring(slen-2, slen)); 289 return dbuff.toString(); 290 } 291 292 } // end Bill class