(2022级)成都工业学院软件构造实验四:用户交互的软件构造

 写在前面

1、基于2022级软件工程实验指导书

2、代码仅提供参考

3、如果代码不满足你的要求,请寻求其他的途径

运行环境

window11家庭版

IntelliJ IDEA 2023.2.2

jdk17.0.6

实验要求

任务:

教材5.6节  案例分析与实践,完成菜单式用户交互的构造

新增交付物:视频演示完成的构造任务,每个演示之前先说要演示的题目、然后演示;稍微停顿几秒,再说下一个

构造任务7.1:构造用户交互的菜单框架原型。完成菜单的设计与构造,实现子菜单、菜单之间的转换。

构造任务7.2:完成在线练习。要设计和构造,并集成到菜单框架。

提供截屏演示+讲解

源代码

BinaryOperation.java

import java.util.*;

abstract class BinaryOperation {
    protected int operand1;
    protected int operand2;
    protected int result;

    public BinaryOperation() {
        // 生成操作数和计算结果
        Random rand = new Random();
        operand1 = rand.nextInt(101); // 生成0到100的随机数
        operand2 = generateOperand2();
        result = operate(operand1, operand2);
    }

    protected abstract int operate(int operand1, int operand2);

    // 生成第二个操作数
    protected abstract int generateOperand2();

    public String getExpression() {
        return operand1+getOperator()+operand2+"=";
    }

    protected abstract String getOperator();

    public int getResult() {
        return result;
    }
}

// 加法类
class Addition extends BinaryOperation {
    @Override
    protected int operate(int operand1, int operand2) {
        return operand1 + operand2;
    }

    @Override
    protected int generateOperand2() {
        Random rand = new Random();
        return rand.nextInt(101 - operand1); // 第二个操作数不能超过100减去第一个操作数
    }

    @Override
    protected String getOperator() {
        return "+";
    }
}

// 减法类
class Subtraction extends BinaryOperation {
    @Override
    protected int operate(int operand1, int operand2) {
        return operand1 - operand2;
    }

    @Override
    protected int generateOperand2() {
        Random rand = new Random();
        return rand.nextInt(operand1 + 1); // 第二个操作数不能超过第一个操作数
    }

    @Override
    protected String getOperator() {
        return "-";
    }
}

Exercise.java

//构造要求2:实现Exercise
class Exercise {
    private BinaryOperation operation;

    public Exercise(BinaryOperation operation) {
        this.operation = operation;
    }

    public String getExpression() {
        return operation.getExpression();
    }

    public int getResult() {
        return operation.getResult();
    }
}

ExerciseSheet.java

import java.util.HashSet;
import java.util.Set;

//构造要求2:实现ExerciseSheet
class ExerciseSheet {
    private Exercise[] exercises;

    public ExerciseSheet(int numExercises, Class<? extends BinaryOperation> operationType) {
        exercises = new Exercise[numExercises];
        try {
            Set<String> expressions = new HashSet<>(); // 使用集合来确保题目不重复
            for (int i = 0; i < numExercises; i++) {
                BinaryOperation operation = operationType.newInstance();
                String expression = operation.getExpression();
                // 如果集合中已经有了相同的表达式,则重新生成直到不重复为止
                while (expressions.contains(expression)) {
                    operation = operationType.newInstance();
                    expression = operation.getExpression();
                }
                expressions.add(expression);
                exercises[i] = new Exercise(operation);
            }
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public Exercise[] getExercises() {
        return exercises;
    }
}

ExerciseFIlesGUI.java

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

public class ExerciseFilesGUI extends JFrame {
    private JButton generateAdditionButton; // 生成加法练习题按钮
    private JButton generateSubtractionButton; // 生成减法练习题按钮
    private JButton generateMixedButton; // 生成混合练习题按钮
    private JButton readAndCalculateAdditionButton; // 读取并计算加法练习题按钮
    private JButton readAndCalculateSubtractionButton; // 读取并计算减法练习题按钮
    private JButton readAndCalculateMixedButton; // 读取并计算混合练习题按钮
    private JPanel resultPanel; // 结果面板
    private static final int NUM_EXERCISES = 50; // 练习题数量
    private JFrame mainFrame; // 主窗体

    public ExerciseFilesGUI(JFrame mainFrame) {
        super("练习题管理器"); // 设置窗体标题
        this.mainFrame = mainFrame;
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // 设置关闭行为为仅关闭当前窗口
        setLayout(new BorderLayout()); // 设置布局为边界布局

        JPanel buttonPanel = new JPanel(new GridLayout(2, 3, 10, 5)); // 创建按钮面板,使用网格布局

        generateAdditionButton = new JButton("生成加法练习题"); // 创建生成加法练习题按钮
        generateAdditionButton.addActionListener(new GenerateButtonListener("addition_exercises.csv")); // 添加点击事件监听器
        buttonPanel.add(generateAdditionButton); // 将按钮添加到面板中

        generateSubtractionButton = new JButton("生成减法练习题"); // 创建生成减法练习题按钮
        generateSubtractionButton.addActionListener(new GenerateButtonListener("subtraction_exercises.csv")); // 添加点击事件监听器
        buttonPanel.add(generateSubtractionButton); // 将按钮添加到面板中

        generateMixedButton = new JButton("生成混合练习题"); // 创建生成混合练习题按钮
        generateMixedButton.addActionListener(new GenerateButtonListener("mixed_operation_exercises.csv")); // 添加点击事件监听器
        buttonPanel.add(generateMixedButton); // 将按钮添加到面板中

        readAndCalculateAdditionButton = new JButton("读取加法练习题"); // 创建读取加法练习题按钮
        readAndCalculateAdditionButton.addActionListener(new ReadAndCalculateButtonListener("addition_exercises.csv")); // 添加点击事件监听器
        buttonPanel.add(readAndCalculateAdditionButton); // 将按钮添加到面板中

        readAndCalculateSubtractionButton = new JButton("读取减法练习题"); // 创建读取减法练习题按钮
        readAndCalculateSubtractionButton.addActionListener(new ReadAndCalculateButtonListener("subtraction_exercises.csv")); // 添加点击事件监听器
        buttonPanel.add(readAndCalculateSubtractionButton); // 将按钮添加到面板中

        readAndCalculateMixedButton = new JButton("读取混合练习题"); // 创建读取混合练习题按钮
        readAndCalculateMixedButton.addActionListener(new ReadAndCalculateButtonListener("mixed_operation_exercises.csv")); // 添加点击事件监听器
        buttonPanel.add(readAndCalculateMixedButton); // 将按钮添加到面板中

        add(buttonPanel, BorderLayout.NORTH); // 将按钮面板添加到窗体的北部

        resultPanel = new JPanel(new GridLayout(25, 2, 10, 5)); // 创建结果面板,使用网格布局
        JScrollPane scrollPane = new JScrollPane(resultPanel); // 创建滚动窗格
        add(scrollPane, BorderLayout.CENTER); // 将滚动窗格添加到窗体的中心

        pack(); // 调整窗体大小以适应其子组件的首选大小
        setSize(800, 600); // 设置窗体大小
        setLocationRelativeTo(null); // 设置窗体居中显示
        setVisible(true); // 设置窗体可见
    }

    private class GenerateButtonListener implements ActionListener {
        private String filename;

        public GenerateButtonListener(String filename) {
            this.filename = filename;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            generateExercises(filename); // 调用方法生成练习题
            JOptionPane.showMessageDialog(null, "练习题已生成"); // 显示消息框提示用户练习题已生成
        }
    }

    private class ReadAndCalculateButtonListener implements ActionListener {
        private String filename;

        public ReadAndCalculateButtonListener(String filename) {
            this.filename = filename;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            String[] results = calculateExercises(filename); // 计算练习题结果
            displayResults(results); // 显示结果
        }
    }

    private void displayResults(String[] results) {
        resultPanel.removeAll(); // 清空结果面板

        for (int i = 0; i < results.length; i++) {
            JLabel label = new JLabel(results[i], SwingConstants.CENTER); // 创建标签显示结果
            resultPanel.add(label); // 将标签添加到结果面板中
        }

        resultPanel.revalidate(); // 重新验证结果面板
        resultPanel.repaint(); // 重绘结果面板
    }

    public static void runGUI(JFrame mainFrame) {
        SwingUtilities.invokeLater(() -> new ExerciseFilesGUI(mainFrame)); // 在事件调度线程上创建并显示 GUI
    }

    public static void generateExercises(String filename) {
        if (filename.equals("addition_exercises.csv")) {
            generateAdditionCSV(filename); // 生成加法练习题
        } else if (filename.equals("subtraction_exercises.csv")) {
            generateSubtractionCSV(filename); // 生成减法练习题
        } else if (filename.equals("mixed_operation_exercises.csv")) {
            generateMixedOperationCSV(filename); // 生成混合练习题
        }
    }

    public static void generateAdditionCSV(String filename) {
        generateCSV(filename, Addition.class); // 生成加法练习题的 CSV 文件
    }

    public static void generateSubtractionCSV(String filename) {
        generateCSV(filename, Subtraction.class); // 生成减法练习题的 CSV 文件
    }

    public static void generateMixedOperationCSV(String filename) {
        try (PrintWriter writer = new PrintWriter(new FileWriter(filename))) {
            Random rand = new Random();
            for (int i = 0; i < NUM_EXERCISES; i++) {
                Class<? extends BinaryOperation> operationType = rand.nextBoolean() ? Addition.class : Subtraction.class; // 随机选择加法或减法
                BinaryOperation operation = operationType.getDeclaredConstructor().newInstance(); // 实例化运算类
                writer.println(operation.getExpression()); // 将表达式写入文件
            }
        } catch (IOException | NoSuchMethodException | InstantiationException | IllegalAccessException |
                 InvocationTargetException e) {
            e.printStackTrace(); // 打印异常信息
        }
    }

    private static void generateCSV(String filename, Class<? extends BinaryOperation> operationType) {
        try (PrintWriter writer = new PrintWriter(new FileWriter(filename))) {
            ExerciseSheet sheet = new ExerciseSheet(NUM_EXERCISES, operationType); // 创建练习题表格
            Exercise[] exercises = sheet.getExercises(); // 获取练习题数组
            for (Exercise exercise : exercises) {
                writer.println(exercise.getExpression()); // 将表达式写入文件
            }
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }
    }

    private String[] calculateExercises(String filename) {
        String[] results = new String[NUM_EXERCISES]; // 创建结果数组
        try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
            String line;
            int count = 0;
            while ((line = reader.readLine()) != null) {
                line = line.trim(); // 去除首尾空格
                if (!line.isEmpty()) {
                    results[count] = calculateExpression(line); // 计算表达式结果
                    count++;
                }
            }
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }
        return results; // 返回结果数组
    }

    private String calculateExpression(String expression) {
        String[] parts = expression.split("\\+|-|="); // 根据运算符分割表达式
        int operand1 = Integer.parseInt(parts[0].trim()); // 获取操作数1
        int operand2 = Integer.parseInt(parts[1].trim()); // 获取操作数2
        if (expression.contains("+")) {
            return expression + (operand1 + operand2); // 返回加法表达式和结果
        } else if (expression.contains("-")) {
            return expression + (operand1 - operand2); // 返回减法表达式和结果
        } else {
            return "Invalid expression"; // 返回无效表达式提示
        }
    }
}

ExerciseCorrectionGUI.java

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ExerciseCorrectionGUI extends JFrame {
    private JPanel exercisePanel; // 练习面板
    private java.util.List<JLabel> exerciseLabels; // 练习标签列表
    private java.util.List<JTextField> userInputFields; // 用户输入文本框列表
    private JButton submitButton; // 提交按钮
    private JButton redoButton; // 重新作答按钮
    private JButton additionButton; // 加法按钮
    private JButton subtractionButton; // 减法按钮
    private JButton mixedButton; // 混合运算按钮

    private java.util.List<String> exerciseList; // 练习列表
    private java.util.List<Integer> userAnswersList; // 用户答案列表
    private JFrame mainFrame; // 主窗口引用


    public ExerciseCorrectionGUI(JFrame mainFrame) {
        super("答题批改管理器"); // 设置窗口标题
        this.mainFrame = mainFrame;
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置默认关闭操作为退出应用
        setLayout(new BorderLayout()); // 设置布局为边界布局

        JPanel buttonPanel = new JPanel(new GridLayout(1, 3, 10, 5)); // 创建按钮面板,网格布局,一行三列
        additionButton = new JButton("加法算式题"); // 创建加法按钮
        additionButton.addActionListener(new ButtonListener("addition_exercises.csv")); // 添加点击事件监听器
        buttonPanel.add(additionButton); // 将加法按钮添加到面板中

        subtractionButton = new JButton("减法算式题"); // 创建减法按钮
        subtractionButton.addActionListener(new ButtonListener("subtraction_exercises.csv")); // 添加点击事件监听器
        buttonPanel.add(subtractionButton); // 将减法按钮添加到面板中

        mixedButton = new JButton("混合算式题"); // 创建混合运算按钮
        mixedButton.addActionListener(new ButtonListener("mixed_operation_exercises.csv")); // 添加点击事件监听器
        buttonPanel.add(mixedButton); // 将混合运算按钮添加到面板中

        add(buttonPanel, BorderLayout.NORTH); // 将按钮面板添加到窗口的北部

        exercisePanel = new JPanel(new GridLayout(25, 2, 10, 5)); // 创建练习面板,网格布局,25行两列
        add(exercisePanel, BorderLayout.CENTER); // 将练习面板添加到窗口的中心

        exerciseLabels = new ArrayList<>(); // 初始化练习标签列表
        userInputFields = new ArrayList<>(); // 初始化用户输入文本框列表
        for (int i = 0; i < 50; i++) {
            JLabel label = new JLabel("", SwingConstants.CENTER); // 创建标签
            exerciseLabels.add(label); // 添加到标签列表
            exercisePanel.add(label); // 将标签添加到练习面板中

            JTextField field = new JTextField(10); // 创建文本框
            userInputFields.add(field); // 添加到文本框列表
            exercisePanel.add(field); // 将文本框添加到练习面板中
        }

        JPanel buttonPanelSouth = new JPanel(new FlowLayout()); // 创建按钮面板,流式布局
        redoButton = new JButton("重新作答"); // 创建重新作答按钮
        redoButton.addActionListener(new RedoButtonListener()); // 添加点击事件监听器
        buttonPanelSouth.add(redoButton); // 将重新作答按钮添加到按钮面板中

        submitButton = new JButton("立即提交"); // 创建提交按钮
        submitButton.addActionListener(new SubmitButtonListener()); // 添加点击事件监听器
        buttonPanelSouth.add(submitButton); // 将提交按钮添加到按钮面板中

        add(buttonPanelSouth, BorderLayout.SOUTH); // 将按钮面板添加到窗口的南部

        pack(); // 调整窗口大小以适应组件大小
        setLocationRelativeTo(null); // 将窗口置于屏幕中央
        setVisible(true); // 设置窗口可见

        generateExercises("mixed_operation_exercises.csv"); // 生成练习题
    }

    private void generateExercises(String filename) {
        exerciseList = new ArrayList<>(); // 初始化练习列表
        try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
            String line;
            while ((line = reader.readLine()) != null) {
                exerciseList.add(line); // 逐行读取练习题
            }
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "未找到练习题."); // 显示错误消息
            e.printStackTrace(); // 打印异常信息
        }

        if (!exerciseList.isEmpty()) { // 如果练习列表不为空
            for (int i = 0; i < 25 && i < exerciseList.size(); i++) {
                exerciseLabels.get(i * 2).setText(exerciseList.get(i * 2)); // 设置练习标签内容
                exerciseLabels.get(i * 2 + 1).setText(exerciseList.get(i * 2 + 1)); // 设置练习标签内容
            }
            userAnswersList = new ArrayList<>(); // 初始化用户答案列表
        } else {
            exerciseLabels.get(0).setText("No exercises loaded."); // 如果练习列表为空,显示提示消息
        }
    }

    private class ButtonListener implements ActionListener {
        private String filename;

        public ButtonListener(String filename) {
            this.filename = filename;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            generateExercises(filename); // 生成练习题
        }
    }

    private class RedoButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            for (JTextField field : userInputFields) {
                field.setText(""); // 清空用户输入文本框
            }
            userAnswersList.clear(); // 清空用户答案列表
        }
    }

    private class SubmitButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            for (JTextField field : userInputFields) {
                String userInput = field.getText().trim(); // 获取用户输入文本
                int userAnswer;
                try {
                    if (userInput.isEmpty()) {
                        userAnswer = -1;
                    } else {
                        userAnswer = Integer.parseInt(userInput); // 解析用户答案
                    }
                } catch (NumberFormatException ex) {
                    userAnswer = -1; // 处理异常情况
                }
                userAnswersList.add(userAnswer); // 将用户答案添加到列表中
            }

            int correctCount = 0; // 正确答案计数
            for (int i = 0; i < exerciseList.size(); i++) {
                int correctAnswer = evaluateExpression(exerciseList.get(i)); // 获取正确答案
                int userAnswer = userAnswersList.get(i); // 获取用户答案
                if (userAnswer == correctAnswer) { // 判断用户答案是否正确
                    correctCount++; // 正确答案计数加一
                }
            }

            int totalExercises = exerciseList.size(); // 练习总数
            int incorrectCount = totalExercises - correctCount; // 错误答案数
            int score = (int) ((double) correctCount / totalExercises * 100); // 得分计算

            String message = String.format("题目总数: %d\n正确个数: %d\n错误个数: %d\n最后得分: %d",
                    totalExercises, correctCount, incorrectCount, score); // 构建消息字符串
            JOptionPane.showMessageDialog(null, message); // 显示消息对话框
            dispose(); // 关闭窗口
        }
    }

    private static int evaluateExpression(String expression) {
        Pattern pattern = Pattern.compile("\\s*(\\d+)\\s*([-+])\\s*(\\d+)\\s*="); // 创建正则表达式模式
        Matcher matcher = pattern.matcher(expression); // 创建匹配器
        if (matcher.matches()) { // 如果匹配成功
            int operand1 = Integer.parseInt(matcher.group(1)); // 获取操作数1
            String operator = matcher.group(2); // 获取运算符
            int operand2 = Integer.parseInt(matcher.group(3)); // 获取操作数2

            if (operator.equals("+")) { // 如果是加法
                return operand1 + operand2; // 返回加法结果
            } else if (operator.equals("-")) { // 如果是减法
                return operand1 - operand2; // 返回减法结果
            }
        }
        return 0; // 默认返回值
    }

    public static void runGUI(JFrame mainFrame) {
        SwingUtilities.invokeLater(() -> new ExerciseCorrectionGUI(mainFrame)); // 创建并显示GUI
    }
}

BinaryOperationBaseGUI.java

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import java.util.List;

public class BinaryOperationBaseGUI extends JFrame {
    private List<String> additionBase; // 加法算式基列表
    private List<String> subtractionBase; // 减法算式基列表

    private JButton generateAdditionButton; // 生成加法按钮
    private JButton generateSubtractionButton; // 生成减法按钮
    private JButton generateMixedOperationButton; // 生成混合算式按钮
    private JButton extractAdditionButton; // 抽取加法按钮
    private JButton extractSubtractionButton; // 抽取减法按钮
    private JButton extractMixedOperationButton; // 抽取混合算式按钮
    private JFrame mainFrame; // 主窗口引用

    // 构造方法
    public BinaryOperationBaseGUI(JFrame mainFrame) {
        setTitle("算式基管理器"); // 设置窗口标题
        this.mainFrame = mainFrame; // 初始化主窗口引用
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置默认关闭操作为退出应用
        setLayout(new GridLayout(2, 3, 10, 10)); // 设置布局为网格布局,2行3列,间距为10

        // 创建按钮并添加到窗口
        generateAdditionButton = new JButton("生成加法算式基");
        generateSubtractionButton = new JButton("生成减法算式基");
        generateMixedOperationButton = new JButton("生成混合算式基");
        extractAdditionButton = new JButton("抽取加法算式题");
        extractSubtractionButton = new JButton("抽取减法算式题");
        extractMixedOperationButton = new JButton("抽取混合算式题");
        add(generateAdditionButton);
        add(generateSubtractionButton);
        add(generateMixedOperationButton);
        add(extractAdditionButton);
        add(extractSubtractionButton);
        add(extractMixedOperationButton);

        // 为按钮添加事件监听器
        generateAdditionButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                generateAdditionBase(100); // 生成加法算式基
                saveBaseToFile(additionBase, "addition_base.csv"); // 保存到文件
                JOptionPane.showMessageDialog(BinaryOperationBaseGUI.this, "加法算式基已生成并保存"); // 弹出提示框
            }
        });

        generateSubtractionButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                generateSubtractionBase(100); // 生成减法算式基
                saveBaseToFile(subtractionBase, "subtraction_base.csv"); // 保存到文件
                JOptionPane.showMessageDialog(BinaryOperationBaseGUI.this, "减法算式基已生成并保存"); // 弹出提示框
            }
        });

        generateMixedOperationButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                generateMixedOperationBase(100); // 生成混合算式基
                saveBaseToFile(additionBase, "mixed_operation_base.csv"); // 保存到文件
                JOptionPane.showMessageDialog(BinaryOperationBaseGUI.this, "混合算式基已生成并保存"); // 弹出提示框
            }
        });

        extractAdditionButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                generateAdditionBase(100); // 生成加法算式基
                List<String> randomAdditionOperations = getRandomAdditionOperations(50); // 获取随机加法算式
                saveBaseToFile(randomAdditionOperations, "addition_operations.csv"); // 保存到文件
                JOptionPane.showMessageDialog(BinaryOperationBaseGUI.this, "提取加法运算成功并保存。"); // 弹出提示框
            }
        });

        extractSubtractionButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                generateSubtractionBase(100); // 生成减法算式基
                List<String> randomSubtractionOperations = getRandomSubtractionOperations(50); // 获取随机减法算式
                saveBaseToFile(randomSubtractionOperations, "subtraction_operations.csv"); // 保存到文件
                JOptionPane.showMessageDialog(BinaryOperationBaseGUI.this, "提取减法运算成功并保存。"); // 弹出提示框
            }
        });

        extractMixedOperationButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                generateMixedOperationBase(100); // 生成混合算式基
                List<String> randomMixedOperations = getRandomMixedOperationOperations(50); // 获取随机混合算式
                saveBaseToFile(randomMixedOperations, "mixed_operation_operations.csv"); // 保存到文件
                JOptionPane.showMessageDialog(BinaryOperationBaseGUI.this, "提取混合运算成功并保存。"); // 弹出提示框
            }
        });

        pack(); // 调整窗口大小以适应内容
        setLocationRelativeTo(null); // 将窗口置于屏幕中央
    }

    // 生成加法算式基
    private void generateAdditionBase(int numOperations) {
        additionBase = new ArrayList<>(); // 初始化加法算式基列表
        for (int i = 0; i < numOperations; i++) {
            BinaryOperation addition = new Addition(); // 创建加法实例
            additionBase.add(cleanExpression(addition.getExpression())); // 添加加法表达式到列表中
        }
    }

    // 生成减法算式基
    private void generateSubtractionBase(int numOperations) {
        subtractionBase = new ArrayList<>(); // 初始化减法算式基列表
        for (int i = 0; i < numOperations; i++) {
            BinaryOperation subtraction = new Subtraction(); // 创建减法实例
            subtractionBase.add(cleanExpression(subtraction.getExpression())); // 添加减法表达式到列表中
        }
    }

    // 生成混合算式基
    private void generateMixedOperationBase(int numOperations) {
        additionBase = new ArrayList<>(); // 初始化加法算式基列表
        subtractionBase = new ArrayList<>(); // 初始化减法算式基列表
        generateAdditionBase(numOperations / 2); // 生成加法算式基
        generateSubtractionBase(numOperations / 2); // 生成减法算式基
    }

    // 将算式基保存到文件
    private void saveBaseToFile(List<String> base, String filename) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) {
            for (String operation : base) {
                writer.write(operation); // 写入算式
                writer.newLine(); // 换行
            }
        } catch (IOException ex) {
            ex.printStackTrace(); // 打印异常信息
        }
    }

    // 获取随机加法算式
    private List<String> getRandomAdditionOperations(int numOperations) {
        return getRandomOperations(additionBase, numOperations); // 调用通用的获取随机算式方法
    }

    // 获取随机减法算式
    private List<String> getRandomSubtractionOperations(int numOperations) {
        return getRandomOperations(subtractionBase, numOperations); // 调用通用的获取随机算式方法
    }

    // 获取随机混合算式
    private List<String> getRandomMixedOperationOperations(int numOperations) {
        List<String> mixedOperations = new ArrayList<>(); // 初始化混合算式列表
        if (additionBase != null && subtractionBase != null) { // 确保加法和减法算式基都已生成
            mixedOperations.addAll(additionBase); // 将加法算式基加入混合算式列表
            mixedOperations.addAll(subtractionBase); // 将减法算式基加入混合算式列表
            Collections.shuffle(mixedOperations); // 随机打乱混合算式列表
            return mixedOperations.subList(0, numOperations); // 返回指定数量的随机混合算式
        } else {
            return new ArrayList<>(); // 若算式基未生成,则返回空列表
        }
    }

    // 获取随机算式
    private List<String> getRandomOperations(List<String> base, int numOperations) {
        List<String> randomOperations = new ArrayList<>(); // 初始化随机算式列表
        Random rand = new Random(); // 创建随机数生成器
        for (int i = 0; i < numOperations; i++) {
            int index = rand.nextInt(base.size()); // 生成随机索引
            randomOperations.add(base.get(index)); // 添加随机算式到列表中
        }
        return randomOperations; // 返回随机算式列表
    }

    // 清除表达式中的空白字符
    private String cleanExpression(String expression) {
        return expression.replaceAll("\\s+", ""); // 使用正则表达式替换空白字符为空字符串
    }

    // 运行GUI
    public static void runGUI(JFrame mainFrame) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new BinaryOperationBaseGUI(mainFrame).setVisible(true); // 创建并显示GUI
            }
        });
    }
}

MainGUI.java

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class MainGUI extends JFrame {
    private JPanel optionsPanel; // 选项面板

    public MainGUI() {
        setTitle("口算出题程序"); // 设置窗口标题
        setSize(400, 400); // 设置窗口大小
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置默认关闭操作为退出应用
        setLayout(new GridLayout(1, 1)); // 设置布局为网格布局,四行一列

        optionsPanel = new JPanel(new GridLayout(4, 1)); // 创建选项面板,网格布局,四行一列

        add(optionsPanel); // 将选项面板添加到窗口
        addOptions(); // 添加选项按钮
    }

    private void addOptions() {
        JButton button1 = new JButton("批量产生习题并用文件存储"); // 创建按钮1
        button1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ExerciseFilesGUI.runGUI(MainGUI.this); // 在主窗口中调用 ExerciseFilesGUI
            }
        });

        JButton button2 = new JButton("批改练习并储存"); // 创建按钮2
        button2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ExerciseCorrectionGUI.runGUI(MainGUI.this); // 在主窗口中调用 ExerciseCorrectionGUI
            }
        });

        JButton button3 = new JButton("生成算式基并用文件储存"); // 创建按钮3
        button3.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                BinaryOperationBaseGUI.runGUI(MainGUI.this); // 在主窗口中调用 BinaryOperationBaseGUI
            }
        });

        JButton button0 = new JButton("退出"); // 创建退出按钮
        button0.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int option = JOptionPane.showConfirmDialog(MainGUI.this, "确定要退出吗?", "确认", JOptionPane.YES_NO_OPTION); // 显示确认对话框
                if (option == JOptionPane.YES_OPTION) {
                    dispose(); // 关闭主窗口
                }
            }
        });

        optionsPanel.add(button1); // 将按钮1添加到选项面板
        optionsPanel.add(button2); // 将按钮2添加到选项面板
        optionsPanel.add(button3); // 将按钮3添加到选项面板
        optionsPanel.add(button0); // 将退出按钮添加到选项面板
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                MainGUI mainGUI = new MainGUI(); // 创建主窗口对象
                mainGUI.setVisible(true); // 设置主窗口可见
            }
        });
    }
}

运行结果

  • 13
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值