鱼C论坛

 找回密码
 立即注册
楼主: zqy173590939

[学习笔记] Java实验完成

[复制链接]
发表于 2023-12-31 17:20:17 | 显示全部楼层
zqy173590939 发表于 2023-12-31 17:19
@FishC
帮我写数据库课程设计,数据库使用MySQL,题 ...


对于教师岗位管理系统的设计,我们可以采用Java语言和MySQL数据库来实现。下面是一个简单的示例代码,可以帮助你开始:

首先,我们需要创建一个名为"Teacher"的Java类,来表示教师的基本信息:

  1. public class Teacher {
  2.     private String name;
  3.     private String idCard;
  4.     private String contact;
  5.     private String email;
  6.     private String job;
  7.     private String researchLab;

  8.     // 构造方法
  9.     public Teacher(String name, String idCard, String contact, String email, String job, String researchLab) {
  10.         this.name = name;
  11.         this.idCard = idCard;
  12.         this.contact = contact;
  13.         this.email = email;
  14.         this.job = job;
  15.         this.researchLab = researchLab;
  16.     }

  17.     // Getter和Setter方法
  18.     // ...

  19.     // toString方法
  20.     @Override
  21.     public String toString() {
  22.         return "姓名:" + name + "\n" +
  23.                 "身份证号:" + idCard + "\n" +
  24.                 "联系方式:" + contact + "\n" +
  25.                 "邮箱:" + email + "\n" +
  26.                 "工作时间:" + job + "\n" +
  27.                 "岗位:" + job + "\n" +
  28.                 "教研室信息:" + researchLab;
  29.     }
  30. }
复制代码


然后,我们可以创建一个名为"TeacherManager"的Java类,来实现教师岗位的管理功能:

  1. import java.util.ArrayList;
  2. import java.util.List;

  3. public class TeacherManager {
  4.     private List<Teacher> teachers;

  5.     public TeacherManager() {
  6.         teachers = new ArrayList<>();
  7.     }

  8.     // 添加教师
  9.     public void addTeacher(Teacher teacher) {
  10.         teachers.add(teacher);
  11.     }

  12.     // 编辑教师信息
  13.     public void editTeacher(String idCard, Teacher newTeacher) {
  14.         for (int i = 0; i < teachers.size(); i++) {
  15.             if (teachers.get(i).getIdCard().equals(idCard)) {
  16.                 teachers.set(i, newTeacher);
  17.                 break;
  18.             }
  19.         }
  20.     }

  21.     // 删除教师
  22.     public void deleteTeacher(String idCard) {
  23.         for (int i = 0; i < teachers.size(); i++) {
  24.             if (teachers.get(i).getIdCard().equals(idCard)) {
  25.                 teachers.remove(i);
  26.                 break;
  27.             }
  28.         }
  29.     }

  30.     // 根据姓名查询教师
  31.     public List<Teacher> searchByName(String name) {
  32.         List<Teacher> result = new ArrayList<>();
  33.         for (Teacher teacher : teachers) {
  34.             if (teacher.getName().equals(name)) {
  35.                 result.add(teacher);
  36.             }
  37.         }
  38.         return result;
  39.     }

  40.     // 根据身份证号查询教师
  41.     public Teacher searchByIdCard(String idCard) {
  42.         for (Teacher teacher : teachers) {
  43.             if (teacher.getIdCard().equals(idCard)) {
  44.                 return teacher;
  45.             }
  46.         }
  47.         return null;
  48.     }

  49.     // 获取所有教师
  50.     public List<Teacher> getAllTeachers() {
  51.         return teachers;
  52.     }
  53. }
复制代码


接下来,我们可以创建一个简单的GUI界面来实现用户交互。你可以使用Swing或JavaFX等库来创建窗体、按钮等组件,并调用TeacherManager类的方法来进行教师岗位管理。由于篇幅有限,这里不提供完整的GUI代码,你可以根据需要自行实现。

最后,在MySQL数据库中创建一个名为"teachers"的表,包含与Teacher类对应的字段。你可以使用JDBC连接数据库,并编写相应的SQL语句来实现数据的持久化操作,例如插入、更新、删除和查询等。

希望以上代码能帮助到你开始设计教师岗位管理系统。由于题目要求较为复杂,还有很多细节需要进一步完善和实现。如果你遇到了具体的问题或需要更详细的帮助,请随时向我提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-31 17:22:56 | 显示全部楼层
FishC 发表于 2023-12-31 17:20
对于教师岗位管理系统的设计,我们可以采用Java语言和MySQL数据库来实现。下面是一个简单的示例代码, ...

根据以上部分你写出的代码,补全完整的GUI部分代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-31 17:24:10 | 显示全部楼层
zqy173590939 发表于 2023-12-31 17:22
根据以上部分你写出的代码,补全完整的GUI部分代码


以下是一个简单的GUI示例代码,使用Swing库来创建窗体和按钮,并与TeacherManager类进行交互:import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.List;public class TeacherManagerGUI {    private JFrame frame;    private JTextField nameTextField;    private JTextField idCardTextField;    private JTextField contactTextField;    private JTextField emailTextField;    private JTextField jobTextField;    private JTextField researchLabTextField;    private JTextArea resultTextArea;    private TeacherManager teacherManager;    // 构造方法    public TeacherManagerGUI() {        teacherManager = new TeacherManager();        initialize();    }    // 初始化界面    private void initialize() {        frame = new JFrame();        frame.setBounds(100, 100, 500, 400);        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        frame.getContentPane().setLayout(null);        // 姓名标签        JLabel nameLabel = new JLabel("姓名:");        nameLabel.setBounds(20, 20, 60, 20);        frame.getContentPane().add(nameLabel);        // 姓名输入框        nameTextField = new JTextField();        nameTextField.setBounds(80, 20, 150, 20);        frame.getContentPane().add(nameTextField);        // 身份证号标签        JLabel idCardLabel = new JLabel("身份证号:");        idCardLabel.setBounds(20, 50, 60, 20);        frame.getContentPane().add(idCardLabel);        // 身份证号输入框        idCardTextField = new JTextField();        idCardTextField.setBounds(80, 50, 150, 20);        frame.getContentPane().add(idCardTextField);        // 其他输入框...        // 添加按钮        JButton addButton = new JButton("添加");        addButton.addActionListener(new ActionListener() {            public void actionPerformed(ActionEvent e) {                String name = nameTextField.getText();                String idCard = idCardTextField.getText();                String contact = contactTextField.getText();                String email = emailTextField.getText();                String job = jobTextField.getText();                String researchLab = researchLabTextField.getText();                Teacher teacher = new Teacher(name, idCard, contact, email, job, researchLab);                teacherManager.addTeacher(teacher);                resultTextArea.setText("添加成功!");            }        });        addButton.setBounds(20, 80, 100, 20);        frame.getContentPane().add(addButton);        // 查询按钮        JButton searchButton = new JButton("查询");        searchButton.addActionListener(new ActionListener() {            public void actionPerformed(ActionEvent e) {                String name = nameTextField.getText();                List<Teacher> teachers = teacherManager.searchByName(name);                StringBuilder result = new StringBuilder();                for (Teacher teacher : teachers) {                    result.append(teacher.toString()).append("\n\n");                }                resultTextArea.setText(result.toString());            }        });        searchButton.setBounds(130, 80, 100, 20);        frame.getContentPane().add(searchButton);        // 结果文本区域        resultTextArea = new JTextArea();        resultTextArea.setBounds(20, 120, 400, 200);        frame.getContentPane().add(resultTextArea);    }    // 启动程序    public void start() {        EventQueue.invokeLater(new Runnable() {            public void run() {                try {                    TeacherManagerGUI window = new TeacherManagerGUI();                    window.frame.setVisible(true);                } catch (Exception e) {                    e.printStackTrace();                }            }        });    }}然后,可以在main方法中创建TeacherManagerGUI对象并调用其start方法来启动程序:public static void main(String[] args) {    TeacherManagerGUI teacherManagerGUI = new TeacherManagerGUI();    teacherManagerGUI.start();}请注意,以上代码只是一个简单示例,你可以根据实际需求自行扩展界面和功能。希望这能对你有所帮助!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-31 20:49:02 | 显示全部楼层
@FishC
package com.example.javafxmw;

import gaijin3.*;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

import java.io.IOException;
import java.sql.*;
import java.util.Optional;

public class HelloApplication extends Application
{
    // 定义全局变量
    //定义一个TextArea控件作为全局变量
    TextArea infoTextArea = new TextArea();

    Button viewAccuracyButton = new Button("View Accuracy");

    FlowPane flowPane = new FlowPane();
    ScrollPane scrollPane = new ScrollPane();// 创建一个滚动面板对象
    private int maxID = 0;

    @Override
    public void start(Stage stage) throws IOException {
        MenuItem generateMenuItem = new MenuItem("Generate");

        // 事件处理器代码
        generateMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                generateEquation();
            }
        });

        MenuItem saveMenuItem = new MenuItem("Save");

        saveMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                saveEquations();
                connectDatabase();
            }
        });

        MenuItem readMenuItem = new MenuItem("Read");

        readMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                flowPane.getChildren().clear(); // 清空当前GUI界面
                showAlert("习题已读取");
                displayAllEquationsFromDatabase();
            }
        });

        MenuItem checkMenuItem = new MenuItem("Check");

        checkMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 检查习题
                checkEquations();
            }
        });


        // View Accuracy按钮的点击事件监听器
        viewAccuracyButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 显示饼状图
                showAccuracyChart();
            }
        });



        Menu fileMenu = new Menu("File");
        Menu saveMenu = new Menu("SaveEquation");
        Menu readMenu = new Menu("ReadEquation");
        Menu checkMenu = new Menu("CheckEquation");

        fileMenu.getItems().addAll(generateMenuItem);
        saveMenu.getItems().add(saveMenuItem);
        readMenu.getItems().add(readMenuItem);
        checkMenu.getItems().add(checkMenuItem);

        MenuBar menuBar = new MenuBar();
        menuBar.getMenus().addAll(fileMenu);
        menuBar.getMenus().add(saveMenu);
        menuBar.getMenus().add(readMenu);
        menuBar.getMenus().add(checkMenu);

        flowPane.setHgap(50);
        flowPane.setVgap(30);
        flowPane.setPadding(new Insets(20));
        flowPane.setPrefSize(800, 560); // 设置 FlowPane 的大小

        BorderPane borderPane = new BorderPane();
        borderPane.setTop(menuBar);
        borderPane.setCenter(flowPane);

        //为了解决题目生成或多flowpane没有拖动条无法显示的问题
        // 将FlowPane放在一个ScrollPane中
        scrollPane.setContent(flowPane);// 设置滚动面板的内容为 flowPane,即将 flowPane 放入滚动面板中
        scrollPane.setFitToHeight(true);// 可以让滚动面板的高度自适应内容的高度
        borderPane.setCenter(scrollPane); // 将ScrollPane放置在中心位置

        HBox bottomBox = new HBox(10, viewAccuracyButton);
        HBox.setMargin(viewAccuracyButton, new Insets(50, 0, 20, 140));
        borderPane.setBottom(bottomBox);

        Scene scene = new Scene(borderPane, 800, 640);
        stage.setTitle("口算习题薄");
        stage.setScene(scene);
        stage.show();

        infoTextArea.setPrefSize(400, 110);
        //将TextArea控件其设置为只读
        infoTextArea.setEditable(false);

        HBox showbottomBox = new HBox(140, viewAccuracyButton, infoTextArea);
        HBox.setMargin(infoTextArea, new Insets(20, 0, 20, 0));
        borderPane.setBottom(showbottomBox);


    }


    public static void main(String[] args) {
        launch();
    }

    //为了使generate的事件处理器更美观特意拉出了这个类
    public EquationCollection generateEquation() {
        // 创建一个警示对话框
        TextInputDialog dialog = new TextInputDialog("5");
        dialog.setTitle("请输入算式数量");
        dialog.setHeaderText(null);
        dialog.setContentText("算式数量:");

        // 显示对话框,并获取用户输入的算式数量
        Optional<String> result = dialog.showAndWait();
        if (result.isPresent())
        {
            int n = Integer.parseInt(result.get());

            // 生成算式
            EquationCollection equationCollection = generateEquations(n);

            // 清空之前的内容
            flowPane.getChildren().clear();

            // 遍历算式集合并显示在GUI中
            for (IEquation equation : equationCollection)
            {
                maxID++; // id自增
                Label idLabel = new Label(String.valueOf(maxID)); // 获取当前最大ID,并将新的算式ID设为其加1
                Label equationLabel = new Label(equation.toString());
                TextField answerField = new TextField(); // 创建一个新的文本框
                HBox equationBox = new HBox(10, idLabel, new Label("、"), equationLabel, answerField); // 将算式ID标签、顿号、算式标签和文本框放入水平布局
                flowPane.getChildren().add(equationBox); // 将水平布局添加到 flowPane 中
            }

            // 连接数据库
            connectDatabase();
        }
        return null;
    }

    // 生成算式的方法
    public EquationCollection generateEquations(int n) {
        EquationCollection equationCollection = new EquationCollection();
        EquationCheckerOfRange equationChecker = new EquationCheckerOfRange(0, 100);
        equationCollection.generate(n, equationChecker);
        return equationCollection;
    }

    // 连接数据库的方法
    public void connectDatabase() {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            DatabaseMetaData dbMeta = conn.getMetaData();
            System.out.println("当前用户:" + dbMeta.getUserName());
            System.out.println("驱动版本:" + dbMeta.getDriverVersion());
            System.out.println("MySQL版本:" + dbMeta.getDatabaseProductVersion());

            stmt = conn.createStatement();

            // 查询最大ID值
            ResultSet rs = stmt.executeQuery("SELECT MAX(id) FROM equationtable");
            if (rs.next()) {
                maxID = rs.getInt(1);
            }

        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }

    private void saveEquations() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            for (Node node : flowPane.getChildren()) {
                if (node instanceof HBox) {
                    HBox equationBox = (HBox) node;
                    Label idLabel = (Label) equationBox.getChildren().get(0); // 获取算式ID标签
                    Label equationLabel = (Label) equationBox.getChildren().get(2);
                    TextField answerField = (TextField) equationBox.getChildren().get(3);

                    String equation = equationLabel.getText();
                    String answerText = answerField.getText();

                    // 检查答案字段是否为空
                    int answer = 0;
                    if (!answerText.isEmpty()) {
                        answer = Integer.parseInt(answerText);
                    }

                    // 计算正确结果
                    int result = calculateResult(equation);

                    // 保存到数据库
                    String sql = "INSERT INTO equationtable (id, Operand1, Operator, Operand2, Result) VALUES (?, ?, ?, ?, ?)";
                    pstmt = conn.prepareStatement(sql);
                    pstmt.setInt(1, Integer.parseInt(idLabel.getText())); // 将算式ID插入到数据库中
                    pstmt.setInt(2, getOperand1(equation));
                    pstmt.setString(3, getOperator(equation));
                    pstmt.setInt(4, getOperand2(equation));
                    pstmt.setInt(5, result);
                    pstmt.executeUpdate();
                }
            }

            System.out.println("算式保存成功!!!");
            showAlert("保存成功!");
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (pstmt != null)
                    pstmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }



    private int calculateResult(String equation) {
        String[] parts = equation.split(" ");
        int operand1 = Integer.parseInt(parts[0]);
        int operand2 = Integer.parseInt(parts[2]);
        String operator = parts[1];

        int result = 0;
        switch (operator) {
            case "+":
                result = operand1 + operand2;
                break;
            case "-":
                result = operand1 - operand2;
                break;
            case "*":          //此处预设乘法和除法便于以后相应的添加功能
                result = operand1 * operand2;
                break;
            case "/":
                result = operand1 / operand2;
                break;
        }

        return result;
    }

    private int getOperand1(String equation) {
        String[] parts = equation.split(" ");
        return Integer.parseInt(parts[0]);
    }

    private String getOperator(String equation) {
        String[] parts = equation.split(" ");
        return parts[1];
    }

    private int getOperand2(String equation) {
        String[] parts = equation.split(" ");
        return Integer.parseInt(parts[2]);
    }

    private void showAlert(String message) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("提示信息");
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }

    private void displayAllEquationsFromDatabase() {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            stmt = conn.createStatement();

            ResultSet rs = stmt.executeQuery("SELECT * FROM equationtable");
            if (!rs.next()) {
                showAlert("当前题库为空");
            } else {
                do {
                    int id = rs.getInt("id");
                    String equation = id + "、 " + rs.getInt("Operand1") + " " + rs.getString("Operator") + " " +
                            rs.getInt("Operand2") + " = " + rs.getInt("Result");
                    Label equationLabel = new Label(equation);
                    flowPane.getChildren().add(equationLabel);
                } while (rs.next());
            }

        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }

    private void checkEquations() {
        int totalEquations = 0; // 总题数
        int correctAnswers = 0; // 答对题数
        int incorrectAnswers = 0; // 答错题数

        for (Node node : flowPane.getChildren()) {
            if (node instanceof HBox) {
                HBox equationBox = (HBox) node;
                Label equationLabel = (Label) equationBox.getChildren().get(2);
                TextField answerField = (TextField) equationBox.getChildren().get(3);
                String equation = equationLabel.getText();
                String answerText = answerField.getText();
                // 检查答案字段是否为空
                if (!answerText.isEmpty()) {
                    totalEquations++;
                    int userAnswer = Integer.parseInt(answerText);
                    int result = calculateResult(equation);
                    if (userAnswer == result) { // 答案正确
                        equationBox.setStyle("-fx-background-color: #99ff99"); // 设置背景色为绿色
                        correctAnswers++;
                    } else { // 答案错误
                        equationBox.setStyle("-fx-background-color: #ff9999"); // 设置背景色为红色
                        incorrectAnswers++;
                    }
                }
            }
        }

        double correctPercentage = (double) correctAnswers / totalEquations * 100;
        double incorrectPercentage = (double) incorrectAnswers / totalEquations * 100;

        infoTextArea.setText("统计信息:\n" +
                "总题数:" + totalEquations + "\n" +
                "正确题数:" + correctAnswers + "\n" +
                "错误题数:" + incorrectAnswers + "\n" +
                "正确率:" + String.format("%.2f", correctPercentage) + "%\n" +
                "错误率:" + String.format("%.2f", incorrectPercentage) + "%");
    }

    private void showAccuracyChart() {
        int totalEquations = 0; // 总题数
        int correctAnswers = 0; // 答对题数
        for (Node node : flowPane.getChildren()) {
            if (node instanceof HBox) {
                HBox equationBox = (HBox) node;
                Label equationLabel = (Label) equationBox.getChildren().get(2);
                TextField answerField = (TextField) equationBox.getChildren().get(3);
                String equation = equationLabel.getText();
                String answerText = answerField.getText();
                // 检查答案字段是否为空
                if (!answerText.isEmpty()) {
                    totalEquations++;
                    int userAnswer = Integer.parseInt(answerText);
                    int result = calculateResult(equation);
                    if (userAnswer == result) { // 答案正确
                        correctAnswers++;
                    }
                }
            }
        }
        // 创建一个饼状图数据
        double correctPercentage = (double) correctAnswers / totalEquations * 100;
        double incorrectPercentage = 100 - correctPercentage;

        infoTextArea.setText("统计信息:\n" +
                "总题数:" + totalEquations + "\n" +
                "正确题数:" + correctAnswers + "\n" +
                "错误题数:" + (totalEquations - correctAnswers) + "\n" +
                "正确率:" + String.format("%.2f", correctPercentage) + "%\n" +
                "错误率:" + String.format("%.2f", incorrectPercentage) + "%");

        // 创建饼状图并显示
        PieChart chart = new PieChart();
        ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList(
                new PieChart.Data("Correct", correctAnswers),
                new PieChart.Data("Incorrect", totalEquations - correctAnswers)
        );
        chart.setData(pieChartData);
        chart.setTitle("Accuracy Chart");

        // 创建一个新的Stage来显示饼状图
        Stage chartStage = new Stage();
        chartStage.setScene(new Scene(chart, 600, 400));
        chartStage.show();
    }

}
为Delete by serial number按钮和Delete all按钮创建事件处理器,点击Delete by serial number按钮后,调用读取方法,读取数据库中所有题目展示到界面中,然后弹出警示对话框,警示对话框内有两个textfield,让用户输入ID范围,输入后点击确定则从数据库删除输入ID范围的算数式,并使用警示对话框弹出删除成功;如果输入超出范围则用警示对话框提示超出范围。点击Delete all按钮则直接删除数据库中所有算数式,并使用警示对话框展示删除成功。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-31 20:49:40 | 显示全部楼层
zqy173590939 发表于 2023-12-31 20:49
@FishC
package com.example.javafxmw;

import ga ...


首先,我们需要为"Delete by serial number"按钮和"Delete all"按钮创建事件处理器。事件处理器会在用户点击按钮时执行相应的操作。

下面是实现这两个按钮事件处理器的代码:

  1. // Delete by serial number按钮的点击事件监听器
  2. deleteBySerialNumberButton.setOnAction(new EventHandler<ActionEvent>() {
  3.     @Override
  4.     public void handle(ActionEvent event) {
  5.         // 读取数据库中的所有题目并展示到界面上
  6.         flowPane.getChildren().clear();
  7.         displayAllEquationsFromDatabase();

  8.         // 创建一个对话框
  9.         Dialog<Pair<String, String>> dialog = new Dialog<>();
  10.         dialog.setTitle("删除算数式");
  11.         dialog.setHeaderText(null);

  12.         // 设置对话框的图标
  13.         Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
  14.         stage.getIcons().add(new Image("/path/to/your/icon.png"));

  15.         // 设置对话框的按钮
  16.         ButtonType deleteButtonType = new ButtonType("Delete", ButtonBar.ButtonData.OK_DONE);
  17.         dialog.getDialogPane().getButtonTypes().addAll(deleteButtonType, ButtonType.CANCEL);

  18.         // 创建输入字段
  19.         TextField startTextField = new TextField();
  20.         TextField endTextField = new TextField();

  21.         // 将输入字段添加到对话框的内容面板中
  22.         GridPane gridPane = new GridPane();
  23.         gridPane.setHgap(10);
  24.         gridPane.setVgap(10);
  25.         gridPane.addRow(0, new Label("起始ID: "), startTextField);
  26.         gridPane.addRow(1, new Label("结束ID: "), endTextField);
  27.         dialog.getDialogPane().setContent(gridPane);

  28.         // 设置按钮点击事件处理器
  29.         Node deleteButton = dialog.getDialogPane().lookupButton(deleteButtonType);
  30.         deleteButton.setDisable(true); // 默认禁用删除按钮

  31.         startTextField.textProperty().addListener((observable, oldValue, newValue) -> {
  32.             deleteButton.setDisable(newValue.trim().isEmpty()); // 当输入字段为空时禁用删除按钮
  33.         });

  34.         // 显示对话框并等待用户操作
  35.         Optional<Pair<String, String>> result = dialog.showAndWait();

  36.         // 处理用户点击确定按钮的情况
  37.         result.ifPresent(pair -> {
  38.             int startID = Integer.parseInt(pair.getKey());
  39.             int endID = Integer.parseInt(pair.getValue());

  40.             // 检查输入ID范围是否合法
  41.             if (startID >= 1 && endID >= startID && endID <= maxID) {
  42.                 // 删除数据库中指定ID范围的算术式
  43.                 deleteEquations(startID, endID);

  44.                 // 清空界面上删除的算术式
  45.                 for (Node node : flowPane.getChildren()) {
  46.                     if (node instanceof HBox) {
  47.                         HBox equationBox = (HBox) node;
  48.                         Label idLabel = (Label) equationBox.getChildren().get(0);
  49.                         int id = Integer.parseInt(idLabel.getText());

  50.                         if (id >= startID && id <= endID) {
  51.                             flowPane.getChildren().remove(node);
  52.                         }
  53.                     }
  54.                 }

  55.                 showAlert("算术式删除成功!");
  56.             } else {
  57.                 showAlert("输入的ID范围不合法!");
  58.             }
  59.         });
  60.     }
  61. });

  62. // Delete all按钮的点击事件监听器
  63. deleteAllButton.setOnAction(new EventHandler<ActionEvent>() {
  64.     @Override
  65.     public void handle(ActionEvent event) {
  66.         // 删除数据库中的所有算术式
  67.         deleteAllEquations();

  68.         // 清空界面上的所有算术式
  69.         flowPane.getChildren().clear();

  70.         showAlert("所有算术式删除成功!");
  71.     }
  72. });
复制代码


然后,我们需要实现`deleteEquations`方法和`deleteAllEquations`方法来删除数据库中的算术式。以下是实现这两个方法的代码:

  1. // 删除数据库中指定ID范围的算术式
  2. private void deleteEquations(int startID, int endID) {
  3.     Connection conn = null;
  4.     PreparedStatement pstmt = null;
  5.     try {
  6.         Class.forName("com.mysql.cj.jdbc.Driver");
  7.         conn = DriverManager.getConnection(
  8.                 "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
  9.                 "root", "Zqy173590939");

  10.         String sql = "DELETE FROM equationtable WHERE id >= ? AND id <= ?";
  11.         pstmt = conn.prepareStatement(sql);
  12.         pstmt.setInt(1, startID);
  13.         pstmt.setInt(2, endID);
  14.         pstmt.executeUpdate();
  15.     } catch (SQLException se) {
  16.         se.printStackTrace();
  17.     } catch (Exception e) {
  18.         e.printStackTrace();
  19.     } finally {
  20.         try {
  21.             if (pstmt != null)
  22.                 pstmt.close();
  23.             if (conn != null)
  24.                 conn.close();
  25.         } catch (SQLException se) {
  26.             se.printStackTrace();
  27.         }
  28.     }
  29.     System.out.println("Goodbye!");
  30. }

  31. // 删除数据库中的所有算术式
  32. private void deleteAllEquations() {
  33.     Connection conn = null;
  34.     Statement stmt = null;
  35.     try {
  36.         Class.forName("com.mysql.cj.jdbc.Driver");
  37.         conn = DriverManager.getConnection(
  38.                 "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
  39.                 "root", "Zqy173590939");

  40.         stmt = conn.createStatement();

  41.         String sql = "DELETE FROM equationtable";
  42.         stmt.executeUpdate(sql);
  43.     } catch (SQLException se) {
  44.         se.printStackTrace();
  45.     } catch (Exception e) {
  46.         e.printStackTrace();
  47.     } finally {
  48.         try {
  49.             if (stmt != null)
  50.                 stmt.close();
  51.             if (conn != null)
  52.                 conn.close();
  53.         } catch (SQLException se) {
  54.             se.printStackTrace();
  55.         }
  56.     }
  57.     System.out.println("Goodbye!");
  58. }
复制代码


最后,我们需要添加一个新的按钮`deleteBySerialNumberButton`和一个新的按钮`deleteAllButton`来代表"Delete by serial number"按钮和"Delete all"按钮。以下是相应的代码:

  1. Button deleteBySerialNumberButton = new Button("Delete by serial number");
  2. Button deleteAllButton = new Button("Delete all");

  3. HBox deleteButtonBox = new HBox(10, deleteBySerialNumberButton, deleteAllButton);
  4. deleteButtonBox.setPadding(new Insets(20));
  5. borderPane.setBottom(deleteButtonBox);
复制代码


将上述代码添加到`start`方法的最后一行,就可以在界面上添加"Delete by serial number"按钮和"Delete all"按钮,并为其添加事件处理器了。

希望以上解答对你有帮助!如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-31 21:02:52 | 显示全部楼层
FishC 发表于 2023-12-31 20:49
首先,我们需要为"Delete by serial number"按钮和"Delete all"按钮创建事件处理器。事件处理器会在用 ...

Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: class javafx.scene.control.ButtonType cannot be cast to class javafx.util.Pair (javafx.scene.control.ButtonType and javafx.util.Pair are in unnamed module of loader 'app')
        at java.base/java.util.Optional.ifPresent(Optional.java:178)
        at com.example.javafxmw.HelloApplication$6.handle(HelloApplication.java:137)
        at com.example.javafxmw.HelloApplication$6.handle(HelloApplication.java:93)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.control.MenuItem.fire(MenuItem.java:459)
        at com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1385)
        at com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.lambda$createChildren$12(ContextMenuContent.java:1338)
        at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.Scene$MouseHandler.process(Scene.java:3897)
        at javafx.scene.Scene.processMouseEvent(Scene.java:1878)
        at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2623)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
        at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
        at com.sun.glass.ui.View.handleMouseEvent(View.java:557)
        at com.sun.glass.ui.View.notifyMouse(View.java:943)
        at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
        at java.base/java.lang.Thread.run(Thread.java:842)
出现了以下问题,请修正
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-31 21:02:57 | 显示全部楼层
zqy173590939 发表于 2023-12-31 21:02
Exception in thread "JavaFX Application Thread" ja ...


出现了ClassCastException,因为JavaFX的ButtonType和Pair属于不同的类,无法直接进行转换。要解决这个问题,我们可以使用一个自定义类来存储起

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-31 21:08:52 | 显示全部楼层
FishC 发表于 2023-12-31 20:49
首先,我们需要为"Delete by serial number"按钮和"Delete all"按钮创建事件处理器。事件处理器会在用 ...

Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: class javafx.scene.control.ButtonType cannot be cast to class javafx.util.Pair (javafx.scene.control.ButtonType and javafx.util.Pair are in unnamed module of loader 'app')
        at java.base/java.util.Optional.ifPresent(Optional.java:178)
        at com.example.javafxmw.HelloApplication$6.handle(HelloApplication.java:137)
        at com.example.javafxmw.HelloApplication$6.handle(HelloApplication.java:93)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.control.MenuItem.fire(MenuItem.java:459)
        at com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1385)
        at com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.lambda$createChildren$12(ContextMenuContent.java:1338)
        at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.Scene$MouseHandler.process(Scene.java:3897)
        at javafx.scene.Scene.processMouseEvent(Scene.java:1878)
        at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2623)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
        at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
        at com.sun.glass.ui.View.handleMouseEvent(View.java:557)
        at com.sun.glass.ui.View.notifyMouse(View.java:943)
        at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
        at java.base/java.lang.Thread.run(Thread.java:842)
出现了以下问题,请修正
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-31 21:09:03 | 显示全部楼层
zqy173590939 发表于 2023-12-31 21:08
Exception in thread "JavaFX Application Thread" ja ...


问题出在代码的这一行:

```
result.ifPresent(pair -> {
    int startID = Integer.parseInt(pair.getKey());
    int endID = Integer.parseInt(pair.getValue());
    // 检查输入ID范围是否

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-31 21:09:55 | 显示全部楼层
FishC 发表于 2023-12-31 20:49
首先,我们需要为"Delete by serial number"按钮和"Delete all"按钮创建事件处理器。事件处理器会在用 ...

Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: class javafx.scene.control.ButtonType cannot be cast to class javafx.util.Pair (javafx.scene.control.ButtonType and javafx.util.Pair are in unnamed module of loader 'app')
        at java.base/java.util.Optional.ifPresent(Optional.java:178)
        at com.example.javafxmw.HelloApplication$6.handle(HelloApplication.java:137)
        at com.example.javafxmw.HelloApplication$6.handle(HelloApplication.java:93)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.control.MenuItem.fire(MenuItem.java:459)
        at com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1385)
        at com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.lambda$createChildren$12(ContextMenuContent.java:1338)
        at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.Scene$MouseHandler.process(Scene.java:3897)
        at javafx.scene.Scene.processMouseEvent(Scene.java:1878)
        at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2623)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
        at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
        at com.sun.glass.ui.View.handleMouseEvent(View.java:557)
        at com.sun.glass.ui.View.notifyMouse(View.java:943)
        at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
        at java.base/java.lang.Thread.run(Thread.java:842)
修正此问题,请给出修改后的代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-31 21:10:03 | 显示全部楼层
zqy173590939 发表于 2023-12-31 21:09
Exception in thread "JavaFX Application Thread" ja ...


您好,根据报错信息,问题出在将ButtonType转换为Pair的地方。在JavaFX中,ButtonType是用于表示对话框的按钮类型的类,而不是用来表示键

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-31 21:12:18 | 显示全部楼层
@FishC
package com.example.javafxmw;

import gaijin3.*;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Pair;

import java.io.IOException;
import java.sql.*;
import java.util.Optional;

public class HelloApplication extends Application
{
    // 定义全局变量
    //定义一个TextArea控件作为全局变量
    TextArea infoTextArea = new TextArea();

    Button viewAccuracyButton = new Button("View Accuracy");

    FlowPane flowPane = new FlowPane();
    ScrollPane scrollPane = new ScrollPane();// 创建一个滚动面板对象
    private int maxID = 0;

    @Override
    public void start(Stage stage) throws IOException {
        MenuItem generateMenuItem = new MenuItem("Generate");

        // 事件处理器代码
        generateMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                generateEquation();
            }
        });

        MenuItem saveMenuItem = new MenuItem("Save");

        saveMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                saveEquations();
                connectDatabase();
            }
        });

        MenuItem readMenuItem = new MenuItem("Read");

        readMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                flowPane.getChildren().clear(); // 清空当前GUI界面
                showAlert("习题已读取");
                displayAllEquationsFromDatabase();
            }
        });

        MenuItem checkMenuItem = new MenuItem("Check");

        checkMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 检查习题
                checkEquations();
            }
        });

        // View Accuracy按钮的点击事件监听器
        viewAccuracyButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 显示饼状图
                showAccuracyChart();
            }
        });

        MenuItem deleteMenuItem = new MenuItem("Delete by serial number");

        

        MenuItem deleteMenuItem1 = new MenuItem("Delete all");

        // Delete all按钮的点击事件监听器
        deleteMenuItem1.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 删除数据库中的所有算术式
                deleteAllEquations();

                // 清空界面上的所有算术式
                flowPane.getChildren().clear();

                showAlert("所有算术式删除成功!");
            }
        });

        Menu fileMenu = new Menu("File");
        Menu saveMenu = new Menu("SaveEquation");
        Menu readMenu = new Menu("ReadEquation");
        Menu checkMenu = new Menu("CheckEquation");
        Menu deleteMenu = new Menu("Delete");

        fileMenu.getItems().addAll(generateMenuItem);
        saveMenu.getItems().add(saveMenuItem);
        readMenu.getItems().add(readMenuItem);
        checkMenu.getItems().add(checkMenuItem);
        deleteMenu.getItems().addAll(deleteMenuItem,deleteMenuItem1);

        MenuBar menuBar = new MenuBar();
        menuBar.getMenus().addAll(fileMenu);
        menuBar.getMenus().add(saveMenu);
        menuBar.getMenus().add(readMenu);
        menuBar.getMenus().add(checkMenu);
        menuBar.getMenus().add(deleteMenu);

        flowPane.setHgap(50);
        flowPane.setVgap(30);
        flowPane.setPadding(new Insets(20));
        flowPane.setPrefSize(800, 560); // 设置 FlowPane 的大小

        BorderPane borderPane = new BorderPane();
        borderPane.setTop(menuBar);
        borderPane.setCenter(flowPane);

        //为了解决题目生成或多flowpane没有拖动条无法显示的问题
        // 将FlowPane放在一个ScrollPane中
        scrollPane.setContent(flowPane);// 设置滚动面板的内容为 flowPane,即将 flowPane 放入滚动面板中
        scrollPane.setFitToHeight(true);// 可以让滚动面板的高度自适应内容的高度
        borderPane.setCenter(scrollPane); // 将ScrollPane放置在中心位置

        HBox bottomBox = new HBox(10, viewAccuracyButton);
        HBox.setMargin(viewAccuracyButton, new Insets(50, 0, 20, 140));
        borderPane.setBottom(bottomBox);

        Scene scene = new Scene(borderPane, 800, 640);
        stage.setTitle("口算习题薄");
        stage.setScene(scene);
        stage.show();

        infoTextArea.setPrefSize(400, 110);
        //将TextArea控件其设置为只读
        infoTextArea.setEditable(false);

        HBox showbottomBox = new HBox(140, viewAccuracyButton, infoTextArea);
        HBox.setMargin(infoTextArea, new Insets(20, 0, 20, 0));
        borderPane.setBottom(showbottomBox);


    }


    public static void main(String[] args) {
        launch();
    }

    //为了使generate的事件处理器更美观特意拉出了这个类
    public EquationCollection generateEquation() {
        // 创建一个警示对话框
        TextInputDialog dialog = new TextInputDialog("5");
        dialog.setTitle("请输入算式数量");
        dialog.setHeaderText(null);
        dialog.setContentText("算式数量:");

        // 显示对话框,并获取用户输入的算式数量
        Optional<String> result = dialog.showAndWait();
        if (result.isPresent())
        {
            int n = Integer.parseInt(result.get());

            // 生成算式
            EquationCollection equationCollection = generateEquations(n);

            // 清空之前的内容
            flowPane.getChildren().clear();

            // 遍历算式集合并显示在GUI中
            for (IEquation equation : equationCollection)
            {
                maxID++; // id自增
                Label idLabel = new Label(String.valueOf(maxID)); // 获取当前最大ID,并将新的算式ID设为其加1
                Label equationLabel = new Label(equation.toString());
                TextField answerField = new TextField(); // 创建一个新的文本框
                HBox equationBox = new HBox(10, idLabel, new Label("、"), equationLabel, answerField); // 将算式ID标签、顿号、算式标签和文本框放入水平布局
                flowPane.getChildren().add(equationBox); // 将水平布局添加到 flowPane 中
            }

            // 连接数据库
            connectDatabase();
        }
        return null;
    }

    // 生成算式的方法
    public EquationCollection generateEquations(int n) {
        EquationCollection equationCollection = new EquationCollection();
        EquationCheckerOfRange equationChecker = new EquationCheckerOfRange(0, 100);
        equationCollection.generate(n, equationChecker);
        return equationCollection;
    }

    // 连接数据库的方法
    public void connectDatabase() {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            DatabaseMetaData dbMeta = conn.getMetaData();
            System.out.println("当前用户:" + dbMeta.getUserName());
            System.out.println("驱动版本:" + dbMeta.getDriverVersion());
            System.out.println("MySQL版本:" + dbMeta.getDatabaseProductVersion());

            stmt = conn.createStatement();

            // 查询最大ID值
            ResultSet rs = stmt.executeQuery("SELECT MAX(id) FROM equationtable");
            if (rs.next()) {
                maxID = rs.getInt(1);
            }

        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }

    private void saveEquations() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            for (Node node : flowPane.getChildren()) {
                if (node instanceof HBox) {
                    HBox equationBox = (HBox) node;
                    Label idLabel = (Label) equationBox.getChildren().get(0); // 获取算式ID标签
                    Label equationLabel = (Label) equationBox.getChildren().get(2);
                    TextField answerField = (TextField) equationBox.getChildren().get(3);

                    String equation = equationLabel.getText();
                    String answerText = answerField.getText();

                    // 检查答案字段是否为空
                    int answer = 0;
                    if (!answerText.isEmpty()) {
                        answer = Integer.parseInt(answerText);
                    }

                    // 计算正确结果
                    int result = calculateResult(equation);

                    // 保存到数据库
                    String sql = "INSERT INTO equationtable (id, Operand1, Operator, Operand2, Result) VALUES (?, ?, ?, ?, ?)";
                    pstmt = conn.prepareStatement(sql);
                    pstmt.setInt(1, Integer.parseInt(idLabel.getText())); // 将算式ID插入到数据库中
                    pstmt.setInt(2, getOperand1(equation));
                    pstmt.setString(3, getOperator(equation));
                    pstmt.setInt(4, getOperand2(equation));
                    pstmt.setInt(5, result);
                    pstmt.executeUpdate();
                }
            }

            System.out.println("算式保存成功!!!");
            showAlert("保存成功!");
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (pstmt != null)
                    pstmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }



    private int calculateResult(String equation) {
        String[] parts = equation.split(" ");
        int operand1 = Integer.parseInt(parts[0]);
        int operand2 = Integer.parseInt(parts[2]);
        String operator = parts[1];

        int result = 0;
        switch (operator) {
            case "+":
                result = operand1 + operand2;
                break;
            case "-":
                result = operand1 - operand2;
                break;
            case "*":          //此处预设乘法和除法便于以后相应的添加功能
                result = operand1 * operand2;
                break;
            case "/":
                result = operand1 / operand2;
                break;
        }

        return result;
    }

    private int getOperand1(String equation) {
        String[] parts = equation.split(" ");
        return Integer.parseInt(parts[0]);
    }

    private String getOperator(String equation) {
        String[] parts = equation.split(" ");
        return parts[1];
    }

    private int getOperand2(String equation) {
        String[] parts = equation.split(" ");
        return Integer.parseInt(parts[2]);
    }

    private void showAlert(String message) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("提示信息");
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }

    private void displayAllEquationsFromDatabase() {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            stmt = conn.createStatement();

            ResultSet rs = stmt.executeQuery("SELECT * FROM equationtable");
            if (!rs.next()) {
                showAlert("当前题库为空");
            } else {
                do {
                    int id = rs.getInt("id");
                    String equation = id + "、 " + rs.getInt("Operand1") + " " + rs.getString("Operator") + " " +
                            rs.getInt("Operand2") + " = " + rs.getInt("Result");
                    Label equationLabel = new Label(equation);
                    flowPane.getChildren().add(equationLabel);
                } while (rs.next());
            }

        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }

    private void checkEquations() {
        int totalEquations = 0; // 总题数
        int correctAnswers = 0; // 答对题数
        int incorrectAnswers = 0; // 答错题数

        for (Node node : flowPane.getChildren()) {
            if (node instanceof HBox) {
                HBox equationBox = (HBox) node;
                Label equationLabel = (Label) equationBox.getChildren().get(2);
                TextField answerField = (TextField) equationBox.getChildren().get(3);
                String equation = equationLabel.getText();
                String answerText = answerField.getText();
                // 检查答案字段是否为空
                if (!answerText.isEmpty()) {
                    totalEquations++;
                    int userAnswer = Integer.parseInt(answerText);
                    int result = calculateResult(equation);
                    if (userAnswer == result) { // 答案正确
                        equationBox.setStyle("-fx-background-color: #99ff99"); // 设置背景色为绿色
                        correctAnswers++;
                    } else { // 答案错误
                        equationBox.setStyle("-fx-background-color: #ff9999"); // 设置背景色为红色
                        incorrectAnswers++;
                    }
                }
            }
        }

        double correctPercentage = (double) correctAnswers / totalEquations * 100;
        double incorrectPercentage = (double) incorrectAnswers / totalEquations * 100;

        infoTextArea.setText("统计信息:\n" +
                "总题数:" + totalEquations + "\n" +
                "正确题数:" + correctAnswers + "\n" +
                "错误题数:" + incorrectAnswers + "\n" +
                "正确率:" + String.format("%.2f", correctPercentage) + "%\n" +
                "错误率:" + String.format("%.2f", incorrectPercentage) + "%");
    }

    private void showAccuracyChart() {
        int totalEquations = 0; // 总题数
        int correctAnswers = 0; // 答对题数
        for (Node node : flowPane.getChildren()) {
            if (node instanceof HBox) {
                HBox equationBox = (HBox) node;
                Label equationLabel = (Label) equationBox.getChildren().get(2);
                TextField answerField = (TextField) equationBox.getChildren().get(3);
                String equation = equationLabel.getText();
                String answerText = answerField.getText();
                // 检查答案字段是否为空
                if (!answerText.isEmpty()) {
                    totalEquations++;
                    int userAnswer = Integer.parseInt(answerText);
                    int result = calculateResult(equation);
                    if (userAnswer == result) { // 答案正确
                        correctAnswers++;
                    }
                }
            }
        }
        // 创建一个饼状图数据
        double correctPercentage = (double) correctAnswers / totalEquations * 100;
        double incorrectPercentage = 100 - correctPercentage;

        infoTextArea.setText("统计信息:\n" +
                "总题数:" + totalEquations + "\n" +
                "正确题数:" + correctAnswers + "\n" +
                "错误题数:" + (totalEquations - correctAnswers) + "\n" +
                "正确率:" + String.format("%.2f", correctPercentage) + "%\n" +
                "错误率:" + String.format("%.2f", incorrectPercentage) + "%");

        // 创建饼状图并显示
        PieChart chart = new PieChart();
        ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList(
                new PieChart.Data("Correct", correctAnswers),
                new PieChart.Data("Incorrect", totalEquations - correctAnswers)
        );
        chart.setData(pieChartData);
        chart.setTitle("Accuracy Chart");

        // 创建一个新的Stage来显示饼状图
        Stage chartStage = new Stage();
        chartStage.setScene(new Scene(chart, 600, 400));
        chartStage.show();
    }

   

    // 删除数据库中的所有算术式
    private void deleteAllEquations() {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            stmt = conn.createStatement();

            String sql = "DELETE FROM equationtable";
            stmt.executeUpdate(sql);
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }



}
为Delete by serial number按钮创建事件处理器,点击Delete by serial number按钮后,调用读取方法,读取数据库中所有题目展示到界面中,然后弹出警示对话框,警示对话框内有两个textfield,让用户输入ID范围,输入后点击确定则从数据库删除输入ID范围的算数式,并使用警示对话框弹出删除成功;如果输入超出范围则用警示对话框提示超出范围。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-31 21:12:38 | 显示全部楼层
zqy173590939 发表于 2023-12-31 21:12
@FishC
package com.example.javafxmw;

import ga ...


首先,我们需要为 "Delete by serial number" 按钮创建一个事件处理器。在这个事件处理器中,我们需要调用 `displayAllEquationsFromDatabase` 方法,将数据库中的算术式显示到界面上。然后,我们可以使用 `TextInputDialog` 弹出警示对话框,让用户输入要删除的算术式的ID范围。最后,根据用户的输入,在数据库中删除相应的算术式,并显示删除成功的警示对话框。

下面是完整的代码实现:

  1. // 定义 Delete by serial number 按钮的点击事件监听器
  2. deleteMenuItem.setOnAction(new EventHandler() {
  3.     @Override
  4.     public void handle(ActionEvent event) {
  5.         // 显示数据库中的所有算术式
  6.         flowPane.getChildren().clear();
  7.         displayAllEquationsFromDatabase();

  8.         // 创建一个警示对话框并设置标题和头部文本
  9.         TextInputDialog dialog = new TextInputDialog();
  10.         dialog.setTitle("删除算术式");
  11.         dialog.setHeaderText("请输入要删除的算术式的ID范围(格式:start-end)");

  12.         // 获取用户输入的起始ID和结束ID
  13.         Optional<String> result = dialog.showAndWait();
  14.         if (result.isPresent()) {
  15.             String[] ids = result.get().split("-");
  16.             int startID = Integer.parseInt(ids[0]);
  17.             int endID = Integer.parseInt(ids[1]);

  18.             // 删除ID在范围内的算术式
  19.             deleteEquationsByRange(startID, endID);
  20.         }
  21.     }
  22. });

  23. // 删除数据库中范围内的算术式的方法
  24. private void deleteEquationsByRange(int startID, int endID) {
  25.     Connection conn = null;
  26.     Statement stmt = null;
  27.     try {
  28.         Class.forName("com.mysql.cj.jdbc.Driver");
  29.         conn = DriverManager.getConnection(
  30.                 "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
  31.                 "root", "Zqy173590939");

  32.         stmt = conn.createStatement();

  33.         // 查询数据库中符合范围条件的算术式
  34.         ResultSet rs = stmt.executeQuery("SELECT * FROM equationtable WHERE id >= " + startID + " AND id <= " + endID);
  35.         if (rs.next()) {
  36.             // 逐个删除算术式
  37.             do {
  38.                 int id = rs.getInt("id");
  39.                 stmt.executeUpdate("DELETE FROM equationtable WHERE id = " + id);
  40.             } while (rs.next());

  41.             showAlert("算术式删除成功!");
  42.         } else {
  43.             showAlert("没有找到符合范围条件的算术式!");
  44.         }
  45.     } catch (SQLException se) {
  46.         se.printStackTrace();
  47.     } catch (Exception e) {
  48.         e.printStackTrace();
  49.     } finally {
  50.         try {
  51.             if (stmt != null)
  52.                 stmt.close();
  53.             if (conn != null)
  54.                 conn.close();
  55.         } catch (SQLException se) {
  56.             se.printStackTrace();
  57.         }
  58.     }
  59.     System.out.println("Goodbye!");
  60. }
复制代码


请注意,上述代码仅实现了删除数据库中范围内的算术式的功能,对应的界面显示部分需要根据具体情况进行调整。另外,要确保数据库表名和字段名与代码中的一致,否则需要进行相应的修改。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-31 21:16:57 | 显示全部楼层
FishC 发表于 2023-12-31 21:12
首先,我们需要为 "Delete by serial number" 按钮创建一个事件处理器。在这个事件处理器中,我们需要 ...

java.sql.SQLException: Operation not allowed after ResultSet closed
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130)
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:98)
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:90)
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:64)
        at com.mysql.cj.jdbc.result.ResultSetImpl.checkClosed(ResultSetImpl.java:485)
        at com.mysql.cj.jdbc.result.ResultSetImpl.next(ResultSetImpl.java:1802)
        at com.example.javafxmw.HelloApplication.deleteEquationsByRange(HelloApplication.java:533)
        at com.example.javafxmw.HelloApplication$6.handle(HelloApplication.java:113)
        at com.example.javafxmw.HelloApplication$6.handle(HelloApplication.java:93)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.control.MenuItem.fire(MenuItem.java:459)
        at com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1385)
        at com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.lambda$createChildren$12(ContextMenuContent.java:1338)
        at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.Scene$MouseHandler.process(Scene.java:3897)
        at javafx.scene.Scene.processMouseEvent(Scene.java:1878)
        at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2623)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
        at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
        at com.sun.glass.ui.View.handleMouseEvent(View.java:557)
        at com.sun.glass.ui.View.notifyMouse(View.java:943)
        at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
        at java.base/java.lang.Thread.run(Thread.java:842)
出现了以上问题,请改正,给出改正后代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-31 21:17:05 | 显示全部楼层
zqy173590939 发表于 2023-12-31 21:16
java.sql.SQLException: Operation not allowed after ...


在 `deleteEquationsByRange` 方法中,您需要关闭 ResultSet 对象,以确保它不会在查询结束后继续保持打开状态。请尝试在执行完数据库查询后立

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-31 21:27:18 | 显示全部楼层
@FishC
package com.example.javafxmw;

import gaijin3.*;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Pair;

import java.io.IOException;
import java.sql.*;
import java.util.Optional;

public class HelloApplication extends Application
{
    // 定义全局变量
    //定义一个TextArea控件作为全局变量
    TextArea infoTextArea = new TextArea();

    Button viewAccuracyButton = new Button("View Accuracy");

    FlowPane flowPane = new FlowPane();
    ScrollPane scrollPane = new ScrollPane();// 创建一个滚动面板对象
    private int maxID = 0;

    @Override
    public void start(Stage stage) throws IOException {
        MenuItem generateMenuItem = new MenuItem("Generate");

        // 事件处理器代码
        generateMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                generateEquation();
            }
        });

        MenuItem saveMenuItem = new MenuItem("Save");

        saveMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                saveEquations();
                connectDatabase();
            }
        });

        MenuItem readMenuItem = new MenuItem("Read");

        readMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                flowPane.getChildren().clear(); // 清空当前GUI界面
                showAlert("习题已读取");
                displayAllEquationsFromDatabase();
            }
        });

        MenuItem checkMenuItem = new MenuItem("Check");

        checkMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 检查习题
                checkEquations();
            }
        });

        // View Accuracy按钮的点击事件监听器
        viewAccuracyButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 显示饼状图
                showAccuracyChart();
            }
        });

        MenuItem deleteMenuItem = new MenuItem("Delete by serial number");

        

        MenuItem deleteMenuItem1 = new MenuItem("Delete all");

        // Delete all按钮的点击事件监听器
        deleteMenuItem1.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 删除数据库中的所有算术式
                deleteAllEquations();

                // 清空界面上的所有算术式
                flowPane.getChildren().clear();

                showAlert("所有算术式删除成功!");
            }
        });

        Menu fileMenu = new Menu("File");
        Menu saveMenu = new Menu("SaveEquation");
        Menu readMenu = new Menu("ReadEquation");
        Menu checkMenu = new Menu("CheckEquation");
        Menu deleteMenu = new Menu("Delete");

        fileMenu.getItems().addAll(generateMenuItem);
        saveMenu.getItems().add(saveMenuItem);
        readMenu.getItems().add(readMenuItem);
        checkMenu.getItems().add(checkMenuItem);
        deleteMenu.getItems().addAll(deleteMenuItem,deleteMenuItem1);

        MenuBar menuBar = new MenuBar();
        menuBar.getMenus().addAll(fileMenu);
        menuBar.getMenus().add(saveMenu);
        menuBar.getMenus().add(readMenu);
        menuBar.getMenus().add(checkMenu);
        menuBar.getMenus().add(deleteMenu);

        flowPane.setHgap(50);
        flowPane.setVgap(30);
        flowPane.setPadding(new Insets(20));
        flowPane.setPrefSize(800, 560); // 设置 FlowPane 的大小

        BorderPane borderPane = new BorderPane();
        borderPane.setTop(menuBar);
        borderPane.setCenter(flowPane);

        //为了解决题目生成或多flowpane没有拖动条无法显示的问题
        // 将FlowPane放在一个ScrollPane中
        scrollPane.setContent(flowPane);// 设置滚动面板的内容为 flowPane,即将 flowPane 放入滚动面板中
        scrollPane.setFitToHeight(true);// 可以让滚动面板的高度自适应内容的高度
        borderPane.setCenter(scrollPane); // 将ScrollPane放置在中心位置

        HBox bottomBox = new HBox(10, viewAccuracyButton);
        HBox.setMargin(viewAccuracyButton, new Insets(50, 0, 20, 140));
        borderPane.setBottom(bottomBox);

        Scene scene = new Scene(borderPane, 800, 640);
        stage.setTitle("口算习题薄");
        stage.setScene(scene);
        stage.show();

        infoTextArea.setPrefSize(400, 110);
        //将TextArea控件其设置为只读
        infoTextArea.setEditable(false);

        HBox showbottomBox = new HBox(140, viewAccuracyButton, infoTextArea);
        HBox.setMargin(infoTextArea, new Insets(20, 0, 20, 0));
        borderPane.setBottom(showbottomBox);


    }


    public static void main(String[] args) {
        launch();
    }

    //为了使generate的事件处理器更美观特意拉出了这个类
    public EquationCollection generateEquation() {
        // 创建一个警示对话框
        TextInputDialog dialog = new TextInputDialog("5");
        dialog.setTitle("请输入算式数量");
        dialog.setHeaderText(null);
        dialog.setContentText("算式数量:");

        // 显示对话框,并获取用户输入的算式数量
        Optional<String> result = dialog.showAndWait();
        if (result.isPresent())
        {
            int n = Integer.parseInt(result.get());

            // 生成算式
            EquationCollection equationCollection = generateEquations(n);

            // 清空之前的内容
            flowPane.getChildren().clear();

            // 遍历算式集合并显示在GUI中
            for (IEquation equation : equationCollection)
            {
                maxID++; // id自增
                Label idLabel = new Label(String.valueOf(maxID)); // 获取当前最大ID,并将新的算式ID设为其加1
                Label equationLabel = new Label(equation.toString());
                TextField answerField = new TextField(); // 创建一个新的文本框
                HBox equationBox = new HBox(10, idLabel, new Label("、"), equationLabel, answerField); // 将算式ID标签、顿号、算式标签和文本框放入水平布局
                flowPane.getChildren().add(equationBox); // 将水平布局添加到 flowPane 中
            }

            // 连接数据库
            connectDatabase();
        }
        return null;
    }

    // 生成算式的方法
    public EquationCollection generateEquations(int n) {
        EquationCollection equationCollection = new EquationCollection();
        EquationCheckerOfRange equationChecker = new EquationCheckerOfRange(0, 100);
        equationCollection.generate(n, equationChecker);
        return equationCollection;
    }

    // 连接数据库的方法
    public void connectDatabase() {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            DatabaseMetaData dbMeta = conn.getMetaData();
            System.out.println("当前用户:" + dbMeta.getUserName());
            System.out.println("驱动版本:" + dbMeta.getDriverVersion());
            System.out.println("MySQL版本:" + dbMeta.getDatabaseProductVersion());

            stmt = conn.createStatement();

            // 查询最大ID值
            ResultSet rs = stmt.executeQuery("SELECT MAX(id) FROM equationtable");
            if (rs.next()) {
                maxID = rs.getInt(1);
            }

        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }

    private void saveEquations() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            for (Node node : flowPane.getChildren()) {
                if (node instanceof HBox) {
                    HBox equationBox = (HBox) node;
                    Label idLabel = (Label) equationBox.getChildren().get(0); // 获取算式ID标签
                    Label equationLabel = (Label) equationBox.getChildren().get(2);
                    TextField answerField = (TextField) equationBox.getChildren().get(3);

                    String equation = equationLabel.getText();
                    String answerText = answerField.getText();

                    // 检查答案字段是否为空
                    int answer = 0;
                    if (!answerText.isEmpty()) {
                        answer = Integer.parseInt(answerText);
                    }

                    // 计算正确结果
                    int result = calculateResult(equation);

                    // 保存到数据库
                    String sql = "INSERT INTO equationtable (id, Operand1, Operator, Operand2, Result) VALUES (?, ?, ?, ?, ?)";
                    pstmt = conn.prepareStatement(sql);
                    pstmt.setInt(1, Integer.parseInt(idLabel.getText())); // 将算式ID插入到数据库中
                    pstmt.setInt(2, getOperand1(equation));
                    pstmt.setString(3, getOperator(equation));
                    pstmt.setInt(4, getOperand2(equation));
                    pstmt.setInt(5, result);
                    pstmt.executeUpdate();
                }
            }

            System.out.println("算式保存成功!!!");
            showAlert("保存成功!");
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (pstmt != null)
                    pstmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }



    private int calculateResult(String equation) {
        String[] parts = equation.split(" ");
        int operand1 = Integer.parseInt(parts[0]);
        int operand2 = Integer.parseInt(parts[2]);
        String operator = parts[1];

        int result = 0;
        switch (operator) {
            case "+":
                result = operand1 + operand2;
                break;
            case "-":
                result = operand1 - operand2;
                break;
            case "*":          //此处预设乘法和除法便于以后相应的添加功能
                result = operand1 * operand2;
                break;
            case "/":
                result = operand1 / operand2;
                break;
        }

        return result;
    }

    private int getOperand1(String equation) {
        String[] parts = equation.split(" ");
        return Integer.parseInt(parts[0]);
    }

    private String getOperator(String equation) {
        String[] parts = equation.split(" ");
        return parts[1];
    }

    private int getOperand2(String equation) {
        String[] parts = equation.split(" ");
        return Integer.parseInt(parts[2]);
    }

    private void showAlert(String message) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("提示信息");
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }

    private void displayAllEquationsFromDatabase() {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            stmt = conn.createStatement();

            ResultSet rs = stmt.executeQuery("SELECT * FROM equationtable");
            if (!rs.next()) {
                showAlert("当前题库为空");
            } else {
                do {
                    int id = rs.getInt("id");
                    String equation = id + "、 " + rs.getInt("Operand1") + " " + rs.getString("Operator") + " " +
                            rs.getInt("Operand2") + " = " + rs.getInt("Result");
                    Label equationLabel = new Label(equation);
                    flowPane.getChildren().add(equationLabel);
                } while (rs.next());
            }

        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }

    private void checkEquations() {
        int totalEquations = 0; // 总题数
        int correctAnswers = 0; // 答对题数
        int incorrectAnswers = 0; // 答错题数

        for (Node node : flowPane.getChildren()) {
            if (node instanceof HBox) {
                HBox equationBox = (HBox) node;
                Label equationLabel = (Label) equationBox.getChildren().get(2);
                TextField answerField = (TextField) equationBox.getChildren().get(3);
                String equation = equationLabel.getText();
                String answerText = answerField.getText();
                // 检查答案字段是否为空
                if (!answerText.isEmpty()) {
                    totalEquations++;
                    int userAnswer = Integer.parseInt(answerText);
                    int result = calculateResult(equation);
                    if (userAnswer == result) { // 答案正确
                        equationBox.setStyle("-fx-background-color: #99ff99"); // 设置背景色为绿色
                        correctAnswers++;
                    } else { // 答案错误
                        equationBox.setStyle("-fx-background-color: #ff9999"); // 设置背景色为红色
                        incorrectAnswers++;
                    }
                }
            }
        }

        double correctPercentage = (double) correctAnswers / totalEquations * 100;
        double incorrectPercentage = (double) incorrectAnswers / totalEquations * 100;

        infoTextArea.setText("统计信息:\n" +
                "总题数:" + totalEquations + "\n" +
                "正确题数:" + correctAnswers + "\n" +
                "错误题数:" + incorrectAnswers + "\n" +
                "正确率:" + String.format("%.2f", correctPercentage) + "%\n" +
                "错误率:" + String.format("%.2f", incorrectPercentage) + "%");
    }

    private void showAccuracyChart() {
        int totalEquations = 0; // 总题数
        int correctAnswers = 0; // 答对题数
        for (Node node : flowPane.getChildren()) {
            if (node instanceof HBox) {
                HBox equationBox = (HBox) node;
                Label equationLabel = (Label) equationBox.getChildren().get(2);
                TextField answerField = (TextField) equationBox.getChildren().get(3);
                String equation = equationLabel.getText();
                String answerText = answerField.getText();
                // 检查答案字段是否为空
                if (!answerText.isEmpty()) {
                    totalEquations++;
                    int userAnswer = Integer.parseInt(answerText);
                    int result = calculateResult(equation);
                    if (userAnswer == result) { // 答案正确
                        correctAnswers++;
                    }
                }
            }
        }
        // 创建一个饼状图数据
        double correctPercentage = (double) correctAnswers / totalEquations * 100;
        double incorrectPercentage = 100 - correctPercentage;

        infoTextArea.setText("统计信息:\n" +
                "总题数:" + totalEquations + "\n" +
                "正确题数:" + correctAnswers + "\n" +
                "错误题数:" + (totalEquations - correctAnswers) + "\n" +
                "正确率:" + String.format("%.2f", correctPercentage) + "%\n" +
                "错误率:" + String.format("%.2f", incorrectPercentage) + "%");

        // 创建饼状图并显示
        PieChart chart = new PieChart();
        ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList(
                new PieChart.Data("Correct", correctAnswers),
                new PieChart.Data("Incorrect", totalEquations - correctAnswers)
        );
        chart.setData(pieChartData);
        chart.setTitle("Accuracy Chart");

        // 创建一个新的Stage来显示饼状图
        Stage chartStage = new Stage();
        chartStage.setScene(new Scene(chart, 600, 400));
        chartStage.show();
    }

   

    // 删除数据库中的所有算术式
    private void deleteAllEquations() {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            stmt = conn.createStatement();

            String sql = "DELETE FROM equationtable";
            stmt.executeUpdate(sql);
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }



}
修改代码,为Delete by serial number按钮创建事件处理器,点击Delete by serial number按钮后,调用读取方法,读取数据库中所有题目展示到界面中,然后弹出警示对话框,警示对话框内有两个textfield,让用户输入ID范围,输入后点击确定则从数据库删除输入ID范围的算数式,并使用警示对话框弹出删除成功;如果输入超出范围则用警示对话框提示超出范围,如果输入的范围首尾ID都存在,但是,中间缺失了部分序号,则跳过那些确实的需要,保证删除可以正常执行;如果输入的ID范围内,数据库有多条匹配,则把匹配上的全部删除。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-31 21:27:44 | 显示全部楼层
zqy173590939 发表于 2023-12-31 21:27
@FishC
package com.example.javafxmw;

import ga ...


package com.example.javafxmw;

import gaijin3.EquationCollection;
import gaijin3.IEquation;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Pair;

import java.io.IOException;
import java.sql.*;
import java.util.Optional;

public class HelloApplication extends Application {
    // 定义全局变量
    //定义一个TextArea控件作为全局变量
    TextArea infoTextArea = new TextArea();

    Button viewAccuracyButton = new Button("View Accuracy");
    Button deleteBySerialNumberButton = new Button("Delete by serial number");

    FlowPane flowPane = new FlowPane();
    ScrollPane scrollPane = new ScrollPane();// 创建一个滚动面板对象
    private int maxID = 0;

    @Override
    public void start(Stage stage) throws IOException {
        MenuItem generateMenuItem = new MenuItem("Generate");

        // 事件处理器代码
        generateMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                generateEquation();
            }
        });

        MenuItem saveMenuItem = new MenuItem("Save");

        saveMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                saveEquations();
                connectDatabase();
            }
        });

        MenuItem readMenuItem = new MenuItem("Read");

        readMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                flowPane.getChildren().clear(); // 清空当前GUI界面
                showAlert("习题已读取");
                displayAllEquationsFromDatabase();
            }
        });

        MenuItem checkMenuItem = new MenuItem("Check");

        checkMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 检查习题
                checkEquations();
            }
        });

        // View Accuracy按钮的点击事件监听器
        viewAccuracyButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 显示饼状图
                showAccuracyChart();
            }
        });

        // Delete by serial number按钮的点击事件监听器
        deleteBySerialNumberButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 删除算术式
                deleteEquationsBySerialNumber();
            }
        });

        MenuItem deleteMenuItem1 = new MenuItem("Delete all");

        // Delete all按钮的点击事件监听器
        deleteMenuItem1.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 删除数据库中的所有算术式
                deleteAllEquations();

                // 清空界面上的所有算术式
                flowPane.getChildren().clear();

                showAlert("所有算术式删除成功!");
            }
        });

        Menu fileMenu = new Menu("File");
        Menu saveMenu = new Menu("SaveEquation");
        Menu readMenu = new Menu("ReadEquation");
        Menu checkMenu = new Menu("CheckEquation");
        Menu deleteMenu = new Menu("Delete");

        fileMenu.getItems().addAll(generateMenuItem);
        saveMenu.getItems().add(saveMenuItem);
        readMenu.getItems().add(readMenuItem);
        checkMenu.getItems().add(checkMenuItem);
        deleteMenu.getItems().addAll(deleteMenuItem1);

        MenuBar menuBar = new MenuBar();
        menuBar.getMenus().addAll(fileMenu);
        menuBar.getMenus().add(saveMenu);
        menuBar.getMenus().add(readMenu);
        menuBar.getMenus().add(checkMenu);
        menuBar.getMenus().add(deleteMenu);

        flowPane.setHgap(50);
        flowPane.setVgap(30);
        flowPane.setPadding(new Insets(20));
        flowPane.setPrefSize(800, 560); // 设置 FlowPane 的大小

        BorderPane borderPane = new BorderPane();
        borderPane.setTop(menuBar);
        borderPane.setCenter(flowPane);

        //为了解决题目生成或多flowpane没有拖动条无法显示的问题
        // 将FlowPane放在一个ScrollPane中
        scrollPane.setContent(flowPane);// 设置滚动面板的内容为 flowPane,即将 flowPane 放入滚动面板中
        scrollPane.setFitToHeight(true);// 可以让滚动面板的高度自适应内容的高度
        borderPane.setCenter(scrollPane); // 将ScrollPane放置在中心位置

        HBox bottomBox = new HBox(10, viewAccuracyButton, deleteBySerialNumberButton);
        HBox.setMargin(viewAccuracyButton, new Insets(50, 0, 20, 140));
        HBox.setMargin(deleteBySerialNumberButton, new Insets(50, 0, 20, 0));
        borderPane.setBottom(bottomBox);

        Scene scene = new Scene(borderPane, 800, 640);
        stage.setTitle("口算习题薄");
        stage.setScene(scene);
        stage.show();

        infoTextArea.setPrefSize(400, 110);
        //将TextArea控件其设置为只读
        infoTextArea.setEditable(false);

        HBox showbottomBox = new HBox(140, viewAccuracyButton, deleteBySerialNumberButton, infoTextArea);
        HBox.setMargin(infoTextArea, new Insets(20, 0, 20, 0));
        borderPane.setBottom(showbottomBox);


    }

    public static void main(String[] args) {
        launch();
    }

    //为了使generate的事件处理器更美观特意拉出了这个方法
    public EquationCollection generateEquation() {
        // 创建一个警示对话框
        TextInputDialog dialog = new TextInputDialog("5");

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-31 21:28:26 | 显示全部楼层
@FishC
package com.example.javafxmw;

import gaijin3.*;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Pair;

import java.io.IOException;
import java.sql.*;
import java.util.Optional;

public class HelloApplication extends Application
{
    // 定义全局变量
    //定义一个TextArea控件作为全局变量
    TextArea infoTextArea = new TextArea();

    Button viewAccuracyButton = new Button("View Accuracy");

    FlowPane flowPane = new FlowPane();
    ScrollPane scrollPane = new ScrollPane();// 创建一个滚动面板对象
    private int maxID = 0;

    @Override
    public void start(Stage stage) throws IOException {
        MenuItem generateMenuItem = new MenuItem("Generate");

        // 事件处理器代码
        generateMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                generateEquation();
            }
        });

        MenuItem saveMenuItem = new MenuItem("Save");

        saveMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                saveEquations();
                connectDatabase();
            }
        });

        MenuItem readMenuItem = new MenuItem("Read");

        readMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                flowPane.getChildren().clear(); // 清空当前GUI界面
                showAlert("习题已读取");
                displayAllEquationsFromDatabase();
            }
        });

        MenuItem checkMenuItem = new MenuItem("Check");

        checkMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 检查习题
                checkEquations();
            }
        });

        // View Accuracy按钮的点击事件监听器
        viewAccuracyButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 显示饼状图
                showAccuracyChart();
            }
        });

        MenuItem deleteMenuItem = new MenuItem("Delete by serial number");

        

        MenuItem deleteMenuItem1 = new MenuItem("Delete all");

        // Delete all按钮的点击事件监听器
        deleteMenuItem1.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 删除数据库中的所有算术式
                deleteAllEquations();

                // 清空界面上的所有算术式
                flowPane.getChildren().clear();

                showAlert("所有算术式删除成功!");
            }
        });

        Menu fileMenu = new Menu("File");
        Menu saveMenu = new Menu("SaveEquation");
        Menu readMenu = new Menu("ReadEquation");
        Menu checkMenu = new Menu("CheckEquation");
        Menu deleteMenu = new Menu("Delete");

        fileMenu.getItems().addAll(generateMenuItem);
        saveMenu.getItems().add(saveMenuItem);
        readMenu.getItems().add(readMenuItem);
        checkMenu.getItems().add(checkMenuItem);
        deleteMenu.getItems().addAll(deleteMenuItem,deleteMenuItem1);

        MenuBar menuBar = new MenuBar();
        menuBar.getMenus().addAll(fileMenu);
        menuBar.getMenus().add(saveMenu);
        menuBar.getMenus().add(readMenu);
        menuBar.getMenus().add(checkMenu);
        menuBar.getMenus().add(deleteMenu);

        flowPane.setHgap(50);
        flowPane.setVgap(30);
        flowPane.setPadding(new Insets(20));
        flowPane.setPrefSize(800, 560); // 设置 FlowPane 的大小

        BorderPane borderPane = new BorderPane();
        borderPane.setTop(menuBar);
        borderPane.setCenter(flowPane);

        //为了解决题目生成或多flowpane没有拖动条无法显示的问题
        // 将FlowPane放在一个ScrollPane中
        scrollPane.setContent(flowPane);// 设置滚动面板的内容为 flowPane,即将 flowPane 放入滚动面板中
        scrollPane.setFitToHeight(true);// 可以让滚动面板的高度自适应内容的高度
        borderPane.setCenter(scrollPane); // 将ScrollPane放置在中心位置

        HBox bottomBox = new HBox(10, viewAccuracyButton);
        HBox.setMargin(viewAccuracyButton, new Insets(50, 0, 20, 140));
        borderPane.setBottom(bottomBox);

        Scene scene = new Scene(borderPane, 800, 640);
        stage.setTitle("口算习题薄");
        stage.setScene(scene);
        stage.show();

        infoTextArea.setPrefSize(400, 110);
        //将TextArea控件其设置为只读
        infoTextArea.setEditable(false);

        HBox showbottomBox = new HBox(140, viewAccuracyButton, infoTextArea);
        HBox.setMargin(infoTextArea, new Insets(20, 0, 20, 0));
        borderPane.setBottom(showbottomBox);


    }


    public static void main(String[] args) {
        launch();
    }

    //为了使generate的事件处理器更美观特意拉出了这个类
    public EquationCollection generateEquation() {
        // 创建一个警示对话框
        TextInputDialog dialog = new TextInputDialog("5");
        dialog.setTitle("请输入算式数量");
        dialog.setHeaderText(null);
        dialog.setContentText("算式数量:");

        // 显示对话框,并获取用户输入的算式数量
        Optional<String> result = dialog.showAndWait();
        if (result.isPresent())
        {
            int n = Integer.parseInt(result.get());

            // 生成算式
            EquationCollection equationCollection = generateEquations(n);

            // 清空之前的内容
            flowPane.getChildren().clear();

            // 遍历算式集合并显示在GUI中
            for (IEquation equation : equationCollection)
            {
                maxID++; // id自增
                Label idLabel = new Label(String.valueOf(maxID)); // 获取当前最大ID,并将新的算式ID设为其加1
                Label equationLabel = new Label(equation.toString());
                TextField answerField = new TextField(); // 创建一个新的文本框
                HBox equationBox = new HBox(10, idLabel, new Label("、"), equationLabel, answerField); // 将算式ID标签、顿号、算式标签和文本框放入水平布局
                flowPane.getChildren().add(equationBox); // 将水平布局添加到 flowPane 中
            }

            // 连接数据库
            connectDatabase();
        }
        return null;
    }

    // 生成算式的方法
    public EquationCollection generateEquations(int n) {
        EquationCollection equationCollection = new EquationCollection();
        EquationCheckerOfRange equationChecker = new EquationCheckerOfRange(0, 100);
        equationCollection.generate(n, equationChecker);
        return equationCollection;
    }

    // 连接数据库的方法
    public void connectDatabase() {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            DatabaseMetaData dbMeta = conn.getMetaData();
            System.out.println("当前用户:" + dbMeta.getUserName());
            System.out.println("驱动版本:" + dbMeta.getDriverVersion());
            System.out.println("MySQL版本:" + dbMeta.getDatabaseProductVersion());

            stmt = conn.createStatement();

            // 查询最大ID值
            ResultSet rs = stmt.executeQuery("SELECT MAX(id) FROM equationtable");
            if (rs.next()) {
                maxID = rs.getInt(1);
            }

        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }

    private void saveEquations() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            for (Node node : flowPane.getChildren()) {
                if (node instanceof HBox) {
                    HBox equationBox = (HBox) node;
                    Label idLabel = (Label) equationBox.getChildren().get(0); // 获取算式ID标签
                    Label equationLabel = (Label) equationBox.getChildren().get(2);
                    TextField answerField = (TextField) equationBox.getChildren().get(3);

                    String equation = equationLabel.getText();
                    String answerText = answerField.getText();

                    // 检查答案字段是否为空
                    int answer = 0;
                    if (!answerText.isEmpty()) {
                        answer = Integer.parseInt(answerText);
                    }

                    // 计算正确结果
                    int result = calculateResult(equation);

                    // 保存到数据库
                    String sql = "INSERT INTO equationtable (id, Operand1, Operator, Operand2, Result) VALUES (?, ?, ?, ?, ?)";
                    pstmt = conn.prepareStatement(sql);
                    pstmt.setInt(1, Integer.parseInt(idLabel.getText())); // 将算式ID插入到数据库中
                    pstmt.setInt(2, getOperand1(equation));
                    pstmt.setString(3, getOperator(equation));
                    pstmt.setInt(4, getOperand2(equation));
                    pstmt.setInt(5, result);
                    pstmt.executeUpdate();
                }
            }

            System.out.println("算式保存成功!!!");
            showAlert("保存成功!");
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (pstmt != null)
                    pstmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }



    private int calculateResult(String equation) {
        String[] parts = equation.split(" ");
        int operand1 = Integer.parseInt(parts[0]);
        int operand2 = Integer.parseInt(parts[2]);
        String operator = parts[1];

        int result = 0;
        switch (operator) {
            case "+":
                result = operand1 + operand2;
                break;
            case "-":
                result = operand1 - operand2;
                break;
            case "*":          //此处预设乘法和除法便于以后相应的添加功能
                result = operand1 * operand2;
                break;
            case "/":
                result = operand1 / operand2;
                break;
        }

        return result;
    }

    private int getOperand1(String equation) {
        String[] parts = equation.split(" ");
        return Integer.parseInt(parts[0]);
    }

    private String getOperator(String equation) {
        String[] parts = equation.split(" ");
        return parts[1];
    }

    private int getOperand2(String equation) {
        String[] parts = equation.split(" ");
        return Integer.parseInt(parts[2]);
    }

    private void showAlert(String message) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("提示信息");
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }

    private void displayAllEquationsFromDatabase() {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            stmt = conn.createStatement();

            ResultSet rs = stmt.executeQuery("SELECT * FROM equationtable");
            if (!rs.next()) {
                showAlert("当前题库为空");
            } else {
                do {
                    int id = rs.getInt("id");
                    String equation = id + "、 " + rs.getInt("Operand1") + " " + rs.getString("Operator") + " " +
                            rs.getInt("Operand2") + " = " + rs.getInt("Result");
                    Label equationLabel = new Label(equation);
                    flowPane.getChildren().add(equationLabel);
                } while (rs.next());
            }

        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }

    private void checkEquations() {
        int totalEquations = 0; // 总题数
        int correctAnswers = 0; // 答对题数
        int incorrectAnswers = 0; // 答错题数

        for (Node node : flowPane.getChildren()) {
            if (node instanceof HBox) {
                HBox equationBox = (HBox) node;
                Label equationLabel = (Label) equationBox.getChildren().get(2);
                TextField answerField = (TextField) equationBox.getChildren().get(3);
                String equation = equationLabel.getText();
                String answerText = answerField.getText();
                // 检查答案字段是否为空
                if (!answerText.isEmpty()) {
                    totalEquations++;
                    int userAnswer = Integer.parseInt(answerText);
                    int result = calculateResult(equation);
                    if (userAnswer == result) { // 答案正确
                        equationBox.setStyle("-fx-background-color: #99ff99"); // 设置背景色为绿色
                        correctAnswers++;
                    } else { // 答案错误
                        equationBox.setStyle("-fx-background-color: #ff9999"); // 设置背景色为红色
                        incorrectAnswers++;
                    }
                }
            }
        }

        double correctPercentage = (double) correctAnswers / totalEquations * 100;
        double incorrectPercentage = (double) incorrectAnswers / totalEquations * 100;

        infoTextArea.setText("统计信息:\n" +
                "总题数:" + totalEquations + "\n" +
                "正确题数:" + correctAnswers + "\n" +
                "错误题数:" + incorrectAnswers + "\n" +
                "正确率:" + String.format("%.2f", correctPercentage) + "%\n" +
                "错误率:" + String.format("%.2f", incorrectPercentage) + "%");
    }

    private void showAccuracyChart() {
        int totalEquations = 0; // 总题数
        int correctAnswers = 0; // 答对题数
        for (Node node : flowPane.getChildren()) {
            if (node instanceof HBox) {
                HBox equationBox = (HBox) node;
                Label equationLabel = (Label) equationBox.getChildren().get(2);
                TextField answerField = (TextField) equationBox.getChildren().get(3);
                String equation = equationLabel.getText();
                String answerText = answerField.getText();
                // 检查答案字段是否为空
                if (!answerText.isEmpty()) {
                    totalEquations++;
                    int userAnswer = Integer.parseInt(answerText);
                    int result = calculateResult(equation);
                    if (userAnswer == result) { // 答案正确
                        correctAnswers++;
                    }
                }
            }
        }
        // 创建一个饼状图数据
        double correctPercentage = (double) correctAnswers / totalEquations * 100;
        double incorrectPercentage = 100 - correctPercentage;

        infoTextArea.setText("统计信息:\n" +
                "总题数:" + totalEquations + "\n" +
                "正确题数:" + correctAnswers + "\n" +
                "错误题数:" + (totalEquations - correctAnswers) + "\n" +
                "正确率:" + String.format("%.2f", correctPercentage) + "%\n" +
                "错误率:" + String.format("%.2f", incorrectPercentage) + "%");

        // 创建饼状图并显示
        PieChart chart = new PieChart();
        ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList(
                new PieChart.Data("Correct", correctAnswers),
                new PieChart.Data("Incorrect", totalEquations - correctAnswers)
        );
        chart.setData(pieChartData);
        chart.setTitle("Accuracy Chart");

        // 创建一个新的Stage来显示饼状图
        Stage chartStage = new Stage();
        chartStage.setScene(new Scene(chart, 600, 400));
        chartStage.show();
    }

   

    // 删除数据库中的所有算术式
    private void deleteAllEquations() {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            stmt = conn.createStatement();

            String sql = "DELETE FROM equationtable";
            stmt.executeUpdate(sql);
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }



}
修改代码,为Delete by serial number按钮创建事件处理器,点击Delete by serial number按钮后,调用读取方法,读取数据库中所有题目展示到界面中,然后弹出警示对话框,警示对话框内有两个textfield,让用户输入ID范围,输入后点击确定则从数据库删除输入ID范围的算数式,并使用警示对话框弹出删除成功;如果输入超出范围则用警示对话框提示超出范围,如果输入的范围首尾ID都存在,但是,中间缺失了部分序号,则跳过那些确实的需要,保证删除可以正常执行;如果输入的ID范围内,数据库有多条匹配,则把匹配上的全部删除。
给出需要添加和修改的部分即可。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-31 21:28:44 | 显示全部楼层
zqy173590939 发表于 2023-12-31 21:28
@FishC
package com.example.javafxmw;

import ga ...


首先,需要在deleteMenu中添加一个新的MenuItem,命名为deleteMenuItem2:

  1. MenuItem deleteMenuItem2 = new MenuItem("Delete by range");
复制代码


然后,在deleteMenuItem2的点击事件处理器中调用读取方法displayAllEquationsFromDatabase(),并弹出警示对话框让用户输入ID范围:

  1. deleteMenuItem2.setOnAction(new EventHandler<ActionEvent>() {
  2.     @Override
  3.     public void handle(ActionEvent event) {
  4.         // 读取数据库中所有题目展示到界面中
  5.         flowPane.getChildren().clear();
  6.         displayAllEquationsFromDatabase();
  7.         
  8.         // 创建一个警示对话框
  9.         Dialog<Pair<String, String>> dialog = new Dialog<>();
  10.         dialog.setTitle("删除算术式范围");
  11.         dialog.setHeaderText(null);

  12.         // 设置对话框的图标
  13.         Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
  14.         stage.getIcons().add(new Image("file:icon.png"));

  15.         // 设置对话框的按钮
  16.         ButtonType deleteButtonType = new ButtonType("删除", ButtonBar.ButtonData.OK_DONE);
  17.         dialog.getDialogPane().getButtonTypes().addAll(deleteButtonType, ButtonType.CANCEL);

  18.         // 创建并设置对话框的内容
  19.         GridPane grid = new GridPane();
  20.         grid.setHgap(10);
  21.         grid.setVgap(10);
  22.         grid.setPadding(new Insets(20, 150, 10, 10));

  23.         TextField startIDTextField = new TextField();
  24.         TextField endIDTextField = new TextField();

  25.         grid.add(new Label("起始ID:"), 0, 0);
  26.         grid.add(startIDTextField, 1, 0);
  27.         grid.add(new Label("结束ID:"), 2, 0);
  28.         grid.add(endIDTextField, 3, 0);

  29.         dialog.getDialogPane().setContent(grid);

  30.         // 点击删除按钮时的逻辑
  31.         dialog.setResultConverter(dialogButton -> {
  32.             if (dialogButton == deleteButtonType) {
  33.                 int startID = Integer.parseInt(startIDTextField.getText());
  34.                 int endID = Integer.parseInt(endIDTextField.getText());

  35.                 // 删除数据库中匹配的算术式
  36.                 deleteEquationsByRange(startID, endID);

  37.                 // 清空界面上的匹配的算术式
  38.                 for (Node node : flowPane.getChildren()) {
  39.                     if (node instanceof HBox) {
  40.                         HBox equationBox = (HBox) node;
  41.                         Label idLabel = (Label) equationBox.getChildren().get(0); // 获取算式ID标签

  42.                         int id = Integer.parseInt(idLabel.getText());
  43.                         if (id >= startID && id <= endID) {
  44.                             flowPane.getChildren().remove(equationBox);
  45.                         }
  46.                     }
  47.                 }
  48.                
  49.                 showAlert("算术式删除成功!");
  50.             }
  51.             return null;
  52.         });

  53.         dialog.showAndWait();
  54.     }
  55. });
复制代码


需要添加一个新的方法deleteEquationsByRange()来实现根据ID范围删除算术式的功能:

  1. private void deleteEquationsByRange(int startID, int endID) {
  2.     Connection conn = null;
  3.     PreparedStatement pstmt = null;
  4.     try {
  5.         Class.forName("com.mysql.cj.jdbc.Driver");
  6.         conn = DriverManager.getConnection(
  7.                 "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
  8.                 "root", "Zqy173590939");

  9.         String sql = "DELETE FROM equationtable WHERE id >= ? AND id <= ?";
  10.         pstmt = conn.prepareStatement(sql);
  11.         pstmt.setInt(1, startID);
  12.         pstmt.setInt(2, endID);
  13.         pstmt.executeUpdate();
  14.     } catch (SQLException se) {
  15.         se.printStackTrace();
  16.     } catch (Exception e) {
  17.         e.printStackTrace();
  18.     } finally {
  19.         try {
  20.             if (pstmt != null)
  21.                 pstmt.close();
  22.             if (conn != null)
  23.                 conn.close();
  24.         } catch (SQLException se) {
  25.             se.printStackTrace();
  26.         }
  27.     }
  28.     System.out.println("Goodbye!");
  29. }
复制代码


最后,记得在deleteMenu中添加deleteMenuItem2:

  1. deleteMenu.getItems().addAll(deleteMenuItem,deleteMenuItem1,deleteMenuItem2);
复制代码


这样就完成了根据ID范围删除算术式的功能。希望对你有帮助!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-31 22:00:29 | 显示全部楼层
@FishC
package com.example.javafxmw;

import gaijin3.*;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Pair;

import java.io.IOException;
import java.sql.*;
import java.util.Optional;

public class HelloApplication extends Application
{
    // 定义全局变量
    //定义一个TextArea控件作为全局变量
    TextArea infoTextArea = new TextArea();

    Button viewAccuracyButton = new Button("View Accuracy");

    FlowPane flowPane = new FlowPane();
    ScrollPane scrollPane = new ScrollPane();// 创建一个滚动面板对象
    private int maxID = 0;

    @Override
    public void start(Stage stage) throws IOException {
        MenuItem generateMenuItem = new MenuItem("Generate");

        // 事件处理器代码
        generateMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                generateEquation();
            }
        });

        MenuItem saveMenuItem = new MenuItem("Save");

        saveMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                saveEquations();
                connectDatabase();
            }
        });

        MenuItem readMenuItem = new MenuItem("Read");

        readMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                flowPane.getChildren().clear(); // 清空当前GUI界面
                showAlert("习题已读取");
                displayAllEquationsFromDatabase();
            }
        });

        MenuItem checkMenuItem = new MenuItem("Check");

        checkMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 检查习题
                checkEquations();
            }
        });

        // View Accuracy按钮的点击事件监听器
        viewAccuracyButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 显示饼状图
                showAccuracyChart();
            }
        });

        MenuItem deleteMenuItem = new MenuItem("Delete by serial number");

        // Delete by serial number按钮的点击事件监听器,部分删除算数式
        deleteMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                deleteEquations();
            }
        });

        MenuItem deleteMenuItem1 = new MenuItem("Delete all");

        // Delete all按钮的点击事件监听器,全部删除
        deleteMenuItem1.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 删除数据库中的所有算术式
                deleteAllEquations();

                // 清空界面上的所有算术式
                flowPane.getChildren().clear();

                showAlert("所有算术式删除成功!");
            }
        });

        MenuItem mistakesEquationsCollection = new MenuItem("Redo Mistakes Equations");

        Menu fileMenu = new Menu("File");
        Menu saveMenu = new Menu("SaveEquation");
        Menu readMenu = new Menu("ReadEquation");
        Menu checkMenu = new Menu("CheckEquation");
        Menu deleteMenu = new Menu("Delete");
        Menu mistakesEquationsCollectionMenu = new Menu("MistakesEquationsCollection");

        fileMenu.getItems().addAll(generateMenuItem);
        saveMenu.getItems().add(saveMenuItem);
        readMenu.getItems().add(readMenuItem);
        checkMenu.getItems().add(checkMenuItem);
        deleteMenu.getItems().addAll(deleteMenuItem,deleteMenuItem1);
        mistakesEquationsCollectionMenu.getItems().add(mistakesEquationsCollection);

        MenuBar menuBar = new MenuBar();
        menuBar.getMenus().addAll(fileMenu);
        menuBar.getMenus().add(saveMenu);
        menuBar.getMenus().add(readMenu);
        menuBar.getMenus().add(checkMenu);
        menuBar.getMenus().add(deleteMenu);
        menuBar.getMenus().add(mistakesEquationsCollectionMenu);

        flowPane.setHgap(50);
        flowPane.setVgap(30);
        flowPane.setPadding(new Insets(20));
        flowPane.setPrefSize(800, 560); // 设置 FlowPane 的大小

        BorderPane borderPane = new BorderPane();
        borderPane.setTop(menuBar);
        borderPane.setCenter(flowPane);

        //为了解决题目生成或多flowpane没有拖动条无法显示的问题
        // 将FlowPane放在一个ScrollPane中
        scrollPane.setContent(flowPane);// 设置滚动面板的内容为 flowPane,即将 flowPane 放入滚动面板中
        scrollPane.setFitToHeight(true);// 可以让滚动面板的高度自适应内容的高度
        borderPane.setCenter(scrollPane); // 将ScrollPane放置在中心位置

        HBox bottomBox = new HBox(10, viewAccuracyButton);
        HBox.setMargin(viewAccuracyButton, new Insets(50, 0, 20, 140));
        borderPane.setBottom(bottomBox);

        Scene scene = new Scene(borderPane, 800, 640);
        stage.setTitle("口算习题薄");
        stage.setScene(scene);
        stage.show();

        infoTextArea.setPrefSize(400, 110);
        //将TextArea控件其设置为只读
        infoTextArea.setEditable(false);

        HBox showbottomBox = new HBox(140, viewAccuracyButton, infoTextArea);
        HBox.setMargin(infoTextArea, new Insets(20, 0, 20, 0));
        borderPane.setBottom(showbottomBox);


    }


    public static void main(String[] args) {
        launch();
    }

    //为了使generate的事件处理器更美观特意拉出了这个类
    public EquationCollection generateEquation() {
        // 创建一个警示对话框
        TextInputDialog dialog = new TextInputDialog("5");
        dialog.setTitle("请输入算式数量");
        dialog.setHeaderText(null);
        dialog.setContentText("算式数量:");

        // 显示对话框,并获取用户输入的算式数量
        Optional<String> result = dialog.showAndWait();
        if (result.isPresent())
        {
            int n = Integer.parseInt(result.get());

            // 生成算式
            EquationCollection equationCollection = generateEquations(n);

            // 清空之前的内容
            flowPane.getChildren().clear();

            // 遍历算式集合并显示在GUI中
            for (IEquation equation : equationCollection)
            {
                maxID++; // id自增
                Label idLabel = new Label(String.valueOf(maxID)); // 获取当前最大ID,并将新的算式ID设为其加1
                Label equationLabel = new Label(equation.toString());
                TextField answerField = new TextField(); // 创建一个新的文本框
                HBox equationBox = new HBox(10, idLabel, new Label("、"), equationLabel, answerField); // 将算式ID标签、顿号、算式标签和文本框放入水平布局
                flowPane.getChildren().add(equationBox); // 将水平布局添加到 flowPane 中
            }

            // 连接数据库
            connectDatabase();
        }
        return null;
    }

    // 生成算式的方法
    public EquationCollection generateEquations(int n) {
        EquationCollection equationCollection = new EquationCollection();
        EquationCheckerOfRange equationChecker = new EquationCheckerOfRange(0, 100);
        equationCollection.generate(n, equationChecker);
        return equationCollection;
    }

    // 连接数据库的方法
    public void connectDatabase() {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            DatabaseMetaData dbMeta = conn.getMetaData();
            System.out.println("当前用户:" + dbMeta.getUserName());
            System.out.println("驱动版本:" + dbMeta.getDriverVersion());
            System.out.println("MySQL版本:" + dbMeta.getDatabaseProductVersion());

            stmt = conn.createStatement();

            // 查询最大ID值
            ResultSet rs = stmt.executeQuery("SELECT MAX(id) FROM equationtable");
            if (rs.next()) {
                maxID = rs.getInt(1);
            }

        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }

    private void saveEquations() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            for (Node node : flowPane.getChildren()) {
                if (node instanceof HBox) {
                    HBox equationBox = (HBox) node;
                    Label idLabel = (Label) equationBox.getChildren().get(0); // 获取算式ID标签
                    Label equationLabel = (Label) equationBox.getChildren().get(2);
                    TextField answerField = (TextField) equationBox.getChildren().get(3);

                    String equation = equationLabel.getText();
                    String answerText = answerField.getText();

                    // 检查答案字段是否为空
                    int answer = 0;
                    if (!answerText.isEmpty()) {
                        answer = Integer.parseInt(answerText);
                    }

                    // 计算正确结果
                    int result = calculateResult(equation);

                    // 保存到数据库
                    String sql = "INSERT INTO equationtable (id, Operand1, Operator, Operand2, Result) VALUES (?, ?, ?, ?, ?)";
                    pstmt = conn.prepareStatement(sql);
                    pstmt.setInt(1, Integer.parseInt(idLabel.getText())); // 将算式ID插入到数据库中
                    pstmt.setInt(2, getOperand1(equation));
                    pstmt.setString(3, getOperator(equation));
                    pstmt.setInt(4, getOperand2(equation));
                    pstmt.setInt(5, result);
                    pstmt.executeUpdate();
                }
            }

            System.out.println("算式保存成功!!!");
            showAlert("保存成功!");
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (pstmt != null)
                    pstmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }



    private int calculateResult(String equation) {
        String[] parts = equation.split(" ");
        int operand1 = Integer.parseInt(parts[0]);
        int operand2 = Integer.parseInt(parts[2]);
        String operator = parts[1];

        int result = 0;
        switch (operator) {
            case "+":
                result = operand1 + operand2;
                break;
            case "-":
                result = operand1 - operand2;
                break;
            case "*":          //此处预设乘法和除法便于以后相应的添加功能
                result = operand1 * operand2;
                break;
            case "/":
                result = operand1 / operand2;
                break;
        }

        return result;
    }

    private int getOperand1(String equation) {
        String[] parts = equation.split(" ");
        return Integer.parseInt(parts[0]);
    }

    private String getOperator(String equation) {
        String[] parts = equation.split(" ");
        return parts[1];
    }

    private int getOperand2(String equation) {
        String[] parts = equation.split(" ");
        return Integer.parseInt(parts[2]);
    }

    private void showAlert(String message) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("提示信息");
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }

    private void displayAllEquationsFromDatabase() {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            stmt = conn.createStatement();

            ResultSet rs = stmt.executeQuery("SELECT * FROM equationtable");
            if (!rs.next()) {
                showAlert("当前题库为空");
            } else {
                do {
                    int id = rs.getInt("id");
                    String equation = id + "、 " + rs.getInt("Operand1") + " " + rs.getString("Operator") + " " +
                            rs.getInt("Operand2") + " = " + rs.getInt("Result");
                    Label equationLabel = new Label(equation);
                    flowPane.getChildren().add(equationLabel);
                } while (rs.next());
            }

        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }

    private void checkEquations() {
        int totalEquations = 0; // 总题数
        int correctAnswers = 0; // 答对题数
        int incorrectAnswers = 0; // 答错题数

        for (Node node : flowPane.getChildren()) {
            if (node instanceof HBox) {
                HBox equationBox = (HBox) node;
                Label equationLabel = (Label) equationBox.getChildren().get(2);
                TextField answerField = (TextField) equationBox.getChildren().get(3);
                String equation = equationLabel.getText();
                String answerText = answerField.getText();
                // 检查答案字段是否为空
                if (!answerText.isEmpty()) {
                    totalEquations++;
                    int userAnswer = Integer.parseInt(answerText);
                    int result = calculateResult(equation);
                    if (userAnswer == result) { // 答案正确
                        equationBox.setStyle("-fx-background-color: #99ff99"); // 设置背景色为绿色
                        correctAnswers++;
                    } else { // 答案错误
                        equationBox.setStyle("-fx-background-color: #ff9999"); // 设置背景色为红色
                        incorrectAnswers++;
                    }
                }
            }
        }

        double correctPercentage = (double) correctAnswers / totalEquations * 100;
        double incorrectPercentage = (double) incorrectAnswers / totalEquations * 100;

        infoTextArea.setText("统计信息:\n" +
                "总题数:" + totalEquations + "\n" +
                "正确题数:" + correctAnswers + "\n" +
                "错误题数:" + incorrectAnswers + "\n" +
                "正确率:" + String.format("%.2f", correctPercentage) + "%\n" +
                "错误率:" + String.format("%.2f", incorrectPercentage) + "%");
    }

    private void showAccuracyChart() {
        int totalEquations = 0; // 总题数
        int correctAnswers = 0; // 答对题数
        for (Node node : flowPane.getChildren()) {
            if (node instanceof HBox) {
                HBox equationBox = (HBox) node;
                Label equationLabel = (Label) equationBox.getChildren().get(2);
                TextField answerField = (TextField) equationBox.getChildren().get(3);
                String equation = equationLabel.getText();
                String answerText = answerField.getText();
                // 检查答案字段是否为空
                if (!answerText.isEmpty()) {
                    totalEquations++;
                    int userAnswer = Integer.parseInt(answerText);
                    int result = calculateResult(equation);
                    if (userAnswer == result) { // 答案正确
                        correctAnswers++;
                    }
                }
            }
        }
        // 创建一个饼状图数据
        double correctPercentage = (double) correctAnswers / totalEquations * 100;
        double incorrectPercentage = 100 - correctPercentage;

        infoTextArea.setText("统计信息:\n" +
                "总题数:" + totalEquations + "\n" +
                "正确题数:" + correctAnswers + "\n" +
                "错误题数:" + (totalEquations - correctAnswers) + "\n" +
                "正确率:" + String.format("%.2f", correctPercentage) + "%\n" +
                "错误率:" + String.format("%.2f", incorrectPercentage) + "%");

        // 创建饼状图并显示
        PieChart chart = new PieChart();
        ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList(
                new PieChart.Data("Correct", correctAnswers),
                new PieChart.Data("Incorrect", totalEquations - correctAnswers)
        );
        chart.setData(pieChartData);
        chart.setTitle("Accuracy Chart");

        // 创建一个新的Stage来显示饼状图
        Stage chartStage = new Stage();
        chartStage.setScene(new Scene(chart, 600, 400));
        chartStage.show();
    }

    //为了使事件处理器的代码更简洁,刻意独立出了这个方法,没有具体意义
    private void deleteEquations() {
        // 读取数据库中所有题目展示到界面中
        flowPane.getChildren().clear();
        displayAllEquationsFromDatabase();

        // 创建一个警示对话框
        Dialog<Pair<String, String>> dialog = new Dialog<>();
        dialog.setTitle("删除算术式范围");
        dialog.setHeaderText(null);

        // 设置对话框的按钮
        ButtonType deleteButtonType = new ButtonType("删除", ButtonBar.ButtonData.OK_DONE);
        dialog.getDialogPane().getButtonTypes().addAll(deleteButtonType, ButtonType.CANCEL);

        // 创建并设置对话框的内容
        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(20, 150, 10, 10));

        TextField startIDTextField = new TextField();
        TextField endIDTextField = new TextField();

        grid.add(new Label("起始ID:"), 0, 0);
        grid.add(startIDTextField, 1, 0);
        grid.add(new Label("结束ID:"), 2, 0);
        grid.add(endIDTextField, 3, 0);

        dialog.getDialogPane().setContent(grid);

        // 点击删除按钮时的逻辑
        dialog.setResultConverter(dialogButton -> {
            if (dialogButton == deleteButtonType) {
                int startID = Integer.parseInt(startIDTextField.getText());
                int endID = Integer.parseInt(endIDTextField.getText());

                // 删除数据库中匹配的算术式
                deleteEquationsByRange(startID, endID);

                // 清空界面上的匹配的算术式
                for (Node node : flowPane.getChildren()) {
                    if (node instanceof HBox) {
                        HBox equationBox = (HBox) node;
                        Label idLabel = (Label) equationBox.getChildren().get(0); // 获取算式ID标签

                        int id = Integer.parseInt(idLabel.getText());
                        if (id >= startID && id <= endID) {
                            flowPane.getChildren().remove(equationBox);
                        }
                    }
                }

                showAlert("算术式删除成功!");
            }
            return null;
        });

        dialog.showAndWait();
    }

    private void deleteEquationsByRange(int startID, int endID) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            String sql = "DELETE FROM equationtable WHERE id >= ? AND id <= ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, startID);
            pstmt.setInt(2, endID);
            pstmt.executeUpdate();
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (pstmt != null)
                    pstmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }

    // 删除数据库中的所有算术式
    private void deleteAllEquations() {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/rjgzdatabase?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false",
                    "root", "Zqy173590939");

            stmt = conn.createStatement();

            String sql = "DELETE FROM equationtable";
            stmt.executeUpdate(sql);
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }



}
现在数据库中新增了一个错题集表mistakesequationtable,表的结构跟equationtable完全一样,现在需要增加错题集功能,已经创建了错题集菜单栏和重做错题按钮,现在为Redo Mistakes Equations添加事件处理器。
要求修改checkequation的逻辑,使其链接数据库,点击check后,被判定为错题的题目直接保存在错题集表mistakesequationtable中,并且获取mistakesequationtable表中ID最大值,如果表中为空则从1开始编号,如果错题集中有数据则从获取的最大值+1开始标号。获取ID最大值可以参考已存在的方法。
点击Redo Mistakes Equations后,弹出警示对话框,提示用户输入本次想要重做多少道错题,确认后则从错题集中随机抽取出相应的数目显示在界面中,要求这部分区别于读取习题,错误的题目用户可以重做,要有输入框,重做后也可检查对错和查看正确率。
给出需要添加或修改的部分。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 05:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表