Simple Java Calculator: Clean, Readable Code for Beginners

Simple Java Calculator: Step-by-Step Beginner’s GuideBuilding a simple calculator in Java is an excellent first project for beginners. It reinforces core programming concepts—variables, control flow, methods, user input—and can be extended with graphical interfaces or additional features as you grow. This guide walks you through creating two versions: a console (text) calculator and a basic GUI calculator using Swing. Each step includes explanations, complete code, and suggestions for learning extensions.


What you’ll learn

  • Basic Java program structure (classes, methods, main)
  • Reading user input with Scanner
  • Using control flow (if/switch) and loops
  • Implementing arithmetic operations safely (handling divide-by-zero)
  • Creating a simple GUI with Swing (JFrame, JButton, JTextField)
  • Organizing code for readability and reuse

Part 1 — Console Calculator (Beginner)

This console calculator supports addition, subtraction, multiplication, and division. It demonstrates input parsing, input validation, and a simple loop to perform multiple calculations until the user exits.

Key features:

  • Supports +, -, *, /
  • Validates numeric input
  • Handles division by zero gracefully
  • Loop to continue or exit

Code (ConsoleCalculator.java):

import java.util.InputMismatchException; import java.util.Scanner; public class ConsoleCalculator {     public static void main(String[] args) {         Scanner scanner = new Scanner(System.in);         System.out.println("Simple Java Calculator (Console)");         boolean keepRunning = true;         while (keepRunning) {             double a = readDouble(scanner, "Enter first number: ");             double b = readDouble(scanner, "Enter second number: ");             char op = readOperator(scanner, "Enter operator (+, -, *, /): ");             try {                 double result = calculate(a, b, op);                 System.out.printf("Result: %f %c %f = %f%n", a, op, b, result);             } catch (ArithmeticException ex) {                 System.out.println("Error: " + ex.getMessage());             }             System.out.print("Do another calculation? (y/n): ");             String ans = scanner.next().trim().toLowerCase();             if (!ans.equals("y") && !ans.equals("yes")) {                 keepRunning = false;             }         }         System.out.println("Goodbye!");         scanner.close();     }     private static double readDouble(Scanner scanner, String prompt) {         while (true) {             System.out.print(prompt);             try {                 return scanner.nextDouble();             } catch (InputMismatchException ex) {                 System.out.println("Invalid number. Please try again.");                 scanner.next(); // discard invalid token             }         }     }     private static char readOperator(Scanner scanner, String prompt) {         while (true) {             System.out.print(prompt);             String s = scanner.next().trim();             if (s.length() == 1 && "+-*/".indexOf(s.charAt(0)) >= 0) {                 return s.charAt(0);             }             System.out.println("Invalid operator. Use one of: + - * /");         }     }     private static double calculate(double a, double b, char op) {         switch (op) {             case '+': return a + b;             case '-': return a - b;             case '*': return a * b;             case '/':                 if (b == 0) throw new ArithmeticException("Cannot divide by zero.");                 return a / b;             default: throw new IllegalArgumentException("Unknown operator: " + op);         }     } } 

How it works — brief:

  • readDouble uses Scanner.nextDouble inside a try/catch to loop until valid input.
  • readOperator ensures one of the four operators is entered.
  • calculate performs the operation and throws on divide-by-zero.
  • The main loop lets the user run multiple operations.

Part 2 — GUI Calculator with Swing (Introductory)

A GUI calculator improves usability and teaches event-driven programming. This example creates a simple four-function calculator with a numeric keypad, operator buttons, and a display. It uses Swing (javax.swing) and basic layout managers.

Key features:

  • Clickable buttons for digits 0–9, decimal point, operators, equals, and clear
  • Simple expression evaluation by applying operator to two operands
  • Basic input state handling (entering first number, operator, second number)

Code (SimpleSwingCalculator.java):

import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class SimpleSwingCalculator extends JFrame implements ActionListener {     private final JTextField display = new JTextField();     private double firstValue = 0;     private String operator = "";     private boolean startNewNumber = true;     public SimpleSwingCalculator() {         setTitle("Simple Java Calculator");         setSize(300, 400);         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         setLocationRelativeTo(null);         display.setEditable(false);         display.setHorizontalAlignment(JTextField.RIGHT);         display.setFont(new Font("SansSerif", Font.BOLD, 20));         add(display, BorderLayout.NORTH);         JPanel buttonPanel = new JPanel();         buttonPanel.setLayout(new GridLayout(5, 4, 5, 5));         String[] buttons = {             "7", "8", "9", "/",             "4", "5", "6", "*",             "1", "2", "3", "-",             "0", ".", "=", "+",             "C", "", "", ""         };         for (String text : buttons) {             if (text.isEmpty()) {                 buttonPanel.add(new JLabel()); // spacer             } else {                 JButton btn = new JButton(text);                 btn.setFont(new Font("SansSerif", Font.PLAIN, 18));                 btn.addActionListener(this);                 buttonPanel.add(btn);             }         }         add(buttonPanel, BorderLayout.CENTER);     }     @Override     public void actionPerformed(ActionEvent e) {         String cmd = e.getActionCommand();         if ("0123456789.".contains(cmd)) {             if (startNewNumber) {                 display.setText(cmd.equals(".") ? "0." : cmd);                 startNewNumber = false;             } else {                 if (cmd.equals(".") && display.getText().contains(".")) return;                 display.setText(display.getText() + cmd);             }         } else if ("+-*/".contains(cmd)) {             try {                 firstValue = Double.parseDouble(display.getText());             } catch (NumberFormatException ex) {                 firstValue = 0;             }             operator = cmd;             startNewNumber = true;         } else if ("=".equals(cmd)) {             try {                 double second = Double.parseDouble(display.getText());                 double result = compute(firstValue, second, operator);                 display.setText("" + result);             } catch (ArithmeticException ex) {                 display.setText("Error");             } catch (NumberFormatException ex) {                 display.setText("0");             }             startNewNumber = true;             operator = "";         } else if ("C".equals(cmd)) {             display.setText("0");             firstValue = 0;             operator = "";             startNewNumber = true;         }     }     private double compute(double a, double b, String op) {         switch (op) {             case "+": return a + b;             case "-": return a - b;             case "*": return a * b;             case "/":                 if (b == 0) throw new ArithmeticException("Divide by zero");                 return a / b;             default: return b;         }     }     public static void main(String[] args) {         SwingUtilities.invokeLater(() -> {             SimpleSwingCalculator calc = new SimpleSwingCalculator();             calc.setVisible(true);         });     } } 

Notes:

  • This design evaluates expressions only when = is pressed (no operator precedence).
  • The calculator stores the first operand and operator, waits for the second operand, then computes.

Best Practices & Tips

  • Use double for general-purpose calculators, but be aware of floating-point precision. For financial apps, prefer BigDecimal.
  • Separate UI from logic: create a Calculator class that handles calculation logic; GUI only handles input/display.
  • Add unit tests for the calculation logic (JUnit).
  • Handle edge cases: multiple decimal points, very large/small numbers, divide-by-zero, invalid input.
  • Improve UX: keyboard support, backspace/delete, parentheses and expression parsing, operator precedence using Shunting Yard algorithm.

Extensions and Challenge Ideas

  • Implement expression parsing to allow inputs like “3 + 4 * 2” with correct precedence.
  • Add memory functions (M+, M-, MR, MC).
  • Allow keyboard input and shortcut keys.
  • Replace Swing with JavaFX for a modern UI and animations.
  • Add history logging and undo/redo.

Simple projects like this are great practice: you start with a working console app, then move to a GUI, then add features and robustness. If you want, I can convert the calculation logic into a separate class for testing, add keyboard listeners to the GUI, or provide a version that parses full expressions.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *