Java — использование функции IsSelected в radioButtons и JPanel

Мне нужно установить «викторину» на Java, используя JPanel и JRadioButton.

Мой код начинается с чтения текста из файла и помещения его на панель с переключателями, группами кнопок и панелью. Все идет нормально.

Однако моя проблема начинается, когда мне нужно собрать данные от пользователя и сравнить их с правильными ответами.

У меня есть класс Вопросы, Ответы и Чтение (кроме основного и отображения на панели).

Я думал, что когда пользователь нажимает кнопку submit, код показывает звездочки для проверки викторины. Однако ничего не происходит, когда я нажимаю на открытое окно.

Собираю данные в ArrayList для сравнения.

Предполагается, что метод checkQuiz вызывается после того, как пользователь отправит тест. Он сравнивает выбранный радиокнопкой текст с ответом. Предполагается, что программа «работает» до тех пор, пока пользователь не нажмет кнопку «Отправить», однако я считаю, что этого не происходит.

Я попытался использовать ActionListener в коде, но не смог сравнить выбор пользователя с данными, которые использую я.

Извините за большое количество кода. Я попытался опубликовать вопрос mcve. Насколько я знаю, код компилируется, но я не мог игнорировать больше строк.

Спасибо за помощь, код ниже. Приложение

Класс DisplayOnPanel создает фрейм для использования подклассом:

import javax.swing.JFrame;

public class DisplayOnPanel extends JFrame {
    JFrame frame = new JFrame();
    public DisplayOnPanel(){
        frame.setSize(500,500);
    }
}

Основной класс:

public class Main {
public static void main (String[]args){
      new Read();
    }
}

Вопросы о выпускных:

public class Question {
private String _question;
private String _option1;
private String _option2;
private String _option3;
private String _option4;
private int _qIndex=0;
public Question(String question, String option1, String option2, String option3,
                String option4){
    this._question = question;
    this._option1 = option1;
    this._option2 = option2;
    this._option3 = option3;
    this._option4 = option4;


}
public void set_qIndex(int index) {
    this._qIndex = index;
}

Class Read — чтение из файла и последующее отображение результатов на панели. Он также заполняет ArrayLists ответами, вопросами, ButtonGroups и JPanels.

import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Read extends DisplayOnPanel {


protected ArrayList<Question> Questions = new ArrayList<>();
protected ArrayList<ButtonGroup> BG = new ArrayList<>();
protected ArrayList<JPanel> JP = new ArrayList<>();
protected ArrayList<Answer> Answers = new ArrayList<>();
protected int qNumber = 0, finalscore = 0;
private JLabel lblScore;
private JToggleButton Submit = new JToggleButton();
//constructor

public Read() {
    super();
    //a "label" in the file will indicate the final score
    final int NUMBER_OF_LABELS_ADDED_TO_FRAME = 1;
    int number_of_lines_in_the_file, final_score = 0;
    try {
        number_of_lines_in_the_file = read(Questions);
        addButtonsToFrame(Questions, number_of_lines_in_the_file +
                NUMBER_OF_LABELS_ADDED_TO_FRAME, BG, JP);
        Submit.setText("Submit Quiz"); //create a submit button
        JPanel SubmitPanel = new JPanel();
        SubmitPanel.setVisible(true);
        this.add(SubmitPanel);
        SubmitPanel.add(Submit);

Submit.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    for (int i = 0; i < BG.size(); i++) {
                        //handle cases of the user didn't complete the test
                        if (BG.get(i).getSelection()==null) {
                            JOptionPane.showMessageDialog(frame, "Exam not finished - Restart.");
                            i=BG.size()-1; //finish the loop
                            frame.setVisible(false);
                            dispose();
                            new Read();
                        }
                    }
                    checkQuiz(BG, Answers, ONE_QUESTION_GRADE); //check quiz
                    Submit.setEnabled(false); //can't redo quiz //
                    // unless "Restart" pressed


                }
            });            
//adding final score label
        lblScore = new JLabel("Your Final Score: " + finalscore);
        add(lblScore);
        pack();
        this.setVisible(true);
        while (!Submit.isSelected()) {
            if (Submit.isSelected()) {
                checkQuiz(BG, Answers);
            }
        }
    } catch (FileNotFoundException e) {
        System.out.println("couldn't open file");
    }
}
//the method reads from the file


//returns the number of lines (quesiton) in the file

public int read(ArrayList<Question> Questions) throws FileNotFoundException {
    int number_of_lines = 0;
    try {
        File f = new File("C:\\Users\\Assaf\\Desktop\\exam.txt");
        Scanner input = new Scanner(f);
        //read from file direcly into the constructor
        while (input.hasNext()) {
            Question q = new Question((input.nextLine())
                    , (input.nextLine()),
                    (input.nextLine()),
                    (input.nextLine()),
                    (input.nextLine()));
            //adding the question and the answers to an array
            Questions.add(q);
            number_of_lines++;
            q.set_qIndex(number_of_lines);
            Answers.add(new Answer(q));

        }
        input.close();
    } catch (FileNotFoundException nf) {
        System.out.println("couldn't open file");
    }
    //return number of lines in the file
    return number_of_lines;
}
public void addButtonsToFrame(ArrayList<Question> q, int number_of_lines,
                              ArrayList<ButtonGroup> BG, ArrayList<JPanel> JP) {
    int j = 0;
    for (int i = 0; i < q.size(); i++) {
        qNumber = i;
        BG.add(new ButtonGroup());
        JP.add(new JPanel());
        JP.get(i).setSize(499, 400);
        //creating buttons
JRadioButton option1 = new JRadioButton(q.get(i).get_option1());
option1.setActionCommand(q.get(i).get_option1());
JRadioButton option2 = new JRadioButton(q.get(i).get_option2());
option2.setActionCommand(q.get(i).get_option2());
JRadioButton option3 = new JRadioButton(q.get(i).get_option3());
option3.setActionCommand(q.get(i).get_option3());
JRadioButton option4 = new JRadioButton(q.get(i).get_option4());
option4.setActionCommand(q.get(i).get_option4());
        //adding to group buttons
        BG.get(j).add(option1);
        BG.get(j).add(option2);
        BG.get(j).add(option3);
        BG.get(j).add(option4);
        //adding the buttons to the panel
        JP.get(j).add(option1);
        JP.get(j).add(option2);
        JP.get(j).add(option3);
        JP.get(j).add(option4);
        //setting layout that matches our goal
        this.setLayout(new GridLayout(number_of_lines + 1, 1));
        //set title and border for each question
        JP.get(i).setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createEtchedBorder(), "question number " + qNumber + ": " + q.get(i).get_question()));
        //adding the panel to the frame
        this.add(JP.get(j));
        //BG.get(i).getSelection()
        JP.get(j).setVisible(true);
        j++;
    }
}
public void checkQuiz(ArrayList<ButtonGroup> BG, ArrayList<Answer> A) {
    ArrayList<String> Selections = new ArrayList<>();
    int CORRECT_ANSWER = 0;
    for (int i = 0; i < BG.size(); i++) {
        if (BG.get(i).getSelection().getActionCommand()
                .compareTo(A.get(i).get_answer()) == CORRECT_ANSWER) {
            finalscore = finalscore + 10;
        }
    }

}

Ответ класса

public class Answer {
private String _question;
private String _answer;
private int _qIndex=0;

public Answer (Question q){
    this._answer = q.get_option1();
    this._question=q.get_question();
    this._qIndex=q.get_qIndex();

}

Редактировать – опубликовал мой рабочий код.


person Assaf    schedule 29.11.2017    source источник
comment
Я не нахожу EventListener в вашем коде. Кроме того, объект frame, который вы создали в DisplayOnPanel, бесполезен, поскольку он нигде не используется.   -  person Praveen    schedule 29.11.2017
comment
Проблема с EventListener здесь заключается в том, что я получаю исключение nullPointerException, так как пытаюсь провести сравнение с методом CheckQuiz. Как я могу его использовать? Благодарю вас!   -  person Assaf    schedule 29.11.2017
comment
Я попытался работать с EvenListener - и обнаружил, что не могу вызвать другой метод, который работает с массивами - все время получая нулевые исключения.   -  person Assaf    schedule 29.11.2017
comment
"The program is supposed to be "running" until the user clicks the "submit" button, however I believe it does not happen." Свинг работает НЕ так. Вам не нужен цикл, и это заморозит ваш графический интерфейс. Просто используйте ActionListener на кнопке отправки и проверьте, какие радиокнопки выбраны с помощью isSelected () на ваших радиокнопках, когда происходит событие (щелчок по кнопке или нажатая клавиша ‹Enter›).   -  person Ansharja    schedule 29.11.2017
comment
Спасибо @Ansharja, это отличная идея, но я получаю нулевое исключение, когда пытаюсь это сделать. BG и остальные массивы равны нулю, когда я это делаю по какой-то причине.   -  person Assaf    schedule 29.11.2017
comment
Приложения в графическом пользовательском интерфейсе управляются событиями, небольшие части реагируют на события, такие как нажатие кнопки. Не последовательно во времени. Возможно, сначала осмотрите несколько небольших демо-приложений.   -  person Joop Eggen    schedule 29.11.2017
comment
Попробуйте отредактировать свой код, чтобы создать настоящий минимально воспроизводимый пример, в котором вы используете ActionListener. Предложенный способ работает, вы что-то делаете не так.   -  person Ansharja    schedule 29.11.2017


Ответы (1)


i) Вам необходимо установить команду действия перед ее получением,

JRadioButton option1 = new JRadioButton(q.get(i).get_option1());
option1.setActionCommand(q.get(i).get_option1());
JRadioButton option2 = new JRadioButton(q.get(i).get_option2());
option2.setActionCommand(q.get(i).get_option2());
JRadioButton option3 = new JRadioButton(q.get(i).get_option3());
option3.setActionCommand(q.get(i).get_option3());
JRadioButton option4 = new JRadioButton(q.get(i).get_option4());
option4.setActionCommand(q.get(i).get_option4());

ii) Вы не установили окончательную оценку в ярлыке в конце метода checkQuiz,
lblScore.setText("Your Final Score: " + finalscore);

iii) Не рекомендуется использовать цикл while. Также метод checkQuiz не будет вызываться большую часть времени с текущей используемой вами логикой. Следовательно, используйте интерфейс ActionListener вместо while,

Submit.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent arg0) {
         checkQuiz(BG, Answers);
    }
});
person Praveen    schedule 29.11.2017
comment
Спасибо!!! Что делает setActionCommand, чего не делает обычный ActionListener? - person Assaf; 29.11.2017
comment
setActionCommand задает команду действия в формате String, который помогает определить действие, которое нужно выполнить во время и ActionEvent в формате ActionListener. - person Praveen; 29.11.2017