简体   繁体   English

如何计算正确选择的JRadioButton并打印总的“分数”?

[英]How do I count the correctly selected JRadioButton and Print a total “Score”?

My application is a Mutliple choice quiz. 我的应用程序是Mutliple选择测验。 Right now there are only two questions so i can test the logic, but after I figure it out ill add up to 100. Really I have a new Frame with buttons added to a panel and then the panel added to the JFrame. 现在只有两个问题,因此我可以测试逻辑,但是在我弄清楚它的总和为100后。确实,我有一个新的Frame,将按钮添加到面板,然后将该面板添加到JFrame。 I then use nextQuestion() method to allow me to go through multiple questions as long as there are questions left.and there is also a timer that i through in their that gives a time for each question, 10 seconds. 然后我使用nextQuestion()方法使我可以处理多个问题,只要还有剩余的问题。还有一个计时器可以让我为每个问题留出10秒的时间。

        protected void nextQuestion() {
            timer.stop();
            currentQuestion++;
            if (currentQuestion >= quiz.size()) {
                cardLayout.show(QuestionsPanel, "last");
                next.setEnabled(false);
                //Show however many correct after last question. 
                //iterate on the collection to count the selected radio buttons
                //What im confused about is really how do i tell the program which (options) are right or wrong. 
                //and if i can do that how do i only count the correct ones. 
                //or for example do i have to take the total questions and subtract by the ones they didnt choose? 
                //a code example on how to do this would be great. 
            } else {
                cardLayout.show(QuestionsPanel, Integer.toString(currentQuestion));
                startTime = null;
                next.setText("Next");
                next.setEnabled(true);
                timer.start();
            }
        }



    public interface Question {

        public String getPrompt();

        public String getCorrectAnswer();

        public String[] getOptions();

        public String getUserResponse();

        public void setUserResponse(String response);

        public boolean isCorrect();
    }

    public class ChoiceQuestion implements Question {

        private final String prompt;
        private final String correctAnswer;
        private final String[] options;

        private String userResponse;

        public ChoiceQuestion(String prompt, String correctAnswer, String... options) {
            this.prompt = prompt;
            this.correctAnswer = correctAnswer;
            this.options = options;
        }

        @Override
        public String getPrompt() {
            return prompt;
        }

        @Override
        public String getCorrectAnswer() {
            return correctAnswer;
        }

        @Override
        public String[] getOptions() {
            return options;
        }

        @Override
        public String getUserResponse() {
            return userResponse;
        }

        @Override
        public void setUserResponse(String response) {
            userResponse = response;
        }

        @Override
        public boolean isCorrect() {
            return getCorrectAnswer().equals(getUserResponse());
        }
    }

    public class QuestionPane extends JPanel {

        private Question question;

        public QuestionPane(Question question) {
            this.question = question;

            setLayout(new BorderLayout());

            JLabel prompt = new JLabel("<html><b>" + question.getPrompt() + "</b></html>");
            prompt.setHorizontalAlignment(JLabel.LEFT);

            add(prompt, BorderLayout.NORTH);

            JPanel guesses = new JPanel(new GridBagLayout());
            guesses.setBorder(new EmptyBorder(10,10,10,10));
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1;
            gbc.anchor = GridBagConstraints.WEST;

            List<String> options = new ArrayList<>(Arrays.asList(question.getOptions()));
            options.add(question.getCorrectAnswer());
            Collections.sort(options);

            ButtonGroup bg = new ButtonGroup();
            for (String option : options) {
                JRadioButton btn = new JRadioButton(option);
                bg.add(btn);

                guesses.add(btn, gbc);
            }

            add(guesses);

        }

        public Question getQuestion() {
            return question;
        }

        public class ActionHandler implements ActionListener {

            @Override
            public void actionPerformed(ActionEvent e) {
                getQuestion().setUserResponse(e.getActionCommand());
            }

        }

    }

}

SO really i just have an issue with doing that small if else code block. 所以,实际上我只是在做那么小的代码块方面遇到问题。 If you guys could help me out. 如果你们可以帮助我。 I got some ideas about iterating a collection although i have no idea how to do that.These are just the classes im using and the method i am having a problem with. 尽管我不知道如何做到这一点,但我对迭代一个集合有一些想法。这些只是im正在使用的类以及我遇到问题的方法。

So really simply, when nextQuestion is called, you want to check to see if the currentQuestion is correct or not 真的很简单,当nextQuestion时,您要检查currentQuestion是否正确

private int correctAnswers = 0;
//...
protected void nextQuestion() {
    timer.stop();
    if (currentQuestion >= 0 && currentQuestion < quiz.size()) {
        Question question = quiz.get(currentQuestion);
        if (question.isCorrect()) {
            correctAnswers++;
        }
    }
    currentQuestion++;
    if (currentQuestion >= quiz.size()) {
        cardLayout.show(panelOfQuestions, "last");
        next.setEnabled(false);
    } else {
        cardLayout.show(panelOfQuestions, Integer.toString(currentQuestion));
        startTime = null;
        next.setText("Next");
        next.setEnabled(true);
        timer.start();
    }
}

Here is an example solution for your problem. 这是您的问题的示例解决方案。 Is exactly your original code, with a couple of modifications. 正是您的原始代码,进行了一些修改。 The key is to understand that you have to relate at any moment the selected answer and fill the "userResponse" field of the Choice Question. 关键是要了解您必须随时关联选择的答案并填写选择问题的“ userResponse”字段。

It seems obvious that the best place to set this is when user press "next" button. 似乎最好的设置位置是在用户按下“下一步”按钮时。 You check the radio button selected and fill the ChoiseQuestion accordingly. 您选中选中的单选按钮,并相应地填写ChoiseQuestion。

At last, just manage the quiz List to check how many correct results there are. 最后,只需管理测验列表即可检查有多少正确结果。 In my example, the result is printed on the console. 在我的示例中,结果打印在控制台上。

public class QuizMain { 公共类QuizMain {

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

public QuizMain() {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                ex.printStackTrace();
            }

            List<Question> quiz = new ArrayList<>(5);
            // Couple of conceptual mistakes here.... 
            quiz.add(new ChoiceQuestion("Where is Japan Located?", "Asia", "North America", "Africa", "Europe", "Asia"));
            // There was a mistake, correct answer is 2
            // quiz.add(new ChoiceQuestion("1 + 1:", "2", "4", "3", "1"));
            quiz.add(new ChoiceQuestion("1 + 1:", "2", "4", "3", "2", "1"));

            JFrame frame = new JFrame("QUIZ TIME!");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new QuizPane(quiz));
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
}

public class QuizPane extends JPanel {

    private List<Question> quiz;

    private long countdown = 10;
    private Timer timer;
    private JButton next;
    private JButton intro;


    private CardLayout cardLayout;
    private int currentQuestion;

    private JPanel QuestionsPanel;

    private Long startTime;

    public QuizPane(List<Question> quiz) {
        this.quiz = quiz;
        cardLayout = new CardLayout();
        QuestionsPanel = new JPanel(cardLayout);
        QuestionsPanel.setBorder(new EmptyBorder(40,45,40,45));

        JButton start = new JButton("Start");
        start.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                currentQuestion = -1;
                nextQuestion();
                timer.start();
            }
        });

        JButton intro = new JButton("Instructions");
        intro.addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            instructionBox();
          }
        });


        JPanel mainPanel = new JPanel(new GridBagLayout());
        mainPanel.add(start);
        mainPanel.add(intro);
        QuestionsPanel.add(mainPanel, "start");


        for (int index = 0; index < quiz.size(); index++) {
            Question question = quiz.get(index);
            QuestionPane pane = new QuestionPane(question);
            question.setButtonGroup(pane.getButtonGroup());
            QuestionsPanel.add(pane, Integer.toString(index));
        }
        QuestionsPanel.add(new JLabel("You have finished the Quiz"), "last");
        currentQuestion = 0;
        cardLayout.show(QuestionsPanel, "Start");

        setLayout(new BorderLayout());
        add(QuestionsPanel);

        JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        next = new JButton("Next");
        buttonPane.add(next);
        next.setEnabled(false);

        add(buttonPane, BorderLayout.SOUTH);

        next.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                nextQuestion();
            }
        });

        timer = new Timer(250, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (startTime == null) {
                    startTime = System.currentTimeMillis();
                }
                long duration = (System.currentTimeMillis() - startTime) / 1000;
                if (duration >= countdown) {
                    nextQuestion();
                } else {
                    long timeLeft = countdown - duration;
                    next.setText("Next (" + timeLeft + ")");
                    next.repaint();
                }
            }
        });
    }

    protected void nextQuestion() {
        // store the selected answer for each question
        if (currentQuestion >= 0 && currentQuestion < quiz.size() ) {
            Question currentQObject = quiz.get(currentQuestion);
            if (currentQObject != null) {
                currentQObject.setUserResponse(getSelected(currentQObject.getButtonGroup()));
            }
        }
        timer.stop();
        currentQuestion++;
        if (currentQuestion >= quiz.size()) {
            cardLayout.show(QuestionsPanel, "last");
            next.setEnabled(false);
            //Show however many correct after last question. 
            //iterate on the collection to count the selected radio buttons
            //What im confused about is really how do i tell the program which (options) are right or wrong. 
            //and if i can do that how do i only count the correct ones. 
            //or for example do i have to take the total questions and subtract by the ones they didnt choose? 
            //a code example on how to do this would be great.

            // Just iterate over quiz list to check if answers are correct:
            int totalCorrect = 0;
            for (Question q : quiz) {
                if (q.isCorrect()) { 
                    totalCorrect++;
                }
            }

            // Show Corrects any way....
            System.out.println("Total correct responses: " + totalCorrect);

        } else {
            cardLayout.show(QuestionsPanel, Integer.toString(currentQuestion));
            startTime = null;
            next.setText("Next");
            next.setEnabled(true);
            timer.start();
        }
    }

    private String getSelected(ButtonGroup buttonGroup) {
        JRadioButton selectedRadio = null;
        Enumeration e = buttonGroup.getElements();
        while (e.hasMoreElements()) {
            JRadioButton rad = (JRadioButton) e.nextElement();
            if (rad.isSelected()) {
                selectedRadio = rad;
                break;
            }
        }
        return selectedRadio.getText();
    }

    protected void instructionBox() {
        JOptionPane.showMessageDialog(null,"<html><b><div width='111px' height = '82px' align='justified'> 1.You have limited time to answer each question and your score will be shown at the end of the test. Good Luck!</div></body></html>",
        "Instructions",
        JOptionPane.INFORMATION_MESSAGE);
     }
 }

public interface Question {

    public String getPrompt();

    public void setButtonGroup(ButtonGroup buttonGroup);

    public ButtonGroup getButtonGroup();

    public String getCorrectAnswer();

    public String[] getOptions();

    public String getUserResponse();

    public void setUserResponse(String response);

    public boolean isCorrect();
}

public class ChoiceQuestion implements Question {

    private final String prompt;
    private final String correctAnswer;
    private final String[] options;
    private ButtonGroup buttonGroup;

    private String userResponse;

    public ChoiceQuestion(String prompt, String correctAnswer, String... options) {
        this.prompt = prompt;
        this.correctAnswer = correctAnswer;
        this.options = options;
    }

    @Override
    public void setButtonGroup(ButtonGroup buttonGroup) {
        this.buttonGroup = buttonGroup;
    }

    @Override
    public ButtonGroup getButtonGroup() {
        return this.buttonGroup;
    }

    @Override
    public String getPrompt() {
        return prompt;
    }

    @Override
    public String getCorrectAnswer() {
        return correctAnswer;
    }

    @Override
    public String[] getOptions() {
        return options;
    }

    @Override
    public String getUserResponse() {
        return userResponse;
    }

    @Override
    public void setUserResponse(String response) {
        userResponse = response;
    }

    @Override
    public boolean isCorrect() {
        return getCorrectAnswer().equals(getUserResponse());
    }
}

public class QuestionPane extends JPanel {

    private Question question;

    private ButtonGroup buttonGroup = null;

    public QuestionPane(Question question) {
        this.question = question;

        setLayout(new BorderLayout());

        JLabel prompt = new JLabel("<html><b>" + question.getPrompt() + "</b></html>");
        prompt.setHorizontalAlignment(JLabel.LEFT);

        add(prompt, BorderLayout.NORTH);

        JPanel guesses = new JPanel(new GridBagLayout());
        guesses.setBorder(new EmptyBorder(10,10,10,10));
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.weightx = 1;
        gbc.anchor = GridBagConstraints.WEST;

        List<String> options = new ArrayList<>(Arrays.asList(question.getOptions()));
        //options.add(question.getCorrectAnswer());
        Collections.sort(options);

        ButtonGroup bg = new ButtonGroup();
        for (String option : options) {
            JRadioButton btn = new JRadioButton(option);
            btn.setName(option);
            bg.add(btn);

            guesses.add(btn, gbc);
        }
        this.buttonGroup = bg;

        add(guesses);
    }

    public ButtonGroup getButtonGroup() {
        return buttonGroup;
    }

    public Question getQuestion() {
        return question;
    }

    public class ActionHandler implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            getQuestion().setUserResponse(e.getActionCommand());
        }

    }

}

Hope it helps 希望能帮助到你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM