Creating a Timed Arithmetic Quiz Interface in Java Swing

This demonstration outlines the construction of a graphical arithmetic assessment application using Java Swing. The solution generates random mathematical operations dynamically, renders them within a grid layout, implements a session timer, and processes user inputs to calculate accuracy scores.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MathQuizApp {
    private static final int PROBLEM_COUNT = 15;
    private static final int TIME_LIMIT = 90; // seconds

    private final JFrame mainWindow;
    private final List<JTextField> userInputs;
    private final List<MathProblem> problemSet;
    private final JLabel statusTimer;
    private int secondsRemaining;

    // Inner class to hold problem data
    private static class MathProblem {
        String equation;
        String solution;

        MathProblem(String eq, String sol) {
            this.equation = eq;
            this.solution = sol;
        }
    }

    public MathQuizApp() {
        this.problemSet = generateProblems();
        this.userInputs = new ArrayList<>();
        this.secondsRemaining = TIME_LIMIT;
        this.mainWindow = new JFrame("Arithmetic Assessment Tool");
        this.statusTimer = new JLabel("Time Left: " + secondsRemaining + "s", SwingConstants.CENTER);

        initializeInterface();
    }

    private List<MathProblem> generateProblems() {
        List<MathProblem> set = new ArrayList<>();
        Random generator = new Random();

        for (int i = 0; i < PROBLEM_COUNT; i++) {
            int operatorType = generator.nextInt(4);
            int val1, val2;
            String opSign;
            String answer;

            switch (operatorType) {
                case 0: // Addition
                    val1 = generator.nextInt(100);
                    val2 = generator.nextInt(100);
                    opSign = "+";
                    answer = String.valueOf(val1 + val2);
                    break;
                case 1: // Subtraction
                    val1 = generator.nextInt(100);
                    val2 = generator.nextInt(100);
                    opSign = "-";
                    answer = String.valueOf(val1 - val2);
                    break;
                case 2: // Multiplication
                    val1 = generator.nextInt(12);
                    val2 = generator.nextInt(12);
                    opSign = "*";
                    answer = String.valueOf(val1 * val2);
                    break;
                case 3: // Division
                    val2 = generator.nextInt(9) + 1; // Prevent division by zero
                    int quotient = generator.nextInt(10);
                    val1 = val2 * quotient; // Ensure clean division
                    opSign = "/";
                    answer = String.valueOf(quotient);
                    break;
                default:
                    throw new IllegalArgumentException("Invalid operator type");
            }
            set.add(new MathProblem(val1 + " " + opSign + " " + val2 + " =", answer));
        }
        return set;
    }

    private void initializeInterface() {
        mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // Layout: rows for problems + 1 row for timer + 1 row for button
        mainWindow.setLayout(new GridLayout(PROBLEM_COUNT + 2, 2, 5, 5));

        // Populate grid with problems
        for (MathProblem p : problemSet) {
            JLabel label = new JLabel(p.equation);
            JTextField field = new JTextField();
            userInputs.add(field);
            mainWindow.add(label);
            mainWindow.add(field);
        }

        // Timer and Submit Button
        mainWindow.add(statusTimer);
        JButton submitBtn = new JButton("Submit Answers");
        mainWindow.add(submitBtn);

        // Submission Logic
        submitBtn.addActionListener(e -> evaluateResults());

        // Timer Logic
        Timer countdown = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (secondsRemaining > 0) {
                    statusTimer.setText("Time Left: " + --secondsRemaining + "s");
                } else {
                    ((Timer) e.getSource()).stop();
                    disableInputs();
                    JOptionPane.showMessageDialog(mainWindow, "Time is up!", "Session Ended", JOptionPane.WARNING_MESSAGE);
                    evaluateResults();
                }
            }
        });

        mainWindow.pack();
        mainWindow.setVisible(true);
        countdown.start();
    }

    private void disableInputs() {
        for (JTextField field : userInputs) {
            field.setEnabled(false);
        }
    }

    private void evaluateResults() {
        int correct = 0;
        StringBuilder details = new StringBuilder();

        for (int i = 0; i < problemSet.size(); i++) {
            MathProblem p = problemSet.get(i);
            String input = userInputs.get(i).getText().trim();

            if (input.equals(p.solution)) {
                correct++;
            } else {
                details.append(p.equation).append(" Your Answer: ").append(input.isEmpty() ? "(empty)" : input)
                        .append(" | Correct: ").append(p.solution).append("\n");
            }
        }

        int incorrect = PROBLEM_COUNT - correct;
        String message = String.format("Correct: %d\nIncorrect: %d\n\nReview Errors:\n%s", correct, incorrect, details.toString());

        JOptionPane.showMessageDialog(mainWindow, message, "Score Report", JOptionPane.INFORMATION_MESSAGE);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(MathQuizApp::new);
    }
}

Tags: java swing GUI Development Computer Science

Posted on Mon, 08 Jun 2026 17:13:49 +0000 by Urbley