简体   繁体   English

.setBackground()方法不适用于JRadioButton

[英].setBackground() method is not working for JRadioButton

I'm writing a program that has a quiz element, and when the user gets an answer wrong, feedback is given. 我正在编写一个具有测验元素的程序,当用户得到错误答案时,就会给出反馈。 The question JFrame is made of a JLabel that has the actual question, and 4 JRadioButtons that have the different options (named rad1, rad2, rad3, rad4). 问题JFrame由具有实际问题的JLabel和具有不同选项(名为rad1,rad2,rad3,rad4)的4个JRadioButton组成。 What I'm trying to do is if the user gets an asnswer wrong, the radio button with the correct answer's background colour turns green and the radio button with the answer that the user gave's background turns red. 我要尝试做的是,如果用户弄错了答案,则具有正确答案背景颜色的单选按钮将变为绿色,而具有用户给出背景答案的单选按钮将变为红色。

Here's the FOR loop that I'm using to figure out which of the answers is correct: 这是我用来确定哪个答案正确的FOR循环:

private void btnSubmitActionPerformed(java.awt.event.ActionEvent evt) {                                          
    System.out.println("Submit Clicked");
    //figures out what choice the user selected
    String correctAnswer = questions.get(current).getAnswer();
    int numChoice = -1;
    String choice = "";
    boolean answered = false;

    if (rad1.isSelected()) {
        numChoice = 0;
        answered = true;
        choice = rad1.getText();
    } else if (rad2.isSelected()) {
        numChoice = 1;
        answered = true;
        choice = rad2.getText();
    } else if (rad3.isSelected()) {
        numChoice = 2;
        answered = true;
        choice = rad3.getText();
    } else if (rad4.isSelected()) {
        numChoice = 3;
        answered = true;
        choice = rad4.getText();
    } else { //user didn't pick a choice
        JOptionPane.showMessageDialog(null, "You didn't answer the question, try again!");
    }

    if (choice.equals(correctAnswer)) {
        score++;
        System.out.println("score++");
    } else {
        //figures out which of the answers was correct
        rad1.setBackground(Color.RED);
        for (int i = 0; i < 4; i++) {
            if (questions.get(current).getChoices()[i].equals(correctAnswer)) {
                System.out.println(correctAnswer);
                System.out.println(i);
                //me trying to see if it will change if I put it outside the switch
                //confirmed that it will not.
                rad1.setBackground(Color.RED);
                switch (i) {
                    case 0:
                        rad1.setBackground(new Color(51, 204, 51));
                        break;
                    case 1:
                        rad2.setBackground(new Color(51, 204, 51));
                        break;
                    case 2:
                        rad3.setBackground(new Color(51, 204, 51));
                        break;
                    case 3:
                        rad4.setBackground(new Color(51, 204, 51));
                        break;
                }
                break;
            }

        }
        switch (numChoice) {
            case 0:
                rad1.setBackground(new Color(153, 0, 0));
                break;
            case 1:
                rad2.setBackground(new Color(153, 0, 0));
                break;
            case 2:
                rad3.setBackground(new Color(153, 0, 0));
                break;
            case 3:
                rad4.setBackground(new Color(153, 0, 0));
                break;
        }
    }
    //loads next question


    //loads the next question
    if (current < 10) {
        updateFrame();
    } else {
        //ends the quiz
    }
}                    

I've been playing around with the .setBackground() method for a while, and if I put print statements in the case blocks, they execute, but the colouring doesn't happen. 我一直在使用.setBackground()方法一段时间,如果我将print语句放在case块中,它们会执行,但是不会发生着色。 Is there something dumb that I'm missing? 我缺少什么笨蛋吗?

Thanks 谢谢

EDIT: Added more code to see that the FOR loop is within the btnSubmitActionPerformed() method. 编辑:添加了更多代码,以查看FOR循环在btnSubmitActionPerformed()方法内。 When the user clicks the button, their answer is to be judged and the colour of the radio button is to be changed. 当用户单击按钮时,将判断其答案,并更改单选按钮的颜色。

Two immediate things jump to mind: 马上想到两件事:

  1. Where is the code you posted being called from? 您发布的代码从哪里调用? Making UI changes outside of the Swing worker thread is sort of undefined. 在Swing工作线程之外进行UI更改是不确定的。 Sometimes the right thing will happen, other times not. 有时正确的事情会发生,而其他时候则不会。
  2. I've never tried to set colors on radio buttons, but it seems likely that they don't have a background. 我从未尝试过在单选按钮上设置颜色,但似乎它们没有背景。

Try setting some other property, like size, just to see if you get a result. 尝试设置其他属性,例如大小,以查看是否获得结果。 If so, then the problem is that radio buttons don't have a background and you'll have to come up with another design. 如果是这样,那么问题就在于单选按钮没有背景,您将不得不提出另一种设计。 If nothing happens, then it's probably the first problem. 如果什么都没有发生,那可能是第一个问题。

You look to have code that is overly and unnecessarily complex. 您希望代码过于复杂和不必要。 Myself, I'd try to "OOP-ify" things to reduce cyclomatic complexity and have 我自己,我会尝试“ OOP化”的东西来减少圈复杂度并

  • A nonGUI Question class, 一个非GUI Question类,
  • with a String field for questionText, 带有一个用于questionText的字符串字段,
  • with a String field for correctAnswer, 带有用于correctAnswer的字符串字段,
  • with a List<String> for incorrectAnswers. 使用List<String>表示不正确的答案。
  • I'd give it a method, say public List<String> getShuffledAnswers() to return a List of Strings with all answers, both correct and incorrect, shuffled in their own list, 我会给它一个方法,例如public List<String> getShuffledAnswers() ,返回一个字符串列表,其中所有答案(正确和不正确)都在其自己的列表中public List<String> getShuffledAnswers()排列,
  • A boolean method to testAnswer(String test) , and return true of the test equals the correctAnswer. 一个布尔方法testAnswer(String test) ,并且返回true的测试等于correctAnswer。

I'd then create a JPanel called QuestionPanel 然后,我将创建一个名为QuestionPanel的JPanel

  • that has a Question field 有一个问题字段
  • that displays the information of a single Question object, including the questionText in the JLabel and all the shuffled answers in JRadioButtons. 显示单个Question对象的信息,包括JLabel中的questionText和JRadioButtons中所有经过改组的答案。
  • It would have methods for getting the selected JRadioButton and for getting the Question, 它会有获取所选JRadioButton和获取Question的方法,
  • And a method for setting making a JRadioButtons background non-opaque when need be, by calling `setOpaque(false) 以及一种通过调用setOpaque(false)来设置使JRadioButtons背景在不透明时不透明的方法
  • And a method that allows the calling code to set the background of select JRadioButtons with a correct answer color or incorrect answer color. 还有一种方法,该方法允许调用代码使用正确的答案颜色或错误的答案颜色设置选择的JRadioButtons的背景。

For example: 例如:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class TestQuestions extends JPanel {
    private static final Question TEST_QUESTION = new Question("Select the Correct Answer", "This answer is correct", 
            "Incorrect Answer 1", "Incorrect Answer 2", "Incorrect Answer 3");
    private QuestionPanel questionPanel = new QuestionPanel();

    public TestQuestions() {
        questionPanel.setQuestion(TEST_QUESTION);
        JButton testAnswerBtn = new JButton(new AbstractAction("Test Answer") {

            @Override
            public void actionPerformed(ActionEvent e) {
                boolean isCorrect = questionPanel.isCorrectAnswerSelected();
                String message = "";
                if (isCorrect) {
                    message = "Correct answer selected!";
                } else {
                    message = "Incorrect answer selected!";                    
                }
                JOptionPane.showMessageDialog(TestQuestions.this, message);
                questionPanel.displayCorrectWrongAnswers();
            }
        });
        JButton clearAllBtn = new JButton(new AbstractAction("Clear All") {

            @Override
            public void actionPerformed(ActionEvent e) {
                questionPanel.clearAll();
                questionPanel.clearSelection();
            }
        });

        JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 5));
        btnPanel.add(testAnswerBtn);
        btnPanel.add(clearAllBtn);

        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        setLayout(new BorderLayout(5, 5));
        add(questionPanel, BorderLayout.CENTER);
        add(btnPanel, BorderLayout.PAGE_END);
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("TestQuestions");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new TestQuestions());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

@SuppressWarnings("serial")
class QuestionPanel extends JPanel {
    private static final Color CORRECT_ANSWER_SELECTED_COLOR = new Color(151, 255, 151);
    private static final Color CORRECT_ANSWER_NOT_SELECTED_COLOR = new Color(151,151, 255);
    private static final Color INCORRECT_ANSWER_SELECTED_COLOR = new Color(255, 151, 151);
    private Question question;
    private JLabel questionTextLabel = new JLabel();
    private List<JRadioButton> answerButtonList = new ArrayList<>();
    private JPanel answerPanel = new JPanel(new GridLayout(0, 1));
    private ButtonGroup buttonGroup = new ButtonGroup();

    public QuestionPanel() {
        setLayout(new BorderLayout());
        add(questionTextLabel, BorderLayout.PAGE_START);
        add(answerPanel, BorderLayout.CENTER);
    }

    public void setQuestion(Question question) {
        this.question = question;
        questionTextLabel.setText(question.getQuestionText());

        answerPanel.removeAll();
        answerButtonList.clear();
        buttonGroup = new ButtonGroup();

        for (String answer : question.getShuffledAnswers()) {
            JRadioButton rBtn = new JRadioButton(answer);
            rBtn.setActionCommand(answer);
            answerButtonList.add(rBtn);
            buttonGroup.add(rBtn);
            answerPanel.add(rBtn);
        }
    }

    public boolean isCorrectAnswerSelected() {
        ButtonModel model = buttonGroup.getSelection();
        if (model == null) {
            return false; // nothing selected
        } else {
            return question.checkAnswer(model.getActionCommand());
        }
    }

    public void clearAll() {
        for (JRadioButton jRadioButton : answerButtonList) {
            jRadioButton.setOpaque(false);
            jRadioButton.setBackground(null);
        }
    }

    public void clearSelection() {
        buttonGroup.clearSelection();
    }

    public void displayCorrectWrongAnswers() {
        clearAll();
        for (JRadioButton jRadioButton : answerButtonList) {
            if (jRadioButton.isSelected()) {
                jRadioButton.setOpaque(true);
                if (question.checkAnswer(jRadioButton.getActionCommand())) {
                    jRadioButton.setBackground(CORRECT_ANSWER_SELECTED_COLOR);
                } else {
                    jRadioButton.setBackground(CORRECT_ANSWER_NOT_SELECTED_COLOR);
                }
            } else if (question.checkAnswer(jRadioButton.getActionCommand())) {
                jRadioButton.setOpaque(true);
                jRadioButton.setBackground(INCORRECT_ANSWER_SELECTED_COLOR);
            }
        }
    }

}

class Question {
    private String questionText;
    private String correctAnswer;
    private List<String> incorrectAnswerList = new ArrayList<>();
    public Question(String questionText, String correctAnswer, String... incorrectAnswers) {
        this.questionText = questionText;
        this.correctAnswer = correctAnswer;
        for (String incorrectAnswer : incorrectAnswers) {
            incorrectAnswerList.add(incorrectAnswer);
        }
    }

    public String getQuestionText() {
        return questionText;
    }

    public String getCorrectAnswer() {
        return correctAnswer;
    }

    public List<String> getShuffledAnswers() {
        List<String> answers = new ArrayList<>(incorrectAnswerList);
        answers.add(correctAnswer);
        Collections.shuffle(answers);
        return answers;
    }

    public boolean checkAnswer(String test) {
        return correctAnswer.equalsIgnoreCase(test);
    }

}

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

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