FishC
发表于 2023-12-31 17:20:17
zqy173590939 发表于 2023-12-31 17:19
@FishC
帮我写数据库课程设计,数据库使用MySQL,题 ...
对于教师岗位管理系统的设计,我们可以采用Java语言和MySQL数据库来实现。下面是一个简单的示例代码,可以帮助你开始:
首先,我们需要创建一个名为"Teacher"的Java类,来表示教师的基本信息:
public class Teacher {
private String name;
private String idCard;
private String contact;
private String email;
private String job;
private String researchLab;
// 构造方法
public Teacher(String name, String idCard, String contact, String email, String job, String researchLab) {
this.name = name;
this.idCard = idCard;
this.contact = contact;
this.email = email;
this.job = job;
this.researchLab = researchLab;
}
// Getter和Setter方法
// ...
// toString方法
@Override
public String toString() {
return "姓名:" + name + "\n" +
"身份证号:" + idCard + "\n" +
"联系方式:" + contact + "\n" +
"邮箱:" + email + "\n" +
"工作时间:" + job + "\n" +
"岗位:" + job + "\n" +
"教研室信息:" + researchLab;
}
}
然后,我们可以创建一个名为"TeacherManager"的Java类,来实现教师岗位的管理功能:
import java.util.ArrayList;
import java.util.List;
public class TeacherManager {
private List<Teacher> teachers;
public TeacherManager() {
teachers = new ArrayList<>();
}
// 添加教师
public void addTeacher(Teacher teacher) {
teachers.add(teacher);
}
// 编辑教师信息
public void editTeacher(String idCard, Teacher newTeacher) {
for (int i = 0; i < teachers.size(); i++) {
if (teachers.get(i).getIdCard().equals(idCard)) {
teachers.set(i, newTeacher);
break;
}
}
}
// 删除教师
public void deleteTeacher(String idCard) {
for (int i = 0; i < teachers.size(); i++) {
if (teachers.get(i).getIdCard().equals(idCard)) {
teachers.remove(i);
break;
}
}
}
// 根据姓名查询教师
public List<Teacher> searchByName(String name) {
List<Teacher> result = new ArrayList<>();
for (Teacher teacher : teachers) {
if (teacher.getName().equals(name)) {
result.add(teacher);
}
}
return result;
}
// 根据身份证号查询教师
public Teacher searchByIdCard(String idCard) {
for (Teacher teacher : teachers) {
if (teacher.getIdCard().equals(idCard)) {
return teacher;
}
}
return null;
}
// 获取所有教师
public List<Teacher> getAllTeachers() {
return teachers;
}
}
接下来,我们可以创建一个简单的GUI界面来实现用户交互。你可以使用Swing或JavaFX等库来创建窗体、按钮等组件,并调用TeacherManager类的方法来进行教师岗位管理。由于篇幅有限,这里不提供完整的GUI代码,你可以根据需要自行实现。
最后,在MySQL数据库中创建一个名为"teachers"的表,包含与Teacher类对应的字段。你可以使用JDBC连接数据库,并编写相应的SQL语句来实现数据的持久化操作,例如插入、更新、删除和查询等。
希望以上代码能帮助到你开始设计教师岗位管理系统。由于题目要求较为复杂,还有很多细节需要进一步完善和实现。如果你遇到了具体的问题或需要更详细的帮助,请随时向我提问!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
zqy173590939
发表于 2023-12-31 17:22:56
FishC 发表于 2023-12-31 17:20
对于教师岗位管理系统的设计,我们可以采用Java语言和MySQL数据库来实现。下面是一个简单的示例代码, ...
根据以上部分你写出的代码,补全完整的GUI部分代码
FishC
发表于 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 小助理,如未能正确解答您的问题,请继续追问。
zqy173590939
发表于 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);
int operand2 = Integer.parseInt(parts);
String operator = parts;
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);
}
private String getOperator(String equation) {
String[] parts = equation.split(" ");
return parts;
}
private int getOperand2(String equation) {
String[] parts = equation.split(" ");
return Integer.parseInt(parts);
}
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按钮则直接删除数据库中所有算数式,并使用警示对话框展示删除成功。
FishC
发表于 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"按钮创建事件处理器。事件处理器会在用户点击按钮时执行相应的操作。
下面是实现这两个按钮事件处理器的代码:
// Delete by serial number按钮的点击事件监听器
deleteBySerialNumberButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
// 读取数据库中的所有题目并展示到界面上
flowPane.getChildren().clear();
displayAllEquationsFromDatabase();
// 创建一个对话框
Dialog<Pair<String, String>> dialog = new Dialog<>();
dialog.setTitle("删除算数式");
dialog.setHeaderText(null);
// 设置对话框的图标
Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
stage.getIcons().add(new Image("/path/to/your/icon.png"));
// 设置对话框的按钮
ButtonType deleteButtonType = new ButtonType("Delete", ButtonBar.ButtonData.OK_DONE);
dialog.getDialogPane().getButtonTypes().addAll(deleteButtonType, ButtonType.CANCEL);
// 创建输入字段
TextField startTextField = new TextField();
TextField endTextField = new TextField();
// 将输入字段添加到对话框的内容面板中
GridPane gridPane = new GridPane();
gridPane.setHgap(10);
gridPane.setVgap(10);
gridPane.addRow(0, new Label("起始ID: "), startTextField);
gridPane.addRow(1, new Label("结束ID: "), endTextField);
dialog.getDialogPane().setContent(gridPane);
// 设置按钮点击事件处理器
Node deleteButton = dialog.getDialogPane().lookupButton(deleteButtonType);
deleteButton.setDisable(true); // 默认禁用删除按钮
startTextField.textProperty().addListener((observable, oldValue, newValue) -> {
deleteButton.setDisable(newValue.trim().isEmpty()); // 当输入字段为空时禁用删除按钮
});
// 显示对话框并等待用户操作
Optional<Pair<String, String>> result = dialog.showAndWait();
// 处理用户点击确定按钮的情况
result.ifPresent(pair -> {
int startID = Integer.parseInt(pair.getKey());
int endID = Integer.parseInt(pair.getValue());
// 检查输入ID范围是否合法
if (startID >= 1 && endID >= startID && endID <= maxID) {
// 删除数据库中指定ID范围的算术式
deleteEquations(startID, endID);
// 清空界面上删除的算术式
for (Node node : flowPane.getChildren()) {
if (node instanceof HBox) {
HBox equationBox = (HBox) node;
Label idLabel = (Label) equationBox.getChildren().get(0);
int id = Integer.parseInt(idLabel.getText());
if (id >= startID && id <= endID) {
flowPane.getChildren().remove(node);
}
}
}
showAlert("算术式删除成功!");
} else {
showAlert("输入的ID范围不合法!");
}
});
}
});
// Delete all按钮的点击事件监听器
deleteAllButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
// 删除数据库中的所有算术式
deleteAllEquations();
// 清空界面上的所有算术式
flowPane.getChildren().clear();
showAlert("所有算术式删除成功!");
}
});
然后,我们需要实现`deleteEquations`方法和`deleteAllEquations`方法来删除数据库中的算术式。以下是实现这两个方法的代码:
// 删除数据库中指定ID范围的算术式
private void deleteEquations(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!");
}
最后,我们需要添加一个新的按钮`deleteBySerialNumberButton`和一个新的按钮`deleteAllButton`来代表"Delete by serial number"按钮和"Delete all"按钮。以下是相应的代码:
Button deleteBySerialNumberButton = new Button("Delete by serial number");
Button deleteAllButton = new Button("Delete all");
HBox deleteButtonBox = new HBox(10, deleteBySerialNumberButton, deleteAllButton);
deleteButtonBox.setPadding(new Insets(20));
borderPane.setBottom(deleteButtonBox);
将上述代码添加到`start`方法的最后一行,就可以在界面上添加"Delete by serial number"按钮和"Delete all"按钮,并为其添加事件处理器了。
希望以上解答对你有帮助!如果还有其他问题,请随时提问。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
zqy173590939
发表于 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)
出现了以下问题,请修正
FishC
发表于 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 小助理,如未能正确解答您的问题,请继续追问。
zqy173590939
发表于 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)
出现了以下问题,请修正
FishC
发表于 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 小助理,如未能正确解答您的问题,请继续追问。
zqy173590939
发表于 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)
修正此问题,请给出修改后的代码
FishC
发表于 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 小助理,如未能正确解答您的问题,请继续追问。
zqy173590939
发表于 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);
int operand2 = Integer.parseInt(parts);
String operator = parts;
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);
}
private String getOperator(String equation) {
String[] parts = equation.split(" ");
return parts;
}
private int getOperand2(String equation) {
String[] parts = equation.split(" ");
return Integer.parseInt(parts);
}
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范围的算数式,并使用警示对话框弹出删除成功;如果输入超出范围则用警示对话框提示超出范围。
FishC
发表于 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范围。最后,根据用户的输入,在数据库中删除相应的算术式,并显示删除成功的警示对话框。
下面是完整的代码实现:
// 定义 Delete by serial number 按钮的点击事件监听器
deleteMenuItem.setOnAction(new EventHandler() {
@Override
public void handle(ActionEvent event) {
// 显示数据库中的所有算术式
flowPane.getChildren().clear();
displayAllEquationsFromDatabase();
// 创建一个警示对话框并设置标题和头部文本
TextInputDialog dialog = new TextInputDialog();
dialog.setTitle("删除算术式");
dialog.setHeaderText("请输入要删除的算术式的ID范围(格式:start-end)");
// 获取用户输入的起始ID和结束ID
Optional<String> result = dialog.showAndWait();
if (result.isPresent()) {
String[] ids = result.get().split("-");
int startID = Integer.parseInt(ids);
int endID = Integer.parseInt(ids);
// 删除ID在范围内的算术式
deleteEquationsByRange(startID, endID);
}
}
});
// 删除数据库中范围内的算术式的方法
private void deleteEquationsByRange(int startID, int endID) {
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 WHERE id >= " + startID + " AND id <= " + endID);
if (rs.next()) {
// 逐个删除算术式
do {
int id = rs.getInt("id");
stmt.executeUpdate("DELETE FROM equationtable WHERE id = " + id);
} while (rs.next());
showAlert("算术式删除成功!");
} else {
showAlert("没有找到符合范围条件的算术式!");
}
} 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!");
}
请注意,上述代码仅实现了删除数据库中范围内的算术式的功能,对应的界面显示部分需要根据具体情况进行调整。另外,要确保数据库表名和字段名与代码中的一致,否则需要进行相应的修改。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
zqy173590939
发表于 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)
出现了以上问题,请改正,给出改正后代码
FishC
发表于 2023-12-31 21:17:05
zqy173590939 发表于 2023-12-31 21:16
java.sql.SQLException: Operation not allowed after ...
在 `deleteEquationsByRange` 方法中,您需要关闭 ResultSet 对象,以确保它不会在查询结束后继续保持打开状态。请尝试在执行完数据库查询后立
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
zqy173590939
发表于 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);
int operand2 = Integer.parseInt(parts);
String operator = parts;
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);
}
private String getOperator(String equation) {
String[] parts = equation.split(" ");
return parts;
}
private int getOperand2(String equation) {
String[] parts = equation.split(" ");
return Integer.parseInt(parts);
}
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范围内,数据库有多条匹配,则把匹配上的全部删除。
FishC
发表于 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 小助理,如未能正确解答您的问题,请继续追问。
zqy173590939
发表于 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);
int operand2 = Integer.parseInt(parts);
String operator = parts;
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);
}
private String getOperator(String equation) {
String[] parts = equation.split(" ");
return parts;
}
private int getOperand2(String equation) {
String[] parts = equation.split(" ");
return Integer.parseInt(parts);
}
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范围内,数据库有多条匹配,则把匹配上的全部删除。
给出需要添加和修改的部分即可。
FishC
发表于 2023-12-31 21:28:44
zqy173590939 发表于 2023-12-31 21:28
@FishC
package com.example.javafxmw;
import ga ...
首先,需要在deleteMenu中添加一个新的MenuItem,命名为deleteMenuItem2:
MenuItem deleteMenuItem2 = new MenuItem("Delete by range");
然后,在deleteMenuItem2的点击事件处理器中调用读取方法displayAllEquationsFromDatabase(),并弹出警示对话框让用户输入ID范围:
deleteMenuItem2.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
// 读取数据库中所有题目展示到界面中
flowPane.getChildren().clear();
displayAllEquationsFromDatabase();
// 创建一个警示对话框
Dialog<Pair<String, String>> dialog = new Dialog<>();
dialog.setTitle("删除算术式范围");
dialog.setHeaderText(null);
// 设置对话框的图标
Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
stage.getIcons().add(new Image("file:icon.png"));
// 设置对话框的按钮
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();
}
});
需要添加一个新的方法deleteEquationsByRange()来实现根据ID范围删除算术式的功能:
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!");
}
最后,记得在deleteMenu中添加deleteMenuItem2:
deleteMenu.getItems().addAll(deleteMenuItem,deleteMenuItem1,deleteMenuItem2);
这样就完成了根据ID范围删除算术式的功能。希望对你有帮助!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
zqy173590939
发表于 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);
int operand2 = Integer.parseInt(parts);
String operator = parts;
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);
}
private String getOperator(String equation) {
String[] parts = equation.split(" ");
return parts;
}
private int getOperand2(String equation) {
String[] parts = equation.split(" ");
return Integer.parseInt(parts);
}
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后,弹出警示对话框,提示用户输入本次想要重做多少道错题,确认后则从错题集中随机抽取出相应的数目显示在界面中,要求这部分区别于读取习题,错误的题目用户可以重做,要有输入框,重做后也可检查对错和查看正确率。
给出需要添加或修改的部分。