Javaはコンピュータベースの試験プログラムインターフェースを実装します

コンピューターベースのテストのインターフェイスは次のとおりです (単一選択問題)。上部は質問ステータス、下部は質問、1/5/1 は完了した質問数、合計質問数、および正解数。

多肢選択式の質問インターフェイスをもう一度見てみましょう。

判断に関する質問のためのインターフェイス。

正解した場合のフィードバックにはかかった時間も含まれます。

不正解時のフィードバックには、正解とかかった時間が表示されます。

総合スコアは回答の最後に表示されます。

 Question.java 質問バンク

import java.util.ArrayList;
import java.util.List;

class SingleChoice {
    public String question, optionA, optionB, optionC, optionD, correctAnswer;

    public SingleChoice(String question, String optionA, String optionB, String optionC, String optionD, String correctAnswer) {
        this.question = question;
        this.optionA = optionA;
        this.optionB = optionB;
        this.optionC = optionC;
        this.optionD = optionD;
        this.correctAnswer = correctAnswer;
    }
}

class MultipleChoice {
    public String question, optionA, optionB, optionC, optionD, correctAnswer;

    public MultipleChoice(String question, String optionA, String optionB, String optionC, String optionD, String correctAnswer) {
        this.question = question;
        this.optionA = optionA;
        this.optionB = optionB;
        this.optionC = optionC;
        this.optionD = optionD;
        this.correctAnswer = correctAnswer;
    }
}

class TrueOrFalse {
    public String question;
    public boolean correctAnswer;

    public TrueOrFalse(String question, boolean correctAnswer) {
        this.question = question;
        this.correctAnswer = correctAnswer;
    }
}

public class Questions {

    public List<SingleChoice> singleChoices = new ArrayList<>();
    public List<MultipleChoice> multipleChoices = new ArrayList<>();
    public List<TrueOrFalse> trueOrFalse = new ArrayList<>();

    public Questions() {
        // 添加单选题
        singleChoices.add(new SingleChoice("Java中,下列哪个关键字用于声明一个类?", "A. int", "B. float", "C. class", "D. void", "C"));
        singleChoices.add(new SingleChoice("什么是面向对象编程的基本特征之一?", "A. 继承", "B. 多态", "C. 封装", "D. 以上皆是", "D"));
        singleChoices.add(new SingleChoice("在Java中,如何通过继承实现类之间的关系?", "A. extends关键字", "B. implements关键字", "C. super关键字", "D. this关键字", "A"));
        singleChoices.add(new SingleChoice("以下哪个关键字用于在Java中创建接口?", "A. interface", "B. class", "C. abstract", "D. extends", "A"));
        singleChoices.add(new SingleChoice("在Java中,下列哪个关键字用于控制程序的执行流程?", "A. if", "B. else", "C. switch", "D. for", "C"));
        singleChoices.add(new SingleChoice("在Java中,下列哪个关键字用于声明一个常量?", "A. const", "B. final", "C. static", "D. var", "B"));
        singleChoices.add(new SingleChoice("以下哪个不是Java的基本数据类型?", "A. int", "B. boolean", "C. double", "D. string", "D"));
        singleChoices.add(new SingleChoice("在Java中,哪个关键字用于创建一个新的对象?", "A. new", "B. create", "C. make", "D. build", "A"));
        singleChoices.add(new SingleChoice("以下哪个选项可以用于创建多线程?", "A. 哈希", "B. Thread类", "C. Main方法", "D. ArrayList类", "B"));
        singleChoices.add(new SingleChoice("以下哪个关键字可以用于定义抽象类?", "A. abstract", "B. interface", "C. static", "D. final", "A"));
        // 添加多选题
        multipleChoices.add(new MultipleChoice("下列哪些选项是Java的基本数据类型?", "A. boolean", "B. string", "C. integer", "D. double", "AD"));
        multipleChoices.add(new MultipleChoice("下列哪些选项是Java中的流控制语句?", "A. if-else", "B. for", "C. while", "D. function", "ABC"));
        multipleChoices.add(new MultipleChoice("下列哪些选项是Java中的包装类?", "A. Integer", "B. Float", "C. Long", "D. Char", "ABC"));
        multipleChoices.add(new MultipleChoice("下列哪些选项是Java中的集合类?", "A. ArrayList", "B. LinkedList", "C. HashSet", "D. Map", "ABCD"));
        multipleChoices.add(new MultipleChoice("下列哪些选项是Java中的线程状态?", "A. NEW", "B. RUNNING", "C. WAITING", "D. DEAD", "ABCD"));
        multipleChoices.add(new MultipleChoice("下列哪些选项是Java中的线程同步方法?", "A. wait()", "B. notify()", "C. synchronized()", "D. interrupt()", "ABC"));
        multipleChoices.add(new MultipleChoice("下列哪些选项是Java中的异常类型?", "A. Checked Exception", "B. Unchecked Exception", "C. Error", "D. Throwable", "ABCD"));
        multipleChoices.add(new MultipleChoice("下列哪些选项是Java中的注解类型?", "A. @Override", "B. @Deprecated", "C. @SuppressWarnings", "D. @Inject", "ABCD"));
        multipleChoices.add(new MultipleChoice("下列哪些选项是Java中的IO流类型?", "A. FileInputStream", "B. InputStreamReader", "C. OutputStream", "D. Socket", "ABCD"));
        multipleChoices.add(new MultipleChoice("下列哪些选项是Java中的网络通信协议?", "A. TCP", "B. UDP", "C. FTP", "D. HTTP", "ABCD"));
        //添加判断题
        trueOrFalse.add(new TrueOrFalse("Java是一种面向对象的编程语言", true));
        trueOrFalse.add(new TrueOrFalse("Java中的final关键字用于标识一个类不可被继承", true));
        trueOrFalse.add(new TrueOrFalse("Java中的String是基本数据类型", false));
        trueOrFalse.add(new TrueOrFalse("Java中的数组长度可以动态改变", false));
        trueOrFalse.add(new TrueOrFalse("Java中的interface可以实现多重继承", true));
        trueOrFalse.add(new TrueOrFalse("Java中的double类型比float类型精度更高", true));
        trueOrFalse.add(new TrueOrFalse("Java中的HashMap是线程安全的", false));
        trueOrFalse.add(new TrueOrFalse("Java中的try块必须和catch或finally块配合使用", true));
        trueOrFalse.add(new TrueOrFalse("Java中的抽象类可以有构造方法", true));
        trueOrFalse.add(new TrueOrFalse("Java中的静态方法可以被子类重写", false));
    }
}

JavaExam.java メイン インターフェイス

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.util.Collections;
import java.util.List;

public class JavaExam extends JFrame {
    private final JLabel labelQuestion;
    private final JRadioButton radioButtonA, radioButtonB, radioButtonC, radioButtonD;
    private final JCheckBox checkBoxA, checkBoxB, checkBoxC, checkBoxD;
    private final ButtonGroup buttonGroup;
    private final JButton buttonSubmit;
    private final JLabel labelSingleChoiceNum, labelMultipleChoiceNum, labelTrueOrFalseNum, labelScore, labelTime;
    private int singleChoiceCount = 0, multipleChoiceCount = 0, trueOrFalseCount = 0;
    private int singleChoiceCorrectCount = 0, multipleChoiceCorrectCount = 0, trueOrFalseCorrectCount = 0;
    private int score = 0, seconds = 0, questionIndex = 0;
    private boolean isSingleChoice, isMultipleChoice, isTrueOrFalse, submit = false;
    private final List<SingleChoice> singleChoices;
    private final List<MultipleChoice> multipleChoices;
    private final List<TrueOrFalse> trueOrFalse;
    private final Timer timer;
    private final JPanel panelQuestion = new JPanel();

    class GiveQuestion implements Runnable {

        @Override
        public void run() {
            Collections.shuffle(singleChoices);
            Collections.shuffle(multipleChoices);
            Collections.shuffle(trueOrFalse);
            while (questionIndex < 15) {
                submit = false;
                if (questionIndex % 3 == 0) {
                    isSingleChoice = true;
                    showSingleChoiceQuestion(singleChoices.get(singleChoiceCount));
                    singleChoiceCount++;
                } else if (questionIndex % 3 == 1) {
                    isMultipleChoice = true;
                    showMultipleChoiceQuestion(multipleChoices.get(multipleChoiceCount));
                    multipleChoiceCount++;
                } else {
                    isTrueOrFalse = true;
                    showTrueOrFalseQuestion(trueOrFalse.get(trueOrFalseCount));
                    trueOrFalseCount++;
                }
                timer.start();
                while (!submit) {
                }
                questionIndex++;
            }
            endExam();
        }
    }

    public JavaExam() {
        super("Java机考 By YeMaolin");
        singleChoices = new Questions().singleChoices;
        multipleChoices = new Questions().multipleChoices;
        trueOrFalse = new Questions().trueOrFalse;
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 250);
        setLocationRelativeTo(null);
        setLayout(new BorderLayout());
        panelQuestion.setLayout(new GridLayout(5,1));
        panelQuestion.setBorder(new EmptyBorder(0,15,0,0)); // 设置组件的外边距
        labelQuestion = new JLabel("", SwingConstants.CENTER);
        radioButtonA = new JRadioButton("A");
        radioButtonB = new JRadioButton("B");
        radioButtonC = new JRadioButton("C");
        radioButtonD = new JRadioButton("D");
        checkBoxA = new JCheckBox("A");
        checkBoxB = new JCheckBox("B");
        checkBoxC = new JCheckBox("C");
        checkBoxD = new JCheckBox("D");
        buttonGroup = new ButtonGroup();
        buttonGroup.add(radioButtonA);
        buttonGroup.add(radioButtonB);
        buttonGroup.add(radioButtonC);
        buttonGroup.add(radioButtonD);
        JPanel panelInfo = new JPanel();
        labelSingleChoiceNum = new JLabel("单选题:0/5/0", SwingConstants.CENTER);
        labelMultipleChoiceNum = new JLabel("多选题:0/5/0", SwingConstants.CENTER);
        labelTrueOrFalseNum = new JLabel("判断题:0/5/0", SwingConstants.CENTER);
        labelScore = new JLabel("成绩:0分", SwingConstants.CENTER);
        labelTime = new JLabel("用时:0秒", SwingConstants.CENTER);
        panelInfo.add(labelSingleChoiceNum);
        panelInfo.add(labelMultipleChoiceNum);
        panelInfo.add(labelTrueOrFalseNum);
        panelInfo.add(labelScore);
        panelInfo.add(labelTime);
        add(panelInfo,BorderLayout.NORTH);
        add(panelQuestion,BorderLayout.WEST);
        setVisible(true);
        buttonSubmit = new JButton("提交");
        add(buttonSubmit,BorderLayout.SOUTH);
        buttonSubmit.addActionListener(e -> submitAnswer());
        timer = new Timer(1000, e -> {
            seconds++;
            labelTime.setText("用时:" + seconds + "秒");
            if (seconds >= 20) {
                submitAnswer();
            }
        });
        Thread giveQuestion = new Thread(new GiveQuestion());
        giveQuestion.start();
    }

    private void endExam() {
        timer.stop();
        JOptionPane.showMessageDialog(this, "考试结束,您的成绩是" + score + "分!");
        System.exit(0);
    }

    private void showSingleChoiceQuestion(SingleChoice singleChoice) {
        panelQuestion.removeAll();
        labelQuestion.setText(questionIndex + 1 + "/15[单选题]" + singleChoice.question);
        radioButtonA.setText(singleChoice.optionA);
        radioButtonB.setText(singleChoice.optionB);
        radioButtonC.setText(singleChoice.optionC);
        radioButtonD.setText(singleChoice.optionD);
        panelQuestion.add(labelQuestion);
        panelQuestion.add(radioButtonA);
        panelQuestion.add(radioButtonB);
        panelQuestion.add(radioButtonC);
        panelQuestion.add(radioButtonD);
    }

    private void showMultipleChoiceQuestion(MultipleChoice multipleChoice) {
        panelQuestion.removeAll();
        labelQuestion.setText(questionIndex + 1 + "/15[多选题]" + multipleChoice.question);
        checkBoxA.setText(multipleChoice.optionA);
        checkBoxB.setText(multipleChoice.optionB);
        checkBoxC.setText(multipleChoice.optionC);
        checkBoxD.setText(multipleChoice.optionD);
        panelQuestion.add(labelQuestion);
        panelQuestion.add(checkBoxA);
        panelQuestion.add(checkBoxB);
        panelQuestion.add(checkBoxC);
        panelQuestion.add(checkBoxD);
    }

    private void showTrueOrFalseQuestion(TrueOrFalse trueOrFalse) {
        panelQuestion.removeAll();
        labelQuestion.setText(questionIndex + 1 + "/15[判断题]" + trueOrFalse.question);
        radioButtonA.setText("正确");
        radioButtonB.setText("错误");
        panelQuestion.add(labelQuestion);
        panelQuestion.add(radioButtonA);
        panelQuestion.add(radioButtonB);
    }

    private void submitAnswer() {
        timer.stop();
        String correctAnswer = "";
        boolean right = false;
        if (isSingleChoice) {
            String userAnswer = "";
            correctAnswer = singleChoices.get(singleChoiceCount - 1).correctAnswer;
            if (radioButtonA.isSelected()) {
                userAnswer = "A";
            } else if (radioButtonB.isSelected()) {
                userAnswer = "B";
            } else if (radioButtonC.isSelected()) {
                userAnswer = "C";
            } else if(radioButtonD.isSelected()) {
                userAnswer = "D";
            }
            if (userAnswer.equals(correctAnswer)) {
                singleChoiceCorrectCount++;
                score++;
                right = true;
            }
        }else if (isMultipleChoice) {
            correctAnswer = multipleChoices.get(multipleChoiceCount - 1).correctAnswer;
            String userAnswer = "";
            if (checkBoxA.isSelected()) {
                userAnswer += "A";
            }
            if (checkBoxB.isSelected()) {
                userAnswer += "B";
            }
            if (checkBoxC.isSelected()) {
                userAnswer += "C";
            }
            if (checkBoxD.isSelected()) {
                userAnswer += "D";
            }
            if (correctAnswer.equalsIgnoreCase(userAnswer)) {
                multipleChoiceCorrectCount++;
                score += 2;
                right = true;
            }
        }else if (isTrueOrFalse) {
            boolean correct = trueOrFalse.get(trueOrFalseCount - 1).correctAnswer;
            correctAnswer = String.valueOf(correct);
            if (radioButtonA.isSelected()&&correct||radioButtonB.isSelected()&&!correct) {
                trueOrFalseCorrectCount++;
                score++;
                right = true;
            }
        }
        if (right)
            JOptionPane.showMessageDialog(this, "回答正确,用时" + seconds + "秒");
        else JOptionPane.showMessageDialog(this, "回答错误,正确答案是 " + correctAnswer + "\n用时" + seconds + "秒");
        update();
        submit = true;
    }

    private void update() {
        labelScore.setText("成绩:" + score + "分");
        labelSingleChoiceNum.setText("单选题:" + singleChoiceCount + "/5/" + singleChoiceCorrectCount);
        labelMultipleChoiceNum.setText("多选题:" + multipleChoiceCount + "/5/" + multipleChoiceCorrectCount);
        labelTrueOrFalseNum.setText("判断题:" + trueOrFalseCount + "/5/" + trueOrFalseCorrectCount);
        buttonGroup.clearSelection();
        checkBoxA.setSelected(false);
        checkBoxB.setSelected(false);
        checkBoxC.setSelected(false);
        checkBoxD.setSelected(false);
        radioButtonA.setSelected(false);
        radioButtonB.setSelected(false);
        radioButtonC.setSelected(false);
        radioButtonD.setSelected(false);
        seconds = 0;
        isSingleChoice = isMultipleChoice = isTrueOrFalse = false;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(JavaExam::new);
    }
}

まず最も重要な機能は質問の表示ですが、まず3つの質問タイプの構造を設計し、次に質問バンクを構築しました。 1 つ目は単一選択問題です。単一選択問題のクラスを定義します。問題の内容、4 つの選択肢、正解はすべて文字列で表現され、パラメーターを持つコンストラクターが設定されます。

同様に、多肢選択の質問クラスを定義します。多肢選択の質問と単一選択の質問の唯一の違いは、多肢選択の質問には複数の正解があることですが、どちらも文字列を通じて正解を表すことができることです。したがって、これら 2 つのクラスの実装はまったく同じです。

判定質問の場合、質問の内容を記録する文字列と正しい判定結果を記録するブール変数のみが必要です。

次に、質問バンクの準備を開始し、質問バンク クラスを定義し、3 つの質問タイプのコンテナを確立しました。

次に、コンストラクターに質問を追加します。

10 個の多肢選択式の質問を追加します。

10 個の多肢選択問題を追加しました。

正誤質問を 10 個追加します。

次のステップは、GUI インターフェイスに質問を表示し、他の機能ロジックを実装する方法です。

Java Exam がウィンドウになるように、JFrame から継承したクラス Java Exam を定義します。メイン関数の SwingUtilities クラスの invokeLater メソッドを使用して、イベント スケジューリング スレッドで Java Exam のコンストラクターを実行します。

Java Exam コンストラクターでは、ウィンドウのいくつかの基本プロパティを定義し、質問バンクから 3 種類の質問を取り出します。

次に、オプション コンポーネントを初期化します。ここでは、単一選択の質問と正誤質問は一連のラジオ ボタンを共有でき、複数選択の質問ではチェック ボックスが使用されます。

ボタン グループに 4 つのボタンを追加すると、同じボタン グループ内でラジオ ボタンが 1 つだけ選択できるようになります。ユーザーがラジオ ボタンの 1 つを選択すると、他のラジオ ボタンは自動的に選択解除され、ラジオ機能が実現されます。

完了した問題数、総問題数、正答数、3 種類の問題の現在の合計スコアと時間をリアルタイムで表示し、これらの情報は JPanel コンテナーに配置されます。

送信ボタンを設定し、イベントリスナーを実装し、ボタンがクリックされたときに送信回答メソッドを呼び出し、タイマーを設定します。回答が 20 秒を超える場合は、回答が自動的に送信されて回答が完了します。

最後に、質問を表示するスレッド giveQuestion を作成します。

giveQuestion の実装を見てみましょう。プログラムが再起動されるたびに質問の出現順序がランダムになるように、最初に質問の順序をシャッフルします。

次に、各質問タイプの最初の 5 つの質問、合計 15 の質問が表示され、対応する表示関数がそれぞれ呼び出されて質問が表示されます。

次に、タイマーを開始し、回答が送信されるのを待ち、次の質問に切り替えます。回答が 20 秒以内に送信されない場合、システムは自動的に submit 関数を呼び出して送信し、自動的に次の質問に切り替えます。すべての質問に回答すると、end 関数が呼び出されて結果が表示されます。

3 種類の質問の表示では、質問を切り替える必要があるため、JPanel コンテナを使用して質問のコンポーネントをインストールし、毎回質問を表示する前にこのコンテナ内のすべてのコンポーネントをクリアしてから、このコンポーネントを追加します。話題の。

単一選択の質問が表示され、ここに質問番号が追加されます。

同様の多肢選択問題が表示されます。

正誤質問の表示では、単一選択の質問と同じ一連のコンポーネントが使用されますが、正誤質問では正誤を示す 2 つのラジオ ボタンのみが必要です。

次に、回答を送信する関数に注目します。ここでは、まずカウンターを停止し、質問の種類ごとに回答を確認します。

選択問題の答えを確認するには、まず質問バンクから正解を取り出し、答えを比較し、正解を追加します。答えがない場合は、else に D を選択するのではなく、答えを空にする必要があるためです。

多肢選択式の質問の答えを確認するには、選択した ABCD を文字列として順番に連結し、正しい答えと直接比較して等しいかどうかを確認する必要があります。

正誤質問の答えを確認し、正しい答えを選択したかどうかを直接判断します。

答えに対してフィードバックを与えます。答えが正しければ正しいプロンプトと時間が与えられ、答えが間違っていれば正しい答えと時間が与えられ、その後 update 関数が呼び出されてステータスが更新されます。

スコアの更新、3 つの質問タイプの完了問題数と正答数の更新、およびオプション ステータスのクリアを行う更新機能を見てみましょう。

最終回答が完了したときに呼び出される end 関数は、計時を停止して結果を表示するために使用されます。

おすすめ

転載: blog.csdn.net/weixin_62264287/article/details/134973375