diff --git a/src/calculator/Calc.java b/src/calculator/Calc.java index c1dddc6..51470ec 100644 --- a/src/calculator/Calc.java +++ b/src/calculator/Calc.java @@ -6,27 +6,31 @@ import java.util.regex.Pattern; public class Calc { - private static final Pattern MULTIPLY = Pattern.compile("([0-9]+)\\*([0-9]+)"); - private static final Pattern DIVIDE = Pattern.compile("([0-9]+)\\/([0-9]+)"); - private static final Pattern ADD = Pattern.compile("([0-9]+)\\+([0-9]+)"); - private static final Pattern SUBTRACT = Pattern.compile("([0-9]+)\\-([0-9]+)"); + private static final Pattern MULTIPLY = Pattern.compile("([0-9\\.]+)\\*([0-9\\.]+)"); + private static final Pattern DIVIDE = Pattern.compile("([0-9\\.]+)\\/([0-9\\.]+)"); + private static final Pattern ADD = Pattern.compile("([0-9\\.]+)\\+([0-9\\.]+)"); + private static final Pattern SUBTRACT = Pattern.compile("([0-9\\.]+)\\-([0-9\\.]+)"); - public static int calculate(String text) { + public static Double calculate(String text) { StringBuffer buf = new StringBuffer(text); replace(buf, MULTIPLY, (a, b) -> a * b); replace(buf, DIVIDE, (a, b) -> a / b); replace(buf, ADD, (a, b) -> a + b); replace(buf, SUBTRACT, (a, b) -> a - b); - return Integer.parseInt(buf.toString()); + try { + return Double.parseDouble(buf.toString()); + } catch (Exception e) { + return null; + } } - private static void replace(StringBuffer buf, Pattern pattern, BiFunction doit) { + private static void replace(StringBuffer buf, Pattern pattern, BiFunction doit) { while (true) { Matcher matcher = pattern.matcher(buf.toString()); if (!matcher.find()) break; - buf.replace(matcher.start(), matcher.end(), Integer - .toString(doit.apply(Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2))))); + buf.replace(matcher.start(), matcher.end(), Double + .toString(doit.apply(Double.parseDouble(matcher.group(1)), Double.parseDouble(matcher.group(2))))); } } } diff --git a/src/calculator/Gui.java b/src/calculator/Gui.java index 85ce52d..13bdd91 100644 --- a/src/calculator/Gui.java +++ b/src/calculator/Gui.java @@ -5,9 +5,13 @@ import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; import javax.swing.JButton; +import javax.swing.JDialog; import javax.swing.JFrame; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.UIManager; @@ -20,27 +24,58 @@ public class Gui { public Gui() throws Exception { frame = new JFrame(); - frame.setMinimumSize(new Dimension(200, 400)); + frame.setMinimumSize(new Dimension(300, 400)); frame.setTitle("Calculator"); frame.setLayout(new BorderLayout(10, 10)); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.addKeyListener(new KeyListener() { + + @Override + public void keyTyped(KeyEvent e) { + if (e.getKeyChar() == '+') + tf.setText(tf.getText() + '+'); + else if (e.getKeyChar() == '-') + tf.setText(tf.getText() + "-"); + else if (e.getKeyChar() == '*') + tf.setText(tf.getText() + "*"); + else if (e.getKeyChar() == '/') + tf.setText(tf.getText() + "/"); + else if (e.getKeyChar() == '.') + tf.setText(tf.getText() + "."); + else if (e.getKeyChar() == '\n') { + calc(); + } else if (e.getKeyChar() == '\b' && tf.getText().length() > 0) + tf.setText(tf.getText().substring(0, tf.getText().length() - 1)); + else if (e.getKeyChar() >= '0' && e.getKeyChar() <= '9') + tf.setText(tf.getText() + e.getKeyChar()); + } + + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + } + }); UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); tf = new JTextField(); tf.setFocusable(false); frame.add(tf, BorderLayout.NORTH); panel = new JPanel(); frame.add(panel, BorderLayout.CENTER); - panel.setLayout(new GridLayout(5, 3)); - String str = addNumbers(); - str += "+0-*/"; + panel.setLayout(new GridLayout(4, 4)); + String str = addNumbers("+-*"); + str += ".0"; addAppendButtons(str); addButton('=').addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - tf.setText(Integer.toString(Calc.calculate(tf.getText()))); + calc(); } }); + addAppendButtons("/"); } public void show() { @@ -51,10 +86,13 @@ public class Gui { frame.dispose(); } - private String addNumbers() { + private String addNumbers(String rowend) { String str = ""; + int x = 0; for (int i = 1; i < 10; i++) { str += i; + if (i % 3 == 0) + str += rowend.charAt(x++); } return str; } @@ -71,7 +109,7 @@ public class Gui { tf.setText(tf.getText() + number); } }); - } + } } private JButton addButton(Character c) { @@ -81,4 +119,24 @@ public class Gui { panel.add(num); return num; } + + private void calc() { + try { + Double ret = Calc.calculate(tf.getText()); + if (ret == null) + JOptionPane.showMessageDialog(frame, "Unable to convert result to number!", "Error!", + JOptionPane.WARNING_MESSAGE); + else + tf.setText(Double.toString(ret)); + } catch (ArithmeticException e) { + JOptionPane.showMessageDialog(frame, "Arithmetic error: " + e.getMessage(), "Error!", + JOptionPane.WARNING_MESSAGE); + } catch (NumberFormatException e) { + JOptionPane.showMessageDialog(frame, + "Number format error: " + e.getMessage() + "\n\nThe number may be too large.", "Error!", + JOptionPane.WARNING_MESSAGE); + } catch (Exception e) { + JOptionPane.showMessageDialog(frame, "Unknown error!\n" + e, "Error!", JOptionPane.WARNING_MESSAGE); + } + } }