summaryrefslogtreecommitdiff
path: root/projects/project2_LInfiniteInteger/InfiniteIntegerCalculatorFrame.java
diff options
context:
space:
mode:
authorAlexander Pickering <alexandermpickering@gmail.com>2017-02-06 11:41:36 -0500
committerAlexander Pickering <alexandermpickering@gmail.com>2017-02-06 11:41:36 -0500
commit89cdf3efb49335e7c07a68a5a64657eeec2288a6 (patch)
treecdc0fd8165e65b1637fa54cac11c932acefc8a89 /projects/project2_LInfiniteInteger/InfiniteIntegerCalculatorFrame.java
downloadcoe0445-master.tar.gz
coe0445-master.tar.bz2
coe0445-master.zip
Inital commitHEADmaster
Diffstat (limited to 'projects/project2_LInfiniteInteger/InfiniteIntegerCalculatorFrame.java')
-rw-r--r--projects/project2_LInfiniteInteger/InfiniteIntegerCalculatorFrame.java495
1 files changed, 495 insertions, 0 deletions
diff --git a/projects/project2_LInfiniteInteger/InfiniteIntegerCalculatorFrame.java b/projects/project2_LInfiniteInteger/InfiniteIntegerCalculatorFrame.java
new file mode 100644
index 0000000..6e88ff8
--- /dev/null
+++ b/projects/project2_LInfiniteInteger/InfiniteIntegerCalculatorFrame.java
@@ -0,0 +1,495 @@
+import java.awt.BorderLayout;
+import java.awt.Font;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyListener;
+import java.util.ArrayList;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+
+@SuppressWarnings("serial")
+public class InfiniteIntegerCalculatorFrame extends JFrame
+{
+ private JButton[] numberButtons; // number buttons (0 to 9)
+ private JButton plusButton; // plus button (+)
+ private JButton minusButton; // minus button (-)
+ private JButton multiplyButton; // multiply button (*)
+ private JButton backButton; // back button (<-)
+ private JButton equalButton; // equal button (=)
+ private JButton clearButton; //clear button (C)
+ private JTextArea textArea; // Text area for expression and result
+ private JPanel buttonPanel; // panel for all buttons
+ private ArrayList<String> ppString; // Pretty printing string
+ private KeyListener kListener;
+
+ public InfiniteIntegerCalculatorFrame()
+ {
+ textArea = new JTextArea();
+ textArea.setText("0");
+ textArea.setEditable(false);
+ textArea.setLineWrap(true);
+
+ kListener = new KeyEvent();
+ textArea.addKeyListener(kListener);
+
+ Font font = new Font(Font.SERIF, Font.BOLD, 20);
+ textArea.setFont(font);
+
+ setButtonsAndPanel();
+
+ add(buttonPanel, BorderLayout.EAST);
+ add(textArea, BorderLayout.CENTER);
+
+ ppString = new ArrayList<String>();
+ ppString.add("0");
+ }
+
+ public class KeyEvent implements KeyListener
+ {
+ public void keyPressed(java.awt.event.KeyEvent arg0)
+ {
+ int keyCode = arg0.getKeyCode();
+ char keyChar = arg0.getKeyChar();
+
+ if(keyCode >= 48 && keyCode <=57 && keyChar != '*')
+ {
+ ButtonListener bl = new ButtonListener(keyCode - 48);
+ bl.actionPerformed(new ActionEvent(numberButtons[keyCode - 48], 1001, "" + (keyCode - 48)));
+ }
+ else if(keyCode >= 96 && keyCode <= 105)
+ {
+ ButtonListener bl = new ButtonListener(keyCode - 96);
+ bl.actionPerformed(new ActionEvent(numberButtons[keyCode - 96], 1001, "" + (keyCode - 96)));
+ }
+ else if(keyCode == 61 && keyChar == '+')
+ {
+ ButtonListener bl = new ButtonListener(10);
+ bl.actionPerformed(new ActionEvent(equalButton, 1001, "+"));
+ }
+ else if(keyCode == 107)
+ {
+ ButtonListener bl = new ButtonListener(10);
+ bl.actionPerformed(new ActionEvent(equalButton, 1001, "+"));
+ }
+ else if(keyCode == 45 && keyChar == '-')
+ {
+ ButtonListener bl = new ButtonListener(11);
+ bl.actionPerformed(new ActionEvent(minusButton, 1001, "-"));
+ }
+ else if(keyCode == 109)
+ {
+ ButtonListener bl = new ButtonListener(11);
+ bl.actionPerformed(new ActionEvent(minusButton, 1001, "-"));
+ }
+ else if(keyCode == 56 && keyChar == '*')
+ {
+ ButtonListener bl = new ButtonListener(12);
+ bl.actionPerformed(new ActionEvent(multiplyButton, 1001, "*"));
+ }
+ else if(keyCode == 106)
+ {
+ ButtonListener bl = new ButtonListener(12);
+ bl.actionPerformed(new ActionEvent(multiplyButton, 1001, "*"));
+ }
+ else if(keyCode == 8)
+ {
+ ButtonListener bl = new ButtonListener(13);
+ bl.actionPerformed(new ActionEvent(backButton, 1001, "<-"));
+ }
+ else if(keyCode == 61 && keyChar == '=')
+ {
+ ButtonListener bl = new ButtonListener(14);
+ bl.actionPerformed(new ActionEvent(equalButton, 1001, "="));
+ }
+ else if(keyCode == 10)
+ {
+ ButtonListener bl = new ButtonListener(14);
+ bl.actionPerformed(new ActionEvent(equalButton, 1001, "="));
+ }
+ else if(keyCode == 67)
+ {
+ ButtonListener bl = new ButtonListener(15);
+ bl.actionPerformed(new ActionEvent(clearButton, 1001, "C"));
+ }
+ }
+
+ public void keyReleased(java.awt.event.KeyEvent arg0)
+ {
+ }
+
+ public void keyTyped(java.awt.event.KeyEvent arg0)
+ {
+ }
+ }
+
+ /**
+ * setButtonsAndPanel
+ *
+ * Initialize all buttons, initialize the button panel,
+ * and add all buttons into button panel.
+ */
+ private void setButtonsAndPanel()
+ {
+ numberButtons = new JButton[10];
+ ButtonListener[] nbls = new ButtonListener[16];
+ for(int i = 0; i <= 9; i++)
+ {
+ numberButtons[i] = new JButton("" + i);
+ nbls[i] = new ButtonListener(i);
+ numberButtons[i].addActionListener(nbls[i]);
+ }
+
+ plusButton = new JButton("+");
+ nbls[10] = new ButtonListener(10);
+ plusButton.addActionListener(nbls[10]);
+
+ minusButton = new JButton("-");
+ nbls[11] = new ButtonListener(11);
+ minusButton.addActionListener(nbls[11]);
+
+ multiplyButton = new JButton("*");
+ nbls[12] = new ButtonListener(12);
+ multiplyButton.addActionListener(nbls[12]);
+
+ backButton = new JButton("<-");
+ nbls[13] = new ButtonListener(13);
+ backButton.addActionListener(nbls[13]);
+
+ equalButton = new JButton("=");
+ nbls[14] = new ButtonListener(14);
+ equalButton.addActionListener(nbls[14]);
+
+ clearButton = new JButton("C");
+ nbls[15] = new ButtonListener(15);
+ clearButton.addActionListener(nbls[15]);
+
+ buttonPanel = new JPanel();
+ buttonPanel.setLayout(new GridLayout(4,4));
+
+ buttonPanel.add(numberButtons[7]);
+ buttonPanel.add(numberButtons[8]);
+ buttonPanel.add(numberButtons[9]);
+ buttonPanel.add(plusButton);
+ buttonPanel.add(numberButtons[4]);
+ buttonPanel.add(numberButtons[5]);
+ buttonPanel.add(numberButtons[6]);
+ buttonPanel.add(minusButton);
+ buttonPanel.add(numberButtons[1]);
+ buttonPanel.add(numberButtons[2]);
+ buttonPanel.add(numberButtons[3]);
+ buttonPanel.add(multiplyButton);
+ buttonPanel.add(numberButtons[0]);
+ buttonPanel.add(equalButton);
+ buttonPanel.add(clearButton);
+ buttonPanel.add(backButton);
+ }
+
+ private class ButtonListener implements ActionListener
+ {
+ private int number;
+
+ private ButtonListener(int aNumber)
+ {
+ /* Number associated with each button as follows:
+ * - 0 to 9 for number buttons
+ * - 10 for +
+ * - 11 for -
+ * - 12 for *
+ * - 13 for <-
+ * - 14 for =
+ * - 15 for C
+ */
+ number = aNumber;
+ }
+
+ public void actionPerformed(ActionEvent arg0)
+ {
+ int ppSize = ppString.size();
+ boolean error = false;
+
+ if(number < 10)
+ {
+ if(ppSize == 1)
+ {
+ String temp = ppString.get(0);
+
+ if(temp.equals("+") || temp.equals("*"))
+ {
+ ppString.add("" + number);
+ }
+ else if(temp.equals("0"))
+ {
+ ppString.set(0, "" + number);
+ }
+ else
+ {
+ ppString.set(0,temp + number);
+ }
+ }
+ else
+ {
+ String temp = ppString.get(ppSize - 1);
+
+ if(temp.equals("+") || temp.equals("*"))
+ {
+ ppString.add("" + number);
+ }
+ else if(temp.equals("-"))
+ {
+ if(ppString.get(ppSize - 2).equals("+") || ppString.get(ppSize - 2).equals("*"))
+ {
+ ppString.set(ppSize - 1, temp + number);
+ }
+ else
+ {
+ ppString.add("" + number);
+ }
+ }
+ else
+ {
+ ppString.set(ppSize - 1, temp + number);
+ }
+ }
+ }
+ else if(number == 10)
+ {
+ ppString.add("+");
+ }
+ else if(number == 11)
+ {
+ ppString.add("-");
+ }
+ else if(number == 12)
+ {
+ ppString.add("*");
+ }
+ else if(number == 13)
+ {
+ if(ppSize > 0)
+ {
+ String temp = ppString.get(ppSize - 1);
+
+ if(temp.length() > 1)
+ {
+ ppString.set(ppSize - 1, temp.substring(0, temp.length() - 1));
+ }
+ else
+ {
+ ppString.remove(ppSize - 1);
+ }
+ }
+ }
+ else if(number == 14)
+ {
+ InfiniteIntegerInterface result = calculateResult();
+
+ if(result == null)
+ {
+ error = true;
+ }
+ else
+ {
+ ppString.clear();
+ ppString.add(result.toString());
+ }
+ }
+ else if(number == 15)
+ {
+ ppString.clear();
+ ppString.add("0");
+ }
+
+ // Set textArea according to ppString
+
+ ppSize = ppString.size();
+ String displayString = "";
+
+ if(ppSize > 0)
+ {
+ for(int i = 0; i < ppSize; i++)
+ {
+ displayString = displayString + ppString.get(i) + " ";
+ }
+ }
+ else
+ {
+ displayString = "0";
+ }
+
+ if(error)
+ {
+ displayString = displayString + "\nInvalid Expression";
+ }
+
+ textArea.setText(displayString);
+ }
+ }
+
+ /**
+ * calculateResult()
+ *
+ * This method constructs a postfix expression base on the infix expression
+ * stored in the array list of string ppString using stack as explained in
+ * class. Then evaluate the postfix expression using stack.
+ *
+ * @return an infinite integer as a result if the expression is valid.
+ * Otherwise, return null to indicate invalid expression.
+ */
+ private InfiniteIntegerInterface calculateResult()
+ {
+ ArrayList<String> postFix = new ArrayList<String>(); // Postfix expression
+ StackInterface<String> operators = new LStack<String>(); // Stack to store operators
+
+ // Convert infix expression into postfix expression
+
+ int expSize = ppString.size();
+
+ for(int i = 0; i < expSize; i++)
+ {
+ String temp = ppString.get(i);
+
+ if(temp.length() > 1)
+ {
+ postFix.add(temp);
+ }
+ else if(isOperator(temp.charAt(0)))
+ {
+ if(temp.equals("+") || temp.equals("-"))
+ {
+ while(!operators.isEmpty())
+ {
+ postFix.add(operators.pop());
+ }
+ operators.push(temp);
+ }
+ else
+ {
+ while(!operators.isEmpty() && operators.peek().equals("*"))
+ {
+ postFix.add(operators.pop());
+ }
+ operators.push(temp);
+ }
+ }
+ else
+ {
+ postFix.add(temp);
+ }
+ }
+
+ while(!operators.isEmpty())
+ {
+ postFix.add(operators.pop());
+ }
+
+ // Display postfix expression
+
+ System.out.print("Postfix: ");
+
+ for(int i = 0; i < postFix.size(); i++)
+ {
+ System.out.print(postFix.get(i) + " ");
+ }
+ System.out.println();
+
+ // Evaluate postfix expression
+
+ StackInterface<InfiniteIntegerInterface> resultStack = new LStack<InfiniteIntegerInterface>();
+
+ int postFixSize = postFix.size();
+
+ for(int i = 0; i < postFixSize; i++)
+ {
+ String temp = postFix.get(i);
+
+ if(temp.length() == 1 && isOperator(temp.charAt(0)))
+ {
+ /* Encounter an operator, pop the top of the stack
+ * twice to use those numbers as operand, calculate
+ * the result, and push the result back onto the
+ * stack.
+ */
+ InfiniteIntegerInterface op1, op2; // operand 1 and 2
+
+ if(resultStack.isEmpty())
+ {
+ return null; // if the stack is empty, invalid expression
+ }
+ else
+ {
+ op2 = resultStack.pop(); // Pop the second operand
+ }
+
+ if(resultStack.isEmpty())
+ {
+ return null; // if the stack is empty, invalid expression
+ }
+ else
+ {
+ op1 = resultStack.pop(); // Pop the first operand
+ }
+
+ /* Calculating result of "op1 operator op2"
+ * and push the result back onto the stack.
+ */
+ if(temp.equals("+"))
+ {
+ resultStack.push(op1.plus(op2));
+ }
+ else if(temp.equals("-"))
+ {
+ resultStack.push(op1.minus(op2));
+ }
+ else
+ {
+ resultStack.push(op1.multiply(op2));
+ }
+ }
+ else
+ {
+ // Encounter a number, push the number onto the stack.
+
+ resultStack.push(new LInfiniteInteger(temp));
+ }
+ }
+
+ /* The expression is valid if the stack contain exactly
+ * one item. That one single item is the result of evaluating
+ * the arithmetic expression.
+ */
+
+ InfiniteIntegerInterface result = null;
+
+ if(resultStack.isEmpty())
+ {
+ return null; // The stack is empty, invalid expression
+ }
+ else
+ {
+ result = resultStack.pop(); // Pop the result out of the stack
+
+ if(!resultStack.isEmpty())
+ {
+ result = null; // The stack is NOT empty, invalid expression
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * isOperator: Return true if the character c is an
+ * operator, +, -, or *. Otherwise, return false.
+ * @param c the character to be tested whether it is
+ * an operator.
+ * @return true if c is an operator. Otherwise, return false.
+ */
+ private boolean isOperator(char c)
+ {
+ return c == '+' || c == '-' || c == '*';
+ }
+}