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);
}
}