2023/11/12 每日总结
今天完成了软件构造的课后作业
请根据今日的课程内容,将口算题生成软件中的题目及习题保存到MySQL数据库中,并实现题目的保存和读取。提交实现效果截图及相关代码
package std; import java.util.HashSet; import java.util.Random; import java.util.Set; public class Exercise { private Set<Expression> exercises; public Exercise() { exercises = new HashSet<>(); } public void generateExercises(int numberOfExercises, int operandRange) { Random random = new Random(); exercises.clear(); // 清空已有的题目 while (exercises.size() < numberOfExercises) { int operand1 = random.nextInt(operandRange + 1); int operand2 = random.nextInt(operandRange + 1); char operator = random.nextBoolean() ? '+' : '-'; Expression newExpression = new Expression(operand1, operand2, operator); // 检查新生成的题目是否已存在 if (!exercises.contains(newExpression)) { exercises.add(newExpression); } } } public Set<Expression> getExercises() { return exercises; } public int getExerciseCount() { return exercises.size(); } } package std; import java.util.Objects; public class Expression { private int operand1; private int operand2; private char operator; private int result; private Integer userAnswer; public Expression(int operand1, int operand2, char operator) { this.operand1 = operand1; this.operand2 = operand2; this.operator = operator; this.result = calculateResult(); } private int calculateResult() { switch (operator) { case '+': return operand1 + operand2; case '-': return operand1 - operand2; default: return 0; } } public String getExpressionString() { return operand1 + " " + operator + " " + operand2 + " = "; } public int getResult() { return result; } public Integer getUserAnswer() { return userAnswer; } public void setUserAnswer(Integer userAnswer) { this.userAnswer = userAnswer; } public boolean isAnswered() { return userAnswer != null; } public boolean isCorrect() { return isAnswered() && userAnswer.equals(result); } public int getOperand1() { return operand1; } public int getOperand2() { return operand2; } public char getOperator() { return operator; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Expression that = (Expression) obj; return operand1 == that.operand1 && operand2 == that.operand2 && operator == that.operator; } @Override public int hashCode() { return Objects.hash(operand1, operand2, operator); } } package std; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.*; import java.sql.*; import java.util.ArrayList; import java.util.List; public class GUI extends JFrame { private Exercise exercise; private int currentPage; private int exercisesPerPage; private int totalExercises; private JTextField numberOfExercisesField; private JPanel exercisePanel; private static final String DB_URL = "jdbc:mysql://localhost:3306/test"; private static final String USER = "root"; private static final String PASSWORD = "123456"; public GUI() { exercise = new Exercise(); currentPage = 0; exercisesPerPage = 25; numberOfExercisesField = new JTextField(5); JButton setNumberOfExercisesButton = new JButton("设置题数"); setNumberOfExercisesButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { totalExercises = Integer.parseInt(numberOfExercisesField.getText()); generateExercises(totalExercises); currentPage = 0; displayExercises(); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(GUI.this, "请输入有效的题目数量。", "错误", JOptionPane.ERROR_MESSAGE); } } }); JButton checkAnswersButton = new JButton("检查答案"); checkAnswersButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { checkAnswers(); } }); JButton saveToCSVButton = new JButton("保存CSV"); saveToCSVButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { saveToCSV(); } }); JButton loadFromCSVButton = new JButton("读取CSV"); loadFromCSVButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { loadFromCSV(); } }); JButton saveToDatabaseButton = new JButton("保存数据库"); saveToDatabaseButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { saveToDatabase(); } }); // 添加以下代码以创建 "从数据库加载" 按钮 JButton loadFromDatabaseButton = new JButton("读取数据库"); loadFromDatabaseButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { loadFromDatabase(); } }); JPanel buttonPanel = new JPanel(); buttonPanel.add(new JLabel("Number of Exercises:")); buttonPanel.add(numberOfExercisesField); buttonPanel.add(setNumberOfExercisesButton); buttonPanel.add(checkAnswersButton); buttonPanel.add(saveToCSVButton); buttonPanel.add(loadFromCSVButton); buttonPanel.add(saveToDatabaseButton); buttonPanel.add(loadFromDatabaseButton); add(buttonPanel, BorderLayout.SOUTH); exercisePanel = new JPanel(); exercisePanel.setLayout(new GridLayout(exercisesPerPage / 5, 5, 10, 10)); JButton prevButton = new JButton("Prev"); prevButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { currentPage = Math.max(0, currentPage - 1); displayExercises(); } }); JButton nextButton = new JButton("Next"); nextButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { currentPage++; displayExercises(); } }); JPanel paginationPanel = new JPanel(); paginationPanel.add(prevButton); paginationPanel.add(nextButton); add(paginationPanel, BorderLayout.NORTH); add(new JScrollPane(exercisePanel), BorderLayout.CENTER); setSize(1000, 600); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); setVisible(true); } private void generateExercises(int numberOfExercises) { exercise.generateExercises(numberOfExercises, 10); } private void displayExercises() { exercisePanel.removeAll(); int startIndex = currentPage * exercisesPerPage; int endIndex = Math.min((currentPage + 1) * exercisesPerPage, totalExercises); List<Expression> exercisesList = new ArrayList<>(exercise.getExercises()); for (int i = startIndex; i < endIndex; i += 5) { JPanel rowPanel = new JPanel(); rowPanel.setLayout(new GridLayout(1, 0, 10, 10)); for (int j = 0; j < 5; j++) { if (i + j < endIndex) { Expression exp = exercisesList.get(i + j); JLabel expressionLabel = new JLabel(exp.getExpressionString()); rowPanel.add(expressionLabel); JTextField answerField = new JTextField(5); answerField.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { updateExpression(); } @Override public void removeUpdate(DocumentEvent e) { updateExpression(); } @Override public void changedUpdate(DocumentEvent e) { updateExpression(); } private void updateExpression() { try { String userInput = answerField.getText(); if (!userInput.isEmpty()) { int userAnswer = Integer.parseInt(userInput); exp.setUserAnswer(userAnswer); } } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(GUI.this, "请输入有效的数字。", "错误", JOptionPane.ERROR_MESSAGE); } } }); rowPanel.add(answerField); } } exercisePanel.add(rowPanel); } revalidate(); repaint(); } private void checkAnswers() { int correctCount = 0; for (Expression exp : exercise.getExercises()) { if (exp.isCorrect()) { correctCount++; } } int accuracy = (int) ((double) correctCount / totalExercises * 100); JOptionPane.showMessageDialog(this, "Correct Answers: " + correctCount + "\nAccuracy: " + accuracy + "%", "Results", JOptionPane.INFORMATION_MESSAGE); } private void saveToCSV() { JFileChooser fileChooser = new JFileChooser(); fileChooser.setDialogTitle("Save to CSV"); fileChooser.setFileFilter(new FileNameExtensionFilter("CSV files (*.csv)", "csv")); int userSelection = fileChooser.showSaveDialog(this); if (userSelection == JFileChooser.APPROVE_OPTION) { File fileToSave = fileChooser.getSelectedFile(); if (!fileToSave.getName().toLowerCase().endsWith(".csv")) { fileToSave = new File(fileToSave.getAbsolutePath() + ".csv"); } try (PrintWriter writer = new PrintWriter(fileToSave)) { List<Expression> exercisesList = new ArrayList<>(exercise.getExercises()); for (Expression exp : exercisesList) { writer.println(exp.getOperand1() + "," + exp.getOperator() + "," + exp.getOperand2() + "," + exp.getResult()); } JOptionPane.showMessageDialog(this, "Saved to: " + fileToSave.getAbsolutePath(), "Save Successful", JOptionPane.INFORMATION_MESSAGE); } catch (IOException ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(this, "Error saving file.", "Error", JOptionPane.ERROR_MESSAGE); } } } private void loadFromCSV() { JFileChooser fileChooser = new JFileChooser(); fileChooser.setDialogTitle("Load from CSV"); fileChooser.setFileFilter(new FileNameExtensionFilter("CSV files (*.csv)", "csv")); int userSelection = fileChooser.showOpenDialog(this); if (userSelection == JFileChooser.APPROVE_OPTION) { File fileToLoad = fileChooser.getSelectedFile(); try (BufferedReader reader = new BufferedReader(new FileReader(fileToLoad))) { exercise.getExercises().clear(); String line; while ((line = reader.readLine()) != null) { String[] parts = line.split(","); if (parts.length == 4) { int operand1 = Integer.parseInt(parts[0]); char operator = parts[1].charAt(0); int operand2 = Integer.parseInt(parts[2]); int result = Integer.parseInt(parts[3]); Expression exp = new Expression(operand1, operand2, operator); exp.setUserAnswer(null); // Reset user answer exercise.getExercises().add(exp); } } totalExercises = exercise.getExercises().size(); currentPage = 0; displayExercises(); JOptionPane.showMessageDialog(this, "Loaded from: " + fileToLoad.getAbsolutePath(), "Load Successful", JOptionPane.INFORMATION_MESSAGE); } catch (IOException | NumberFormatException ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(this, "Error loading file.", "Error", JOptionPane.ERROR_MESSAGE); } } } private void saveToDatabase() { try (Connection connection = DriverManager.getConnection(DB_URL, USER, PASSWORD); Statement statement = connection.createStatement()) { // 如果不存在,则创建 exercises 表 statement.executeUpdate("CREATE TABLE IF NOT EXISTS exercises (" + "operand1 INT, operator CHAR(1), operand2 INT, result INT)"); // 清空表中的现有数据 statement.executeUpdate("TRUNCATE TABLE exercises"); // 将习题插入数据库 for (Expression exp : exercise.getExercises()) { String query = String.format("INSERT INTO exercises VALUES (%d, '%c', %d, %d)", exp.getOperand1(), exp.getOperator(), exp.getOperand2(), exp.getResult()); statement.executeUpdate(query); } JOptionPane.showMessageDialog(this, "习题已保存到数据库", "保存成功", JOptionPane.INFORMATION_MESSAGE); } catch (SQLException ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(this, "保存到数据库时发生错误", "错误", JOptionPane.ERROR_MESSAGE); } } private void loadFromDatabase() { try (Connection connection = DriverManager.getConnection(DB_URL, USER, PASSWORD); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT * FROM exercises")) { exercise.getExercises().clear(); while (resultSet.next()) { int operand1 = resultSet.getInt("operand1"); char operator = resultSet.getString("operator").charAt(0); int operand2 = resultSet.getInt("operand2"); int result = resultSet.getInt("result"); Expression exp = new Expression(operand1, operand2, operator); exp.setUserAnswer(null); // 重置用户答案 exercise.getExercises().add(exp); } totalExercises = exercise.getExercises().size(); currentPage = 0; displayExercises(); JOptionPane.showMessageDialog(this, "从数据库加载习题成功", "加载成功", JOptionPane.INFORMATION_MESSAGE); } catch (SQLException | NumberFormatException ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(this, "从数据库加载习题时发生错误", "错误", JOptionPane.ERROR_MESSAGE); } } } package std; public class Main { public static void main(String[] args) { GUI gui = new GUI(); } }