// ************ class Calc ************************************** import java.awt.*; import java.awt.event.*; import java.math.BigInteger; public class Calc extends java.applet.Applet { private boolean isApplet = true; public void init() { Display display = new Display(); KeyPad keypad = new KeyPad(display, isApplet) ; keypad.decMode(); display.setKeyPad(keypad); display.onScreen(BigInteger.valueOf(0)); String mode = isApplet ? getParameter("mode") : null; if (mode != null) { if ("bin".equals(mode)) keypad.binMode(); else if ("oct".equals(mode)) keypad.octMode(); else if ("hex".equals(mode)) keypad.hexMode(); } setLayout(new BorderLayout()); add("North", display); add("Center", keypad); } public void paint (Graphics g) { Dimension d = getSize(); g.drawRect(0, 0, d.width-1, d.height-1); } public Insets getInsets() { return new Insets(5, 5, 5, 5); } public static void main (String args[]) { Frame f = new Frame("Calc"); Calc calc = new Calc(); calc.isApplet = false; calc.init(); f.setCursor(new Cursor(Cursor.HAND_CURSOR)); f.add("Center", calc); f.pack(); f.setSize(calc.getPreferredSize()); f.setVisible(true); } } // ************* class Display ************************************** final class Display extends Panel { public static final int noop = 0; public static final int equals = 1; public static final int plus = 2; public static final int minus = 3; public static final int times = 4; public static final int divide = 5; public static final int cancel = 6; public static final int neg = 7; public static final int sto1 = 9; public static final int rcl1 = 10; public static final int add1 = 11; public static final int decimal = 12; public static final int hex = 13; public static final int binary = 14; public static final int sqr = 15; public static final int sqrt = 16; public static final int sto2 = 17; public static final int rcl2 = 18; public static final int add2 = 19; public static final int shiftl = 20; public static final int shiftr = 21; public static final int and = 22; public static final int or = 23; public static final int xor = 24; public static final int not = 25; public static final int quit = 26; public static final int octal = 27; private static final String blanks = " "; private TextField screen; private int columns = 30; private int curop = noop; private boolean firstdigit = true; private boolean after_unop = false; private BigInteger x = BigInteger.valueOf(0); private BigInteger y = BigInteger.valueOf(0); private BigInteger m1 = BigInteger.valueOf(0); private BigInteger m2 = BigInteger.valueOf(0); private int radix = 16; private KeyPad keypad; Display() { Font f = new Font("Courier", Font.BOLD, 18); screen = new TextField(columns); screen.setFont(f); screen.setEditable(false); add(screen); } public void setKeyPad (KeyPad keypad) { this.keypad = keypad; } BigInteger sqrt (BigInteger x) { BigInteger r = BigInteger.valueOf(0); BigInteger m = r.setBit(2*x.bitLength()); BigInteger nr; do { nr = r.add(m); if (nr.compareTo(x) != 1) { x = x.subtract(nr); r = nr.add(m); } r = r.shiftRight(1); m = m.shiftRight(2); } while (m.bitCount() != 0); // Comment this in if you want the result rounded // if (x.compareTo(r) == 1) // r = r.add(BigInteger.valueOf(1)); return r; } public void onScreen (BigInteger bi) { String s = bi.toString(radix); int l = s.length(); if (l < columns) screen.setText(blanks.substring(0, columns - l) + s); else screen.setText(s); } public void numberPress (int n) { if (after_unop) return; if (firstdigit) { y = BigInteger.valueOf(n); firstdigit = false; } else { y = y.multiply(BigInteger.valueOf(radix)).add(BigInteger.valueOf(n)); } onScreen(y); } public void operPress (int op) throws ArithmeticException { boolean again = true; while (again) { again = false; switch (op) { case quit: System.exit(0); break; case cancel: x = BigInteger.valueOf(0); y = BigInteger.valueOf(0); curop = noop; break; case sto1: if (firstdigit) m1 = x; else m1 = y; return; case rcl1: y = m1; firstdigit = false; after_unop = true; onScreen(y); return; case add1: if (firstdigit) m1 = m1.add(x); else m1 = m1.add(y); return; case sto2: if (firstdigit) m2 = x; else m2 = y; return; case rcl2: y = m2; firstdigit = false; after_unop = true; onScreen(y); return; case add2: if (firstdigit) m2 = m2.add(x); else m2 = m2.add(y); return; case hex: case decimal: case octal: case binary: switch (op) { case hex: radix = 16; keypad.hexMode(); break; case decimal: radix = 10; keypad.decMode(); break; case octal: radix = 8; keypad.octMode(); break; case binary: radix = 2; keypad.binMode(); break; } op = equals; again = true; break; case not: if (!firstdigit) { y = y.not(); onScreen(y); return; } x = x.not(); y = x; curop = noop; break; case neg: if (curop == noop) { if (firstdigit) x = x.negate(); else x = y.negate(); y = x; } else if (firstdigit) return; else { y = y.negate(); onScreen(y); after_unop = true; return; } after_unop = true; onScreen(x); return; case sqr: if (curop == noop) { if (firstdigit) x = x.multiply(x); else x = y.multiply(y); y = x; } else if (firstdigit) return; else { y = y.multiply(y); onScreen(y); after_unop = true; return; } after_unop = true; onScreen(x); return; case sqrt: if (curop == noop) { if (firstdigit) x = sqrt(x); else x = sqrt(y); y = x; } else if (firstdigit) return; else { y = sqrt(y); onScreen(y); after_unop = true; return; } after_unop = true; onScreen(x); return; case equals: op = noop; /* fall through */ case plus: case minus: case times: case divide: case and: case or: case xor: case shiftl: case shiftr: switch (curop) { case plus: x = x.add(y); break; case minus: x = x.subtract(y); break; case times: x = x.multiply(y); break; case shiftl: x = x.shiftLeft(y.intValue()); break; case shiftr: x = x.shiftRight(y.intValue()); break; case and: x = x.and(y); break; case or: x = x.or(y); break; case xor: x = x.xor(y); break; case divide: try { x = x.divide(y); } catch (ArithmeticException e) { x = BigInteger.valueOf(0); } break; case noop: x = y; break; default: break; } y = x; curop = op; break; default: System.out.println("Unexpected operator"); } firstdigit = true; after_unop = false; onScreen(x); } } } // ************* class KeyPad *********************************** final class KeyPad extends Panel { static String keyname[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" }; private NumKey key[] = new NumKey[16]; private OperKey hexKey, decKey, octKey, binKey; KeyPad (Display display, boolean isApplet) { int i; setLayout(new GridLayout(7, 6, 5, 5)); if (isApplet) add(new NullKey()); else add(new OperKey(display, "Off", display.quit)); add(new OperKey(display, "C", display.cancel)); hexKey = new OperKey(display, "hex", Display.hex); add(hexKey); decKey = new OperKey(display, "dec", Display.decimal); add(decKey); octKey = new OperKey(display, "oct", Display.octal); add(octKey); binKey = new OperKey(display, "bin", Display.binary); add(binKey); for (i = 0xd; i <= 0xf; i++) { key[i] = new NumKey(display, keyname[i], i); add(key[i]); } add(new OperKey(display, "S m1", display.sto1)); add(new OperKey(display, "R m1", display.rcl1)); add(new OperKey(display, "+ m1", display.add1)); for (i = 0xa; i <= 0xc; i++) { key[i] = new NumKey(display, keyname[i], i); add(key[i]); } add(new OperKey(display, "S m2", display.sto2)); add(new OperKey(display, "R m2", display.rcl2)); add(new OperKey(display, "+ m2", display.add2)); for (i = 7; i <= 9; i++) { key[i] = new NumKey(display, keyname[i], i); add(key[i]); } add(new OperKey(display, "/", display.divide)); add(new OperKey(display, "x^2", display.sqr)); add(new OperKey(display, "sqrt", display.sqrt)); for (i = 4; i <= 6; i++) { key[i] = new NumKey(display, keyname[i], i); add(key[i]); } add(new OperKey(display, "*", display.times)); add(new OperKey(display, "<<", display.shiftl)); add(new OperKey(display, ">>", display.shiftr)); for (i = 1; i <= 3; i++) { key[i] = new NumKey(display, keyname[i], i); add(key[i]); } add(new OperKey(display, "-", display.minus)); add(new OperKey(display, "&", display.and)); add(new OperKey(display, "|", display.or)); key[0] = new NumKey(display, keyname[0], 0); add(key[0]); add(new OperKey(display, "+/-", display.neg)); add(new OperKey(display, "=", display.equals)); add(new OperKey(display, "+", display.plus)); add(new OperKey(display, "^", display.xor)); add(new OperKey(display, "~", display.not)); setFont(new Font("Helvetica", Font.BOLD, 14)); } public void hexMode() { for (int i = 2; i < 16; i++) key[i].setEnabled(true); hexKey.setEnabled(false); decKey.setEnabled(true); octKey.setEnabled(true); binKey.setEnabled(true); } public void decMode() { int i; for (i = 2; i < 10; i++) key[i].setEnabled(true); for ( ; i < 16 ; i++) key[i].setEnabled(false); hexKey.setEnabled(true); decKey.setEnabled(false); octKey.setEnabled(true); binKey.setEnabled(true); } public void octMode() { int i; for (i = 2; i < 8; i++) key[i].setEnabled(true); for ( ; i < 16 ; i++) key[i].setEnabled(false); hexKey.setEnabled(true); decKey.setEnabled(true); octKey.setEnabled(false); binKey.setEnabled(true); } public void binMode() { for (int i = 2; i < 16; i++) key[i].setEnabled(false); hexKey.setEnabled(true); decKey.setEnabled(true); octKey.setEnabled(true); binKey.setEnabled(false); } } // ************* class NullKey *********************************** final class NullKey extends Button { NullKey() { setBackground(Color.gray); setForeground(Color.white); this.setEnabled(false); } } // ************* class NumKey *********************************** final class NumKey extends Button implements ActionListener { private int value; private Display display; NumKey (Display display, String label, int initvalue) { setBackground(Color.white); setForeground(Color.black); setLabel(label); value = initvalue; this.display = display; addActionListener(this); } public void actionPerformed (ActionEvent e) { display.numberPress(value); } } // ************* class OperKey *********************************** final class OperKey extends Button implements ActionListener { private Display display; private int op; OperKey (Display display, String label, int op) { setBackground(Color.gray); setForeground(Color.white); setLabel(label); this.display = display; this.op = op; addActionListener(this); } public void actionPerformed (ActionEvent e) { display.operPress(op); } }