// // Calculator4App // // Created by Edward on 2/12/06 // Last modified 2/21/06 // import java.awt.*; import java.awt.event.*; import java.applet.*; import javax.swing.*; import java.text.*; // for DecimalFormat public class Calculator4App extends JApplet { /** * Numbers are entered into a string, curDisplay, whose value is stored in cur * The booleans help keep track of order of operations and proper display * Future improvements: * - perhaps stop user from entering too many digits */ String curDisplay = "0"; double cur = 0; boolean pHold = false; // is there addition waiting to happen? boolean mHold = false; // is there subtraction waiting to happen? boolean tPend = false; // is there multiplication waiting to happen? boolean dPend = false; // is there division waiting to happen? boolean fn = false; // was the last button a function key? boolean decFlag = false; // should we display a superfluous decimal? double addHold = 0; double pending = 0; double mem = 0; JButton but1; JButton but2; JButton but3; JButton but4; JButton but5; JButton but6; JButton but7; JButton but8; JButton but9; JButton but0; JButton butDec; JButton butEq; JButton butC; JButton butMRC; JButton butMin; JButton butPM; JButton butDivide; JButton butTimes; JButton butMinus; JButton butPlus; Font myFont = new Font("monospaced",0,18); DecimalFormat myFormat = new DecimalFormat("0.##########"); DecimalFormat sciFormat = new DecimalFormat("0.##########E0"); /** * the InputMap and ActionMap stuff allows keyboard entry * Future improvements: * - make keyboard keys light up the relevant buttons */ public void setUpGUI() { // set the default look and feel String laf = UIManager.getSystemLookAndFeelClassName(); try { UIManager.setLookAndFeel(laf); } catch (UnsupportedLookAndFeelException exc) { System.err.println ("Warning: UnsupportedLookAndFeel: " + laf); } catch (Exception exc) { System.err.println ("Error loading " + laf + ": " + exc); } // define buttons but1 = new JButton("1"); but1.addActionListener(keyAction); but1.getInputMap(but1.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('1'),"typed"); but1.getActionMap().put("typed", keyAction); but2 = new JButton("2"); but2.addActionListener(keyAction); but2.getInputMap(but2.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('2'),"typed"); but2.getActionMap().put("typed", keyAction); but3 = new JButton("3"); but3.addActionListener(keyAction); but3.getInputMap(but3.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('3'),"typed"); but3.getActionMap().put("typed", keyAction); but4 = new JButton("4"); but4.addActionListener(keyAction); but4.getInputMap(but4.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('4'),"typed"); but4.getActionMap().put("typed", keyAction); but5 = new JButton("5"); but5.addActionListener(keyAction); but5.getInputMap(but5.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('5'),"typed"); but5.getActionMap().put("typed", keyAction); but6 = new JButton("6"); but6.addActionListener(keyAction); but6.getInputMap(but6.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('6'),"typed"); but6.getActionMap().put("typed", keyAction); but7 = new JButton("7"); but7.addActionListener(keyAction); but7.getInputMap(but7.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('7'),"typed"); but7.getActionMap().put("typed", keyAction); but8 = new JButton("8"); but8.addActionListener(keyAction); but8.getInputMap(but8.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('8'),"typed"); but8.getActionMap().put("typed", keyAction); but9 = new JButton("9"); but9.addActionListener(keyAction); but9.getInputMap(but9.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('9'),"typed"); but9.getActionMap().put("typed", keyAction); but0 = new JButton("0"); but0.addActionListener(keyAction); but0.getInputMap(but0.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('0'),"typed"); but0.getActionMap().put("typed", keyAction); butDec = new JButton("."); butDec.addActionListener(keyAction); butDec.getInputMap(butDec.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('.'),"typed"); butDec.getActionMap().put("typed", keyAction); butEq = new JButton("="); butEq.addActionListener(opAction); butEq.getInputMap(butEq.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('='),"typed"); butEq.getActionMap().put("typed", opAction); butC = new JButton("C"); butC.addActionListener(opAction); butMRC = new JButton("MRC"); butMRC.addActionListener(opAction); butMRC.setToolTipText("Memory recall"); butMin = new JButton("M in"); butMin.addActionListener(opAction); butMin.setToolTipText("Store this value in memory"); butPM = new JButton("+/-"); butPM.addActionListener(opAction); butDivide = new JButton("/"); butDivide.addActionListener(opAction); butDivide.getInputMap(butDivide.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('/'),"typed"); butDivide.getActionMap().put("typed", opAction); butTimes = new JButton("x"); butTimes.addActionListener(opAction); butTimes.getInputMap(butTimes.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('*'),"typed"); butTimes.getActionMap().put("typed", opAction); butMinus = new JButton("-"); butMinus.addActionListener(opAction); butMinus.getInputMap(butMinus.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('-'),"typed"); butMinus.getActionMap().put("typed", opAction); butPlus = new JButton("+"); butPlus.addActionListener(opAction); butPlus.getInputMap(butPlus.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('+'),"typed"); butPlus.getActionMap().put("typed", opAction); // set up the button panel, a pain in the... JPanel butPane = new JPanel(); butPane.setLayout(new GridLayout(5,4)); butPane.add(butC); butPane.add(butPM); butPane.add(butMin); butPane.add(butMRC); butPane.add(but7); butPane.add(but8); butPane.add(but9); butPane.add(butDivide); butPane.add(but4); butPane.add(but5); butPane.add(but6); butPane.add(butTimes); butPane.add(but1); butPane.add(but2); butPane.add(but3); butPane.add(butMinus); butPane.add(but0); butPane.add(butDec); butPane.add(butEq); butPane.add(butPlus); // wasn't that fun? now for the main panel JPanel pane = new JPanel(); pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS)); pane.add(Box.createRigidArea(new Dimension(0,32))); pane.add(butPane); setContentPane(pane); } /* * NumKeyAction handles the number entry buttons * OpKeyAction handles the other buttons */ class NumKeyAction extends AbstractAction { public void actionPerformed(ActionEvent e) { Object src = e.getSource(); if (src == but1) { keyN(1); } else { if (src == but2) { keyN(2); } else { if (src == but3) { keyN(3); } else { if (src == but4) { keyN(4); } else { if (src == but5) { keyN(5); } else { if (src == but6) { keyN(6); } else { if (src == but7) { keyN(7); } else { if (src == but8) { keyN(8); } else { if (src == but9) { keyN(9); } else { if (src == but0) { keyN(0); } else { if (src == butDec) { keyDec(); }}}}}}}}}}} } } NumKeyAction keyAction = new NumKeyAction(); // put some of the boolean stuff into this action to shorten code class OpKeyAction extends AbstractAction { public void actionPerformed(ActionEvent e) { Object src = e.getSource(); if (src == butPlus) { keyPlus(); } else { if (src == butMinus) { keyMinus(); } else { if (src == butTimes) { keyTimes(); } else { if (src == butDivide) { keyDivide(); } else { if (src == butEq) { keyEq(); } else { if (src == butC) { keyC(); } else { if (src == butMRC) { keyMRC(); } else { if (src == butMin) { keyMin(); } else { if (src == butPM) { keyPM(); }}}}}}}}} } } OpKeyAction opAction = new OpKeyAction(); /** * keyN handles the entry of a number key * the other key things handle their respective buttons */ public void keyN(int n) { curDisplay = ((fn || curDisplay == "0") ? String.valueOf(n) : curDisplay+n); repaint(); fn = false; } public void keyDec() { if (fn) { curDisplay = "0."; } else { if (curDisplay.indexOf('.') == -1) { curDisplay += "."; } } repaint(); fn = false; decFlag = true; } public void keyEq() { // check if any multiplication or division is pending if (tPend) { cur *= pending; tPend = false; } else { if (dPend) { cur = pending / cur; dPend = false; } } // check if any addition or subtraction is pending if (pHold) { cur += addHold; pHold = false; } else { if (mHold) { cur = addHold - cur; mHold = false; } } curDisplay = String.valueOf(cur); repaint(); fn = true; decFlag = false; } public void keyC() { curDisplay = "0"; repaint(); pHold = false; mHold = false; tPend = false; dPend = false; fn = false; decFlag = false; } public void keyMRC() { curDisplay = String.valueOf(mem); repaint(); fn = true; decFlag = false; } public void keyMin() { mem = cur; fn = true; } public void keyPM() { if (curDisplay != "0") { curDisplay = ((curDisplay.charAt(0) == '-') ? curDisplay.substring(1) : "-"+curDisplay); repaint(); } fn = false; } public void keyDivide() { if (dPend) { cur = pending / cur; } else { if (tPend) { cur *= pending; tPend = false; } dPend = true; } // ignore any pending addition or subtraction pending = cur; curDisplay = String.valueOf(cur); repaint(); fn = true; decFlag = false; } public void keyTimes() { if (tPend) { cur *= pending; } else { if (dPend) { cur = pending / cur; dPend = false; } tPend = true; } pending = cur; curDisplay = String.valueOf(cur); repaint(); fn = true; decFlag = false; } public void keyMinus() { if (tPend) { cur *= pending; tPend = false; } else { if (dPend) { cur = pending / cur; dPend = false; } } if (mHold) { cur = addHold - cur; } else { if (pHold) { cur += addHold; pHold = false; } mHold = true; } addHold = cur; curDisplay = String.valueOf(cur); repaint(); fn = true; decFlag = false; } public void keyPlus() { if (tPend) { cur *= pending; tPend = false; } else { if (dPend) { cur = pending / cur; dPend = false; } } if (pHold) { cur += addHold; } else { if (mHold) { cur = addHold - cur; mHold = false; } pHold = true; } addHold = cur; curDisplay = String.valueOf(cur); repaint(); fn = true; decFlag = false; } public void init() { setUpGUI(); } public void paint (Graphics g) { super.paint(g); g.setFont(myFont); cur = Double.valueOf(curDisplay).doubleValue(); if ((cur < 10000000000.0) && ((cur > .00000001) || (cur == 0) || (cur < -.00000001)) && (!decFlag)) { g.drawString(myFormat.format(cur), 32, 24); } else { if (!decFlag) { g.drawString(sciFormat.format(cur), 32, 24); } else { g.drawString(curDisplay, 32, 24); } } } }