Очки не добавляются к баллу при выборе правильного ответа - PullRequest
1 голос
/ 12 июня 2019

Я делаю викторину.Когда пользователь нажимает на кнопку жанра на экране, чтобы ответить на вопрос, появляется другое окно с вопросом и четырьмя кнопками в качестве возможных ответов.Я пытался запрограммировать его так, чтобы при щелчке правильной опции баллы добавлялись к счету пользователя, а если щелкнуть по неправильной опции, они потеряют жизнь, но она не работает.

Я создал обработчик кнопок, в котором при нажатии на жанр открывается вопрос с 4 вариантами.Под этим я помещаю заявление if if if.Если щелкнуть правильный ответ, дайте пользователю очки, в противном случае, если он неправильный, отнимите жизнь.

private static class ButtonHandler implements ActionListener
    {
        public void actionPerformed (ActionEvent e)
        {

            if (e.getSource () == btnT1)
            {
                frame2.setVisible (true);
                btnT1.setEnabled (false);
                qTitle.setText ("Solar energy generates electricity from what source?");
                a1.setText ("The water");
                a2.setText ("The sun");
                a3.setText ("Fossil fuels");
                a4.setText ("The wind");

                if (e.getSource () == a2)
                {
                    score = score + 100;
                    frame2.setVisible (false);
                }
                else if (e.getSource () != a2)
                {
                    lives = lives - 1;
                    frame2.setVisible (false);
                }

            }

Я хочу добавить к счету и забрать жизни, но это не работает.Не могли бы вы помочь мне заставить его работать?Спасибо за помощь, спасибо.

Кроме того, этот код также может быть полезен для решения проблемы.Это все панели, кнопки, списки действий и т. Д.

private static void guiApp ()
    {

        ButtonHandler onClick = new ButtonHandler (); // calls on ButtonHandler class

        // Creating JPanels
        JPanel gameBoard = new JPanel ();
        JPanel titlePanel = new JPanel ();
        JPanel bottomPanel = new JPanel ();

        gameBoard.setLayout (new GridLayout (4, 5, 4, 4));
        titlePanel.setLayout (new BoxLayout (titlePanel, BoxLayout.PAGE_AXIS));
        bottomPanel.setLayout (new BoxLayout (bottomPanel, BoxLayout.PAGE_AXIS));

        JFrame frame = new JFrame ("Trivia Game");
        frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

        // To monitor button clicks
        btnT1.addActionListener (onClick);
        btnT2.addActionListener (onClick);
        btnT3.addActionListener (onClick);
        btnS1.addActionListener (onClick);
        btnS2.addActionListener (onClick);
        btnS3.addActionListener (onClick);
        btnF1.addActionListener (onClick);
        btnF2.addActionListener (onClick);
        btnF3.addActionListener (onClick);
        btnM1.addActionListener (onClick);
        btnM2.addActionListener (onClick);
        btnM3.addActionListener (onClick);
        btnG1.addActionListener (onClick);
        btnG2.addActionListener (onClick);
        btnG3.addActionListener (onClick); 

        // Formatting widgets
        Font titleFont = new Font ("Forte", Font.BOLD, 36);

        title.setFont (titleFont);
        title.setHorizontalAlignment (title.CENTER);
        tech.setHorizontalAlignment (tech.CENTER);
        sports.setHorizontalAlignment (sports.CENTER);
        food.setHorizontalAlignment (food.CENTER);
        movies.setHorizontalAlignment (movies.CENTER);
        geo.setHorizontalAlignment (geo.CENTER);

        titlePanel.add (title);

        // Adds buttons to panel
        gameBoard.add (tech);
        gameBoard.add (sports);
        gameBoard.add (food);
        gameBoard.add (movies);
        gameBoard.add (geo);
        gameBoard.add (btnT1);
        gameBoard.add (btnS1);
        gameBoard.add (btnF1);
        gameBoard.add (btnM1);
        gameBoard.add (btnG1);
        gameBoard.add (btnT2);
        gameBoard.add (btnS2);
        gameBoard.add (btnF2);
        gameBoard.add (btnM2);
        gameBoard.add (btnG2);
        gameBoard.add (btnT3);
        gameBoard.add (btnS3);
        gameBoard.add (btnF3);
        gameBoard.add (btnM3);
        gameBoard.add (btnG3);
        bottomPanel.add (scoreText);
        bottomPanel.add (livesText);

        //Get the frame's content pane
        Container contentPane = frame.getContentPane ();

        // add panel to frame
        contentPane.add (gameBoard, BorderLayout.CENTER);
        contentPane.add (titlePanel, BorderLayout.NORTH);
        contentPane.add (bottomPanel, BorderLayout.SOUTH);

        //size the window.
        frame.setSize (550, 500);
        frame.setVisible (true);

        // Questions window
        JPanel qPanel = new JPanel ();

        qPanel.setLayout(new BoxLayout(qPanel,BoxLayout.PAGE_AXIS));

        JFrame frame2 = new JFrame ("Question");
        frame2.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

        a1.addActionListener (onClick);
        a2.addActionListener (onClick);
        a3.addActionListener (onClick);
        a4.addActionListener (onClick);

        qPanel.add (qTitle);
        qPanel.add (a1);
        qPanel.add (a2);
        qPanel.add (a3);
        qPanel.add (a4);        

        Container contentPane2 = frame2.getContentPane ();

        contentPane2.add (qPanel);

        //size the window.
        frame2.setSize (500, 200);
        frame2.setVisible (false);

        //Results Window
        JPanel resultsPanel = new JPanel ();
        JPanel rBottomPanel = new JPanel ();

        resultsPanel.setLayout(new BorderLayout());
        rBottomPanel.setLayout (new BoxLayout (rBottomPanel, BoxLayout.LINE_AXIS));

        JFrame frame3 = new JFrame ("Results");
        frame3.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

        resultsPanel.add (resultsMessage, BorderLayout.NORTH);
        rBottomPanel.add (reset, BorderLayout.SOUTH);
        rBottomPanel.add (exit, BorderLayout.SOUTH);

        Container contentPane3 = frame3.getContentPane ();

        contentPane3.add (resultsPanel);
        contentPane3.add (rBottomPanel, BorderLayout.SOUTH);

        //size the window.
        frame3.setSize (400, 300);
        frame3.setVisible (false);
    }

1 Ответ

0 голосов
/ 12 июня 2019

Логика здесь неверна:

private static class ButtonHandler implements ActionListener
{
    public void actionPerformed (ActionEvent e)
    {

        if (e.getSource () == btnT1)
        {
            frame2.setVisible (true);
            btnT1.setEnabled (false);
            qTitle.setText ("Solar energy generates electricity from what source?");
            a1.setText ("The water");
            a2.setText ("The sun");
            a3.setText ("Fossil fuels");
            a4.setText ("The wind");

            if (e.getSource () == a2)
            {
                score = score + 100;
                frame2.setVisible (false);
            }
            else if (e.getSource () != a2)
            {
                lives = lives - 1;
                frame2.setVisible (false);
            }

        }

Этот обработчик будет активирован при нажатии btnT1, до нажатия любой из кнопок a1, a2, a3 или a4, и поэтому вы выполняете свою логическую Тестирование до У пользователя была возможность сделать выбор.

Чтобы это работало, слушатели на a1, a2, a3 и a4 должны иметь логику, которую имеет этот слушатель.

Если бы это была моя программа, я бы отделил свой GUI («представление») от логической части моей программы («модель»), я бы создал класс вопросов, не относящийся к GUI, который содержит текст вопросов, содержащий правильный ответ, который может проверять правильность, и GUI QuestionView, который отображает вопрос и может проверять ответ пользователя по модели (Вопросу), в которой он находится - я бы выделил все это, и не пытайтесь жестко закодировать это, как вы делаете.

В качестве отступления, пожалуйста, прочитайте Использование нескольких JFrames, хорошая / плохая практика?


Например, я бы создал отдельный класс для Question, класс без графического интерфейса пользователя, который содержит вопрос String, строку ответа и возможный ответ ArrayList<String>, который содержит все ответы, которые может выбрать пользователь, что-то вроде этого могло бы работа:

public class Question {
    private String question;
    private List<String> possibleAnswers;
    private String answer;

    public Question(String question, List<String> possibleAnswers, String answer) {
        this.question = question;
        this.answer = answer;

        // randomize things:
        this.possibleAnswers = new ArrayList<>(possibleAnswers);
        Collections.shuffle(this.possibleAnswers);
    }

    public String getQuestion() {
        return question;
    }

    public List<String> getPossibleAnswers() {
        return possibleAnswers;
    }

    public String getAnswer() {
        return answer;
    }

    // test if String matches answer
    public boolean test(String possibleAnswer) {
        return answer.equals(possibleAnswer);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("Q: ");
        sb.append(question);
        sb.append("; ");
        sb.append("A: ");
        sb.append(answer);
        sb.append("; ");
        sb.append(possibleAnswers);
        return sb.toString();
    }
}

Я бы отделил данные от кода и создал бы простой текстовый файл для хранения вопросов. Опять будь проще. В файле, созданном для примера программы, которую я создал, данные вопросов содержались в несколько строк с пустой строкой, разделяющей вопросы. Первая строка каждого вопроса содержала текст вопроса, следующая строка была правильным ответом, а следующие несколько строк были неправильными ответами. Опять же, пустая строка отделяет вопросы. Обратите внимание, что в моем конструкторе класса Question выше я рандомизировал ответы, поэтому в реальном объекте Question больше не гарантируется, что первый возможный ответ будет правильным. Текстовый файл может выглядеть так:

QuestionsFile.txt

Who is buried in Grant's tomb?
Ulysses Grant
George Washington
Abraham Lincoln
Donald Trump

What color was Washington's white horse?
White
Blue
Green
Brown

How many days are there in a week?
7
4
2
3

What is 2 + 2?
4
2
11
I have no idea?

What is the largest celestial body in the solar system?
The sun
Jupiter 
Mars
What is the solar system?

Я бы построчно создавал код для чтения в этом файле, создавая объекты Question во время чтения и помещая их в ArrayList<Question>.

Затем я бы создал JPanel, который отображает один Вопрос в виде графического интерфейса пользователя, что-то с JLabel для отображения строки String, коллекцию JRadioButtons, хранящуюся во вложенном JPanel, который использует GridLayout для хранения возможных строк ответа, и JButton, чтобы представить выбор пользователя для оценки.

Например:

@SuppressWarnings("serial")
public class QuestionViewPanel extends JPanel {
    private Question question; // model for this view
    private JLabel questionLabel;
    private ButtonGroup answersGroup = new ButtonGroup();
    private JButton submitButton = new JButton("Submit");
    private JButton clearAnswerButton = new JButton("Clear Answer");

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

        questionLabel = new JLabel(question.getQuestion());
        questionLabel.setBorder(BorderFactory.createTitledBorder("Question:"));

        JPanel possAnswersPanel = new JPanel(new GridLayout(0, 1));
        possAnswersPanel.setBorder(BorderFactory.createTitledBorder("Possible Answers:"));
        for (String possAnswer : question.getPossibleAnswers()) {
            JRadioButton rBtn = new JRadioButton(possAnswer);
            rBtn.setActionCommand(possAnswer);
            answersGroup.add(rBtn);
            possAnswersPanel.add(rBtn);
        }

        clearAnswerButton.setMnemonic(KeyEvent.VK_C);
        clearAnswerButton.addActionListener(e -> answersGroup.clearSelection());
        submitButton.setMnemonic(KeyEvent.VK_S);
        JPanel bottomPanel = new JPanel();
        bottomPanel.add(submitButton);
        bottomPanel.add(clearAnswerButton);

        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        setLayout(new BorderLayout(5, 5));
        add(questionLabel, BorderLayout.PAGE_START);
        add(possAnswersPanel, BorderLayout.CENTER);
        add(bottomPanel, BorderLayout.PAGE_END);
    }

    public void addSubmitListener(ActionListener listener) {
        submitButton.addActionListener(listener);
    }

    public Question getQuestion() {
        return question;
    }

    public boolean testAnswer() {
        boolean result = false;
        ButtonModel model = answersGroup.getSelection();
        if (model != null) {
            String possibleAnswer = model.getActionCommand();
            result = question.test(possibleAnswer);
        }
        return result;
    }

}

Затем создайте класс быстрого и грязного драйвера, который создает GUI, который использует CardLayout для замены объекта QuestionViewPanel и который объединяет вещи:

@SuppressWarnings("serial")
public class QuestionTest extends JPanel {
    // This String likely needs to be changed
    private static final String RESOURCE_PATH = "QuestionsFile.txt";
    private List<Question> questionsList = new ArrayList<>();
    private List<QuestionViewPanel> questionViewList = new ArrayList<>();
    private CardLayout cardLayout = new CardLayout();
    private JPanel questionViewShowPanel = new JPanel(cardLayout);

    public QuestionTest(List<Question> questionsList) {
        this.questionsList = questionsList;
        for (Question question : questionsList) {
            QuestionViewPanel qView = new QuestionViewPanel(question);
            qView.addSubmitListener(new SubmitListener(qView));
            questionViewShowPanel.add(qView, question.getQuestion());
        }
        setLayout(new BorderLayout());
        add(questionViewShowPanel);
    }

    private class SubmitListener implements ActionListener {
        private QuestionViewPanel qView;

        public SubmitListener(QuestionViewPanel qView) {
            this.qView = qView;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            boolean result = qView.testAnswer();
            String text = result ? "Correct!" : "Wrong!  The correct answer is: " 
                        + qView.getQuestion().getAnswer();
            JOptionPane.showMessageDialog(qView, text, "Result", JOptionPane.PLAIN_MESSAGE);
            cardLayout.next(questionViewShowPanel);
        }
    }

    private static void createAndShowGui(List<Question> questionsList) {
        QuestionTest mainPanel = new QuestionTest(questionsList);

        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);  
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        final List<Question> questionsList = new ArrayList<>();

        InputStream questionsStream = QuestionTest.class.getResourceAsStream(RESOURCE_PATH);
        Scanner scanner = new Scanner(questionsStream);
        String question = "";
        String answer = "";
        List<String> possibleAnswers = new ArrayList<>();
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();           
            if (line.trim().isEmpty()) {
                if (!question.trim().isEmpty()) {
                    questionsList.add(new Question(question, possibleAnswers, answer));
                    question = "";
                    answer = "";
                    possibleAnswers = new ArrayList<>();
                }
            } else if (question.trim().isEmpty()) {
                question = line;
            } else {
                possibleAnswers.add(line);
                if (answer.trim().isBlank()) {
                    answer = line;
                }
            }
        }
        if (!question.trim().isEmpty()) {
            questionsList.add(new Question(question, possibleAnswers, answer));
            question = "";
            answer = "";
            possibleAnswers = new ArrayList<>();
        }
        if (scanner != null) {
            scanner.close();
        }

        SwingUtilities.invokeLater(() -> createAndShowGui(questionsList));
    }
}

Графический интерфейс из этого кода будет выглядеть так:

enter image description here

...