FishC 发表于 2023-12-31 15:14:17

zqy173590939 发表于 2023-12-31 15:14
想要限定textarea大小为500x150,应如何调整

要限定TextArea的大小为500x150,可以使用setPrefSize方法来设置其首选宽度和高度。在HelloApplication类中,将infoTextArea的设置改为以下代码:TextArea infoTextArea = new TextArea();infoTextArea.setEditable(false);infoTextArea.setPrefSize(500, 150);然后,在start方法中将infoTextArea添加到GUI界面的底部HBox布局中:HBox bottomBox = new HBox(10, viewAccuracyButton, infoTextArea);borderPane.setBottom(bottomBox);这样,infoTextArea的大小就被限定为了500x150。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

zqy173590939 发表于 2023-12-31 15:20:18

FishC 发表于 2023-12-31 15:14
要限定TextArea的大小为500x150,可以使用setPrefSize方法来设置其首选宽度和高度。在HelloApplication ...

继续修改使其距离页面底部间隔20像素

FishC 发表于 2023-12-31 15:20:29

zqy173590939 发表于 2023-12-31 15:20
继续修改使其距离页面底部间隔20像素

要将TextArea与页面底部间隔20像素,可以使用setMargin方法来设置其外边距。在HelloApplication类中,找到以下代码:HBox bottomBox = new HBox(10, viewAccuracyButton, infoTextArea);borderPane.setBottom(bottomBox);在这个代码块之前,添加以下代码:HBox.setMargin(infoTextArea, new Insets(0, 0, 20, 0));这样,就为infoTextArea设置了底部的外边距为20像素。完整代码如下:import javafx.application.Application;import javafx.geometry.Insets;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.control.TextArea;import javafx.scene.layout.BorderPane;import javafx.scene.layout.HBox;import javafx.stage.Stage;public class HelloApplication extends Application {    @Override    public void start(Stage primaryStage) {      Button viewAccuracyButton = new Button("View Accuracy");      TextArea infoTextArea = new TextArea();      infoTextArea.setEditable(false);      infoTextArea.setPrefSize(500, 150);      HBox.setMargin(infoTextArea, new Insets(0, 0, 20, 0));      HBox bottomBox = new HBox(10, viewAccuracyButton, infoTextArea);      BorderPane borderPane = new BorderPane();      borderPane.setBottom(bottomBox);      primaryStage.setScene(new Scene(borderPane, 800, 600));      primaryStage.show();    }    public static void main(String[] args) {      launch(args);    }}这样,TextArea就被限定在了500x150的大小,并且与页面底部有20像素的间隔。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

zqy173590939 发表于 2023-12-31 15:28:20

@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();
    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) {
                // 创建一个警示对话框
                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();
                }
            }
      });

      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);
      HBox bottomBox = new HBox(10, viewAccuracyButton);
      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(280, viewAccuracyButton, infoTextArea);
      HBox.setMargin(infoTextArea, new Insets(0, 0, 20, 0));
      borderPane.setBottom(showbottomBox);
      

    }


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

    // 生成算式的方法
    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();
    }

}
修改代码,把viewAccuracy按钮设置的离左边框20间距,离下边框20间距

FishC 发表于 2023-12-31 15:28:31

zqy173590939 发表于 2023-12-31 15:28
@FishC
package com.example.javafxmw;

import ga ...

只需要在对应的HBox中设置间距即可。将`showbottomBox`的代码改为如下:

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

这样就将`viewAccuracyButton`按钮离左边框20间距,离下边框20间距了。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

zqy173590939 发表于 2023-12-31 15:52:16

@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();
    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) {
                // 创建一个警示对话框
                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();
                }
            }
      });

      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);
      HBox bottomBox = new HBox(10, viewAccuracyButton);
      HBox.setMargin(viewAccuracyButton, new Insets(0, 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(0, 0, 20, 0));
      borderPane.setBottom(showbottomBox);


    }


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

    // 生成算式的方法
    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();
    }

}
我发现代码中的GUI界面上只设计flowpane等布局的话,如果在generate时用户输入了10000,在目前代码中给出的那个窗口大小是没办法完全显示的。帮我解决这个问题,如果题目生成的数目超过了GUI显示范围,增加一个拖动条,让用户可以正确的浏览到全部信息。

FishC 发表于 2023-12-31 15:52:31

zqy173590939 发表于 2023-12-31 15:52
@FishC
package com.example.javafxmw;

import ga ...

要解决这个问题,你可以将FlowPane放在一个ScrollPane中,这样当题目数量超过GUI界面的显示范围时,用户可以使用滚动条来查看所有的题目。下面是修改后的代码:

public class HelloApplication extends Application {
    // 其他代码...

    @Override
    public void start(Stage stage) throws IOException {
      // 其他代码...

      // 将FlowPane放在一个ScrollPane中
      ScrollPane scrollPane = new ScrollPane();
      scrollPane.setContent(flowPane);
      scrollPane.setFitToHeight(true);

      BorderPane borderPane = new BorderPane();
      borderPane.setTop(menuBar);
      borderPane.setCenter(scrollPane); // 将ScrollPane放置在中心位置

      // 其他代码...
    }

    // 其他代码...
}

这样,当题目数量超过GUI界面的显示范围时,用户就可以使用滚动条来查看所有的题目了。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

zqy173590939 发表于 2023-12-31 16:05:16

@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();
    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) {
                // 创建一个警示对话框
                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();
                }
            }
      });

      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 scrollPane = new ScrollPane();// 创建一个滚动面板对象
      scrollPane.setContent(flowPane);// 设置滚动面板的内容为 flowPane,即将 flowPane 放入滚动面板中
      scrollPane.setFitToHeight(true);// 可以让滚动面板的高度自适应内容的高度
      borderPane.setCenter(scrollPane); // 将ScrollPane放置在中心位置

      HBox bottomBox = new HBox(10, viewAccuracyButton);
      HBox.setMargin(viewAccuracyButton, new Insets(0, 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(0, 0, 20, 0));
      borderPane.setBottom(showbottomBox);


    }


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

    // 生成算式的方法
    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();
    }

}
为了解决生成题目太多无法显示的问题,我把flowpane添加到了scrollPane,帮我检查check按钮为什么不能正常使用了

FishC 发表于 2023-12-31 16:05:46

zqy173590939 发表于 2023-12-31 16:05
@FishC
package com.example.javafxmw;

import ga ...

你好,我看到你的代码中有一个问题:在checkMenuItem的事件处理程序中,你调用了checkEquations()方法,但是你并没有将该方法添加到MenuItem中。你需要将checkEquations()方法添加到checkMenuItem的事件处理程序中才能使check按钮正常工作。

这是修复后的代码:

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

请注意,你还需要删除重复的`viewAccuracyButton`和`infoTextArea`对象的声明和初始化代码,因为你已经在之前的代码中对它们进行了声明和初始化。

希望这可以帮助到你!如果你还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

zqy173590939 发表于 2023-12-31 16:07:30

FishC 发表于 2023-12-31 16:05
你好,我看到你的代码中有一个问题:在checkMenuItem的事件处理程序中,你调用了checkEquations()方法 ...

重复的`viewAccuracyButton`和`infoTextArea`对象的声明和初始化代码在哪里?

FishC 发表于 2023-12-31 16:07:45

zqy173590939 发表于 2023-12-31 16:07
重复的`viewAccuracyButton`和`infoTextArea`对象的声 ...

非常抱歉,我对代码进行了错误的理解。在你的代码中,确实没有重复声明和初始化`viewAccuracyButton`和`infoTextArea`对象的代码。感谢你的指正。

现在,我们需要更深入地查找check按钮无法正常工作的原因。请问当你点击check按钮时是否发生了任何错误或异常?如果有的话,请提供相应的错误信息。另外,你可以尝试添加一些调试输出语句来检查checkEquations()方法是否被正确调用,并且在方法内部的循环中是否能正确遍历flowPane中的节点。这样我们可以更好地排除问题所在。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

zqy173590939 发表于 2023-12-31 16:14:05


@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) {
                // 创建一个警示对话框
                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();
                }
            }
      });

      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(0, 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(0, 0, 20, 0));
      borderPane.setBottom(showbottomBox);


    }


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

    // 生成算式的方法
    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();
    }

}
为了解决生成题目太多无法显示的问题,我把flowpane添加到了scrollPane,检查checkequations方法,为什么点击check按钮后功能不能正常使用了

FishC 发表于 2023-12-31 16:14:24

zqy173590939 发表于 2023-12-31 16:14
@FishC
package com.example.javafxmw;

import ga ...

根据您提供的代码,我注意到在`checkEquations()`方法中,当用户点击"Check"按钮时,程序会遍历`flowPane`中的每个节点,判断用户输入的答案是否正确,并根据结果修改算式框的背景颜色。但是,我发现在这个方法中有一个问题:在遍历`flowPane`的过程中,会对所有的`HBox`进行判断,包括包含算式标签和答案文本框的`HBox`以及只包含算式标签的`HBox`,导致在计算结果时出错。

为了解决这个问题,我建议您在遍历`flowPane`的过程中,只对包含算式标签和答案文本框的`HBox`进行判断。您可以根据答案文本框是否为空来判断用户是否已经回答了该题目。

下面是修改后的`checkEquations()`方法代码:

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) + "%");
}

请尝试使用以上修改后的代码,看是否能够解决问题。希望对您有帮助!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

zqy173590939 发表于 2023-12-31 16:57:13

FishC 发表于 2023-12-31 16:14
根据您提供的代码,我注意到在`checkEquations()`方法中,当用户点击"Check"按钮时,程序会遍历`flowPa ...

原来的代码这样写会造成什么影响或后果吗?

FishC 发表于 2023-12-31 16:57:36

zqy173590939 发表于 2023-12-31 16:57
原来的代码这样写会造成什么影响或后果吗?

原来的代码在遍历`flowPane`的过程中,会对所有的`HBox`进行判断,包括包含算式标签和答案文本框的`HBox`以及只包含算式标签的`HBox`。这将导致在计算结果时出现以下问题:

1. 当用户没有回答某个题目时,程序仍然会判断该题目的答案是否正确,从而造成错误的统计。
2. 当算式框只包含算式标签时,获取答案文本框的索引将超出范围,导致程序抛出异常。

由于上述问题,可能会影响程序正常运行并显示准确的统计信息和背景颜色变化。

通过修改后的代码,只对包含算式标签和答案文本框的`HBox`进行判断,可以解决这些问题,并确保统计信息和背景颜色的准确性。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

zqy173590939 发表于 2023-12-31 16:59:05

实际上并没有出现这样的问题,你为什么会给出这样的建议呢?

zqy173590939 发表于 2023-12-31 17:02:11

FishC 发表于 2023-12-31 16:57
原来的代码在遍历`flowPane`的过程中,会对所有的`HBox`进行判断,包括包含算式标签和答案文本框的`HBo ...

实际上并没有出现这样的问题,你为什么会给出这样的建议呢?

FishC 发表于 2023-12-31 17:03:13

zqy173590939 发表于 2023-12-31 17:02
实际上并没有出现这样的问题,你为什么会给出这样的建 ...

非常抱歉给您带来困惑。如果您的代码没有出现问题,那么我之前的建议是不必要的。有时候我们会为了预防可能发生的问题而提出修改建议,但这并不意味着一定会出现问题。在给出建议时,我会尽量考虑到潜在的风险和常见的错误情况,但也需要根据具体情况做出判断。如果您的代码已经运行正常,并且没有产生任何错误或副作用,那么您可以继续使用原来的代码,不需要进行任何改动。感谢您的指正,如果您有任何其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

FishC 发表于 2023-12-31 17:03:22

zqy173590939 发表于 2023-12-31 16:59
实际上并没有出现这样的问题,你为什么会给出这样的建 ...

非常抱歉给出了错误的建议。根据你的代码,我没有看到在`checkEquations()`方法中有任何问题。请忽略我之前的回答。

如果你的程序在点击"Check"按钮后无法正常使用,我建议你检查以下几个可能的问题:

1. 确保在点击"Check"按钮时,界面上的所有算式都已经生成并填写了答案。如果有任何一个算式没有填写答案,可能会导致程序出错。

2. 检查`calculateResult(String equation)`方法是否正确计算了算式的结果。

3. 确保`checkEquations()`方法正确地判断了用户的答案是否正确,并更新了相应的GUI显示。

如果问题仍然存在,请提供更多关于问题的细节或报错信息,这样我可以更好地帮助你解决问题。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

zqy173590939 发表于 2023-12-31 17:19:59

@FishC
帮我写数据库课程设计,数据库使用MySQL,题目为教师岗位管理系统。
以下是教师岗位管理系统需求文档和总体设计结合的文档,帮我设计Java程序并给出代码

1. 介绍
教师岗位管理系统是一个用于管理学校教师岗位和相关信息的数据库系统。该系统旨在提供一个简单、高效的方式来管理教师的各类岗位,并能够方便地查看和处理相关信息。

2. 功能需求

2.0 登录注册功能
要求系统拥有良好的注册和登录功能,使用账号密码即可登录,设置登录检查,检查账号密码功能可以适用正则表达式,因为本系统为离线系统,不需要设计验证码也可登录,尽可能减少用户不必要的麻烦。
不同的用户登录后权限不同注意区分。如果为了方便,或者减少代码耦合度考虑,可以把管理员登录单独写为一个JAVA类。运行类分为用户端和管理员端两个,最后封装为不同的EXE即可(封装为EXE文件不要求)。

2.1 岗位管理
   - 系统设置管理员管理员设置两级管理员,一级为总管理员,可以管理所有信息;二级管理员为学院管理员,只可管理部分信息,但可以查询全部信息。管理员可以添加、编辑,查询和删除各类教师岗位,如教授、副教授、讲师等。
   - 系统可以在数据库中正确地记录每个岗位的基本信息,包括姓名,身份证号、联系方式,邮箱、工作时间,岗位,教研室信息等。
   - 系统可以设置每个岗位的权限和职责,以限制其对系统功能的访问和操作。系统指派学院管理员(二级管理员权限要区别于总管理员),该指派权限只有总管理员可以操作。
   支持信息公开化,不同学院的管理员和老师,虽然无权修改其他学院数据,但可以查询全校的数据。


2.2 岗位分配(增)
   - 系统管理员可以根据学校的需求,为不同学院直接添加教师岗位,为不同的教师分配其应当承担的课程或分配教研室。
   - 系统可以正确记录每个课程或教研室的岗位分配情况,包括岗位名称、人员姓名等。
   - 系统可以支持自动调度功能,根据预设规则和岗位人员的可用时间进行值班分配。(此处保留优化空间,如果有老师请假,支持临时调度替补老师)

2.3 授课管理(查)
   - 系统可以记录教师的授课计划、值班情况等,并提供相应的统计报表,让所有用户都可以看到。
   - 系统可以提供实时通知功能,将授课计划分配、值班安排情况通知给相关人员,发到对应人员的邮箱中(实现时可以尝试从数据库遍历出需要今日之后,或者指定期间的需要值班的老师的姓名和邮箱,然后在界面输出这些信息,并输出已发送邮件,并不需要真的发送)。

2.4 信息查询与统计(查,改,删)
   - 管理员可以进行系统查询(查询功能)和统计各类岗位、课程或教研室的相关信息(可以单独查询这些信息,支持分学院查询,支持部分输出)。
- 系统可以根据条件进行排序,排序描述:教师注册登记时,要随机赋予其一个唯一教职工编号,编号格式zc410100()*****,括号内设置不同的学院码,*使用随机数生成数字即可,数据库中要求不可重复。同学院的老师存入一个表内按照后五位排序。不同学院的老师存入一个总表内,按照数字部分整体大小排序即可。
   - 系统可以提供多种查询方式,如按照日期、岗位、课程或教研室等进行查询。(可以全部查询,可以通过某些字段查询到个人或单个信息,比如输入姓名精确查找,输入员工编号盲找等。)


3. 非功能需求
3.1 安全性
   - 系统要求具有一定的安全性能,包括对用户身份的认证和权限控制。
   - 系统要求能够对数据进行访问权限加密,防止未经授权的访问和篡改。

3.2 可用性
   - 系统要求能够稳定运行,保证用户随时可以访问和使用。
   - 系统要求具有良好的用户界面设计,方便用户操作和理解。

3.3 扩展性
   - 系统要求能够方便地扩展和添加新的功能模块,以满足后续的需求变化。

4. 技术需求
   - 数据库管理系统:选择适合的数据库管理系统,如MySQL或Oracle等。
   - 编程语言:选择适合的编程语言和框架进行系统开发。
   以上所有内容是的编码,尝试展示在GUI中。
页: 1 2 [3] 4 5
查看完整版本: Java实验完成