如何在Java秋千上创建分页?

发布于 2025-01-25 07:32:50 字数 2722 浏览 1 评论 0原文

您好,我正在尝试在Java Swing中创建一个考试系统,一旦用户提供了一个良好的答案并单击下一个按钮,我将尝试从问题上更改为同一框架的问题。

这是我要做的事情的一个示例:

public static int i = 1;

  btnEnter.addActionListener(new ActionListener() {
   @Override
   public void actionPerformed(ActionEvent e) {
                    
         if(e.getSource().equals(btnEnter)) {
              
              frame.setVisible(false);
                                          
              JFrame exam = new JFrame("Exam has started.");
              exam.setVisible(true);
              exam.setLayout(null);
              exam.setExtendedState(JFrame.MAXIMIZED_BOTH);

          try {

            String query = "SELECT * FROM questions WHERE QuestionId = " + i;
            PreparedStatement pstmt = ConnectDb.getConnection().prepareStatement(query);
            ResultSet rslt = pstmt.executeQuery();

            if (rslt.next()) {
               
             // Question label
             JLabel Questionlbl = new JLabel();
             Questionlbl.setForeground(Color.BLACK);
             Questionlbl.setFont(new Font("Arial", Font.PLAIN, 25));
             Questionlbl.setBounds(40, 90, 900, 95); 

              // some more components here

             Questionlbl.setText("Question " + i + " " + rslt.getString(2));

                                                                              
             btnNext.addActionListener(new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {

               if(e.getSource().equals(btnNext)) {
                  
                   //Verify answer, increase counter and update query here...
                                                                           
                  SwingUtilities.updateComponentTreeUI(exam);                                                                               
                  exam.invalidate();                                                                              
                  exam.validate();                                                                                
                  exam.repaint();

               }

            }

            });

           }
          catch (Exception ex) {

             JOptionPane.showMessageDialog(null,ex,"Error",JOptionPane.ERROR_MESSAGE);
             exam.setVisible(true);

           }

        });

从技术上讲,我有一个带有按钮(例如btnenter)的主框架,我可以单击该按钮以访问一个包含从数据库中检索到的MCQ问题的帧。现在,一旦我单击下一个按钮(例如btnnext),我想它应该能够验证答案(基于用户选择的广播按钮),同时每次提供一个好的答案,同时增加计数器或索引由用户,然后单击框架上的按钮。

问题是当我单击下一个按钮时,它仅验证第一个问题的第一个答案,并且在同一Jframe(例如考试)上没有显示下一个问题(RadioButtons)。总而言之,我无法将计数器从下一个按钮增加来更新SQL查询,以便指向下一个记录。

我之前曾尝试使用循环,但徒劳无功。我想也许我做错了。

有人知道如何确切地做到这一点吗?

Hello I am trying to create an examination system in Java swing and I am trying to change from question to question on the same frame once a user provides a good answer and clicks on a Next button.

Here is an example of what I am trying to do:

public static int i = 1;

  btnEnter.addActionListener(new ActionListener() {
   @Override
   public void actionPerformed(ActionEvent e) {
                    
         if(e.getSource().equals(btnEnter)) {
              
              frame.setVisible(false);
                                          
              JFrame exam = new JFrame("Exam has started.");
              exam.setVisible(true);
              exam.setLayout(null);
              exam.setExtendedState(JFrame.MAXIMIZED_BOTH);

          try {

            String query = "SELECT * FROM questions WHERE QuestionId = " + i;
            PreparedStatement pstmt = ConnectDb.getConnection().prepareStatement(query);
            ResultSet rslt = pstmt.executeQuery();

            if (rslt.next()) {
               
             // Question label
             JLabel Questionlbl = new JLabel();
             Questionlbl.setForeground(Color.BLACK);
             Questionlbl.setFont(new Font("Arial", Font.PLAIN, 25));
             Questionlbl.setBounds(40, 90, 900, 95); 

              // some more components here

             Questionlbl.setText("Question " + i + " " + rslt.getString(2));

                                                                              
             btnNext.addActionListener(new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {

               if(e.getSource().equals(btnNext)) {
                  
                   //Verify answer, increase counter and update query here...
                                                                           
                  SwingUtilities.updateComponentTreeUI(exam);                                                                               
                  exam.invalidate();                                                                              
                  exam.validate();                                                                                
                  exam.repaint();

               }

            }

            });

           }
          catch (Exception ex) {

             JOptionPane.showMessageDialog(null,ex,"Error",JOptionPane.ERROR_MESSAGE);
             exam.setVisible(true);

           }

        });

Technically, I had a main frame with a button (e.g btnEnter) which I could click to access another frame containing MCQ questions retrieved from a database. Now, once I click on the Next button (e.g btnNext) I guess it should be able to verify the answer (based on a radio button selected by the user) and at the same time increase the counter or index everytime a good answer is provided by the user and clicks on the button on the frame.

The problem is when I click on the Next button it only verifies the first answer of the first question and it does not display the next question with its options (radiobuttons) on the same Jframe (e.g exam). To sum up, I cannot increase the counter from the next button to update the SQL query so that it points to the next record.

I previously tried to use loops but in vain. I guess maybe I've been doing it wrong.

Does anyone knows how to exactly do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

那一片橙海, 2025-02-01 07:32:50

让我们尝试将代码解除倒计时并使用单个责任原则使用委托和依赖注入之类的东西。

,我们将需要某种“容器”类,以管理一个问题和答案,例如

public interface QuestionAnswer {
    public String getQuestion();
    public String[] getPrompts();
    public void setUserAnswer(int answer);
    public int getUserAnswer();
    public boolean isAnsweredCorrectly();
}

...

首先 ,我们需要某种类似的类,这些类充当我们的数据源,我们可以加载问题

public interface QuestionAnswerDataSource {
    public int getCurrentQuestion();
    public int getQuestionCount() throws QuestionAnswerDataSourceException;
    public boolean hasMoreQuestions();
    public QuestionAnswer getNextQuestion() throws QuestionAnswerDataSourceException;
}

为什么使用接口这样?您会在一分钟内看到为什么,但是首先,让我们创建一个基于SQL数据库的数据源的实现

public class DefaultQuestionAnswer implements QuestionAnswer {
    private String question;
    private String[] prompts;
    private int answer;

    private int userAnswer;

    public DefaultQuestionAnswer(String question, String[] prompts, int answer) {
        this.question = question;
        this.prompts = prompts;
        this.answer = answer;
    }

    @Override
    public String getQuestion() {
        return question;
    }

    @Override
    public String[] getPrompts() {
        return prompts;
    }

    @Override
    public void setUserAnswer(int answer) {
        if (answer >= 0 && answer < getPrompts().length) {
            userAnswer = answer;
        }
    }

    public int getUserAnswer() {
        return userAnswer;
    }

    protected int getAnswer() {
        return answer;
    }

    @Override
    public boolean isAnsweredCorrectly() {
        return getUserAnswer() == getAnswer();
    }
}

public class SQLQustionAnswerDataSource implements QuestionAnswerDataSource {
    private int currentQuestion = 0;
    private int questionCount;
    private Connection connection;

    public SQLQustionAnswerDataSource(Connection connection) throws QuestionAnswerDataSourceException {
        this.connection = connection;
        questionCount = getQuestionCount();
    }

    protected Connection getConnection() {
        return connection;
    }

    public boolean hasMoreQuestions() {
        return currentQuestion + 1 < questionCount;
    }

    @Override
    public int getCurrentQuestion() {
        return currentQuestion;
    }

    @Override
    public int getQuestionCount() throws QuestionAnswerDataSourceException {
        String query = "SELECT count(*) FROM questions";
        int count = 0;
        try (PreparedStatement pstmt = getConnection().prepareStatement(query); ResultSet rslt = pstmt.executeQuery()) {
            if (rslt.next()) {
                count = rslt.getInt(1);
            }
        } catch (SQLException ex) {
            throw new QuestionAnswerDataSourceException(ex);
        }
        return count;
    }

    public QuestionAnswer getNextQuestion() throws QuestionAnswerDataSourceException {
        if (!hasMoreQuestions()) {
            throw new QuestionAnswerDataSourceException("No more questions");
        }
        currentQuestion++;
        String query = "SELECT * FROM questions WHERE QuestionId = ?";
        QuestionAnswer qa = null;
        try (PreparedStatement pstmt = getConnection().prepareStatement(query)) {
            pstmt.setInt(1, getCurrentQuestion());
            try (ResultSet rslt = pstmt.executeQuery()) {
                if (rslt.next()) {
                    // Load the prompts which are presented the user ... ie
                    // multiple choices
                    String prompts[] = new String[0];
                    // Load the index of the correct answer
                    int correctAnswer = 0;
                    qa = new DefaultQuestionAnswer(rslt.getString(2), prompts, correctAnswer);
                } else {
                    throw new QuestionAnswerDataSourceException("Question not found");
                }
            }
        } catch (SQLException ex) {
            throw new QuestionAnswerDataSourceException(ex);
        }
        return qa;
    }
}

:我没有SQL数据库可以测试,因此您必须填写Core详细信息

上面的演示是由SQL数据库支持的问题/答案数据源的基本概念。

关于此事的好处是,任何QUASICE andSwerDataSource是可以预期的,我们可以通过UI来使用它...

public class QuestionAnswerPane extends JPanel {

    private QuestionAnswerDataSource dataSource;
    private QuestionAnswer questionAnswer;

    private JLabel questionNumberLabel;
    private JLabel questionLabel;
    private JPanel promptsPane;
    private JLabel scoreLabel;
    private JButton nextButton;

    private int correctAnswers = 0;

    public QuestionAnswerPane(QuestionAnswerDataSource dataSource) {
        this.dataSource = dataSource;
        setLayout(new GridBagLayout());

        questionNumberLabel = new JLabel("Question #");
        questionLabel = new JLabel("...");
        scoreLabel = new JLabel("0");
        nextButton = new JButton("Next >");

        promptsPane = new JPanel(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.anchor = GridBagConstraints.LINE_START;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(4, 4, 4, 4);

        add(questionNumberLabel, gbc);
        gbc.gridy++;
        add(questionLabel, gbc);
        gbc.gridy++;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weighty = 1;
        add(promptsPane, gbc);

        gbc.gridy++;
        gbc.fill = GridBagConstraints.NONE;
        gbc.weighty = 0;
        gbc.anchor = GridBagConstraints.LINE_END;

        add(nextButton, gbc);
        gbc.gridy++;
        add(scoreLabel, gbc);

        nextQuestion();

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

    public QuestionAnswerDataSource getDataSource() {
        return dataSource;
    }

    protected void nextQuestion() {
        QuestionAnswer currentQA = getCurrentQuestionAnswer();
        if (currentQA != null && currentQA.isAnsweredCorrectly()) {
            correctAnswers++;
            scoreLabel.setText(Integer.toString(correctAnswers));
        }

        if (getDataSource().hasMoreQuestions()) {
            try {
                currentQA = getDataSource().getNextQuestion();
                questionNumberLabel.setText(Integer.toString(getDataSource().getCurrentQuestion()) + "/" + Integer.toString(getDataSource().getQuestionCount()));
                setQuestionAnswer(currentQA);
            } catch (QuestionAnswerDataSourceException ex) {
                ex.printStackTrace();
                JOptionPane.showMessageDialog(this, "Could not get next question");
                setQuestionAnswer(null);
            }
        } else {
            setQuestionAnswer(null);
        }

        nextButton.setEnabled(false);
    }

    protected QuestionAnswer getCurrentQuestionAnswer() {
        return questionAnswer;
    }

    public void setQuestionAnswer(QuestionAnswer questionAnswer) {
        this.questionAnswer = questionAnswer;
        updateQAState();
    }

    protected void updateQAState() {
        QuestionAnswer currentQuestionAnswer = getCurrentQuestionAnswer();
        QuestionAnswerDataSource dateSource = getDataSource();
        promptsPane.removeAll();

        if (currentQuestionAnswer == null) {
            questionNumberLabel.setText(null);
            questionLabel.setText(null);
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            promptsPane.add(new JLabel("The quiz is over"), gbc);

            String message = "You scored " + Integer.toString(correctAnswers);
            try {
                message += " out of " + Integer.toString(dateSource.getQuestionCount());
            } catch (QuestionAnswerDataSourceException exp) {
                exp.printStackTrace();
            }
            promptsPane.add(new JLabel(message), gbc);
        } else {
            questionNumberLabel.setText("Question " + (dateSource.getCurrentQuestion() + 1));
            questionLabel.setText(currentQuestionAnswer.getQuestion());
            ActionListener listener = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (e.getSource() instanceof JRadioButton) {
                        JRadioButton btn = (JRadioButton) e.getSource();
                        Object indexValue = btn.getClientProperty("PromptIndex");
                        if (indexValue instanceof Integer) {
                            int index = (int) indexValue;
                            getCurrentQuestionAnswer().setUserAnswer(index);
                            nextButton.setEnabled(true);
                        }
                    }
                }
            };

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1;
            gbc.fill = gbc.HORIZONTAL;

            ButtonGroup bg = new ButtonGroup();
            String[] prompts = questionAnswer.getPrompts();
            for (int index = 0; index < prompts.length; index++) {
                JRadioButton btn = new JRadioButton(prompts[index]);
                btn.putClientProperty("PromptIndex", index);
                btn.addActionListener(listener);

                promptsPane.add(btn, gbc);
            }
        }
    }
}

核心功能围绕nextQuestionupdateUistate方法。这些负责加载下一个问题,如果存在并相应地更新UI。

现在,正如我说的那样,我没有SQL数据库可以进行测试,因此,我创建了自己的“测试”数据源...

public class TestQuestionAnswerDataSource implements QuestionAnswerDataSource {

    private int currentQuestion = -1;
    private List<QuestionAnswer> questionAnswers;

    public TestQuestionAnswerDataSource() {
        questionAnswers = new ArrayList<>(8);
        questionAnswers.add(new DefaultQuestionAnswer("What is always coming, but never arrives?", new String[]{"Post", "Tomorrow", "Political promises", "Public transport"}, 1));
        questionAnswers.add(new DefaultQuestionAnswer("What can be broken, but is never held?", new String[]{"Light speed", "Your back", "Fingers", "A promise"}, 3));
        questionAnswers.add(new DefaultQuestionAnswer("If a plane crashes on the border between the United States and Canada, where do they bury the survivors?", new String[]{"United States", "Canada", "Under the rug", "Survivors are not buried"}, 3));
        questionAnswers.add(new DefaultQuestionAnswer("Is this a question?", new String[]{"Yes", "No", "Maybe", "Only if this is an answer"}, 3));
    }

    @Override
    public int getCurrentQuestion() {
        return currentQuestion;
    }

    @Override
    public int getQuestionCount() throws QuestionAnswerDataSourceException {
        return questionAnswers.size();
    }

    @Override
    public boolean hasMoreQuestions() {
        return currentQuestion + 1 < questionAnswers.size();
    }

    @Override
    public QuestionAnswer getNextQuestion() throws QuestionAnswerDataSourceException {
        if (!hasMoreQuestions()) {
            throw new QuestionAnswerDataSourceException("No more questions");
        }
        currentQuestion++;
        return questionAnswers.get(currentQuestion);
    }

}

然后可以将其插入UI并允许进行控制的测试工作流程。 。

QuestionAnswerDataSource dataSource = new TestQuestionAnswerDataSource();
JFrame frame = new JFrame();
frame.add(new QuestionAnswerPane(dataSource));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

现在

Let's try and decouple the code and make use of the Single Responsibility Principle and make use things like delegation and dependency injection.

First, we're going to need some kind of "container" class which manages a single question and answer, for example...

public interface QuestionAnswer {
    public String getQuestion();
    public String[] getPrompts();
    public void setUserAnswer(int answer);
    public int getUserAnswer();
    public boolean isAnsweredCorrectly();
}

nb: I'm assuming a multiple choice style question/answer workflow

Now, we need some kind class which acts as our data source, through which we can load questions

public interface QuestionAnswerDataSource {
    public int getCurrentQuestion();
    public int getQuestionCount() throws QuestionAnswerDataSourceException;
    public boolean hasMoreQuestions();
    public QuestionAnswer getNextQuestion() throws QuestionAnswerDataSourceException;
}

Why make use of interface like this? You'll see why in a minute, but first, lets create a SQL database based implementation of the data source

public class DefaultQuestionAnswer implements QuestionAnswer {
    private String question;
    private String[] prompts;
    private int answer;

    private int userAnswer;

    public DefaultQuestionAnswer(String question, String[] prompts, int answer) {
        this.question = question;
        this.prompts = prompts;
        this.answer = answer;
    }

    @Override
    public String getQuestion() {
        return question;
    }

    @Override
    public String[] getPrompts() {
        return prompts;
    }

    @Override
    public void setUserAnswer(int answer) {
        if (answer >= 0 && answer < getPrompts().length) {
            userAnswer = answer;
        }
    }

    public int getUserAnswer() {
        return userAnswer;
    }

    protected int getAnswer() {
        return answer;
    }

    @Override
    public boolean isAnsweredCorrectly() {
        return getUserAnswer() == getAnswer();
    }
}

public class SQLQustionAnswerDataSource implements QuestionAnswerDataSource {
    private int currentQuestion = 0;
    private int questionCount;
    private Connection connection;

    public SQLQustionAnswerDataSource(Connection connection) throws QuestionAnswerDataSourceException {
        this.connection = connection;
        questionCount = getQuestionCount();
    }

    protected Connection getConnection() {
        return connection;
    }

    public boolean hasMoreQuestions() {
        return currentQuestion + 1 < questionCount;
    }

    @Override
    public int getCurrentQuestion() {
        return currentQuestion;
    }

    @Override
    public int getQuestionCount() throws QuestionAnswerDataSourceException {
        String query = "SELECT count(*) FROM questions";
        int count = 0;
        try (PreparedStatement pstmt = getConnection().prepareStatement(query); ResultSet rslt = pstmt.executeQuery()) {
            if (rslt.next()) {
                count = rslt.getInt(1);
            }
        } catch (SQLException ex) {
            throw new QuestionAnswerDataSourceException(ex);
        }
        return count;
    }

    public QuestionAnswer getNextQuestion() throws QuestionAnswerDataSourceException {
        if (!hasMoreQuestions()) {
            throw new QuestionAnswerDataSourceException("No more questions");
        }
        currentQuestion++;
        String query = "SELECT * FROM questions WHERE QuestionId = ?";
        QuestionAnswer qa = null;
        try (PreparedStatement pstmt = getConnection().prepareStatement(query)) {
            pstmt.setInt(1, getCurrentQuestion());
            try (ResultSet rslt = pstmt.executeQuery()) {
                if (rslt.next()) {
                    // Load the prompts which are presented the user ... ie
                    // multiple choices
                    String prompts[] = new String[0];
                    // Load the index of the correct answer
                    int correctAnswer = 0;
                    qa = new DefaultQuestionAnswer(rslt.getString(2), prompts, correctAnswer);
                } else {
                    throw new QuestionAnswerDataSourceException("Question not found");
                }
            }
        } catch (SQLException ex) {
            throw new QuestionAnswerDataSourceException(ex);
        }
        return qa;
    }
}

nb: I don't have a SQL database to test against, so you'll have to fill out the core details

The above demonstrations a basic concept of a question/answer data source which is backed by a SQL database.

The good thing about this is, anywhere QuestionAnswerDataSource is expected, we can make use of it, for example, through the UI...

public class QuestionAnswerPane extends JPanel {

    private QuestionAnswerDataSource dataSource;
    private QuestionAnswer questionAnswer;

    private JLabel questionNumberLabel;
    private JLabel questionLabel;
    private JPanel promptsPane;
    private JLabel scoreLabel;
    private JButton nextButton;

    private int correctAnswers = 0;

    public QuestionAnswerPane(QuestionAnswerDataSource dataSource) {
        this.dataSource = dataSource;
        setLayout(new GridBagLayout());

        questionNumberLabel = new JLabel("Question #");
        questionLabel = new JLabel("...");
        scoreLabel = new JLabel("0");
        nextButton = new JButton("Next >");

        promptsPane = new JPanel(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.anchor = GridBagConstraints.LINE_START;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(4, 4, 4, 4);

        add(questionNumberLabel, gbc);
        gbc.gridy++;
        add(questionLabel, gbc);
        gbc.gridy++;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weighty = 1;
        add(promptsPane, gbc);

        gbc.gridy++;
        gbc.fill = GridBagConstraints.NONE;
        gbc.weighty = 0;
        gbc.anchor = GridBagConstraints.LINE_END;

        add(nextButton, gbc);
        gbc.gridy++;
        add(scoreLabel, gbc);

        nextQuestion();

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

    public QuestionAnswerDataSource getDataSource() {
        return dataSource;
    }

    protected void nextQuestion() {
        QuestionAnswer currentQA = getCurrentQuestionAnswer();
        if (currentQA != null && currentQA.isAnsweredCorrectly()) {
            correctAnswers++;
            scoreLabel.setText(Integer.toString(correctAnswers));
        }

        if (getDataSource().hasMoreQuestions()) {
            try {
                currentQA = getDataSource().getNextQuestion();
                questionNumberLabel.setText(Integer.toString(getDataSource().getCurrentQuestion()) + "/" + Integer.toString(getDataSource().getQuestionCount()));
                setQuestionAnswer(currentQA);
            } catch (QuestionAnswerDataSourceException ex) {
                ex.printStackTrace();
                JOptionPane.showMessageDialog(this, "Could not get next question");
                setQuestionAnswer(null);
            }
        } else {
            setQuestionAnswer(null);
        }

        nextButton.setEnabled(false);
    }

    protected QuestionAnswer getCurrentQuestionAnswer() {
        return questionAnswer;
    }

    public void setQuestionAnswer(QuestionAnswer questionAnswer) {
        this.questionAnswer = questionAnswer;
        updateQAState();
    }

    protected void updateQAState() {
        QuestionAnswer currentQuestionAnswer = getCurrentQuestionAnswer();
        QuestionAnswerDataSource dateSource = getDataSource();
        promptsPane.removeAll();

        if (currentQuestionAnswer == null) {
            questionNumberLabel.setText(null);
            questionLabel.setText(null);
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            promptsPane.add(new JLabel("The quiz is over"), gbc);

            String message = "You scored " + Integer.toString(correctAnswers);
            try {
                message += " out of " + Integer.toString(dateSource.getQuestionCount());
            } catch (QuestionAnswerDataSourceException exp) {
                exp.printStackTrace();
            }
            promptsPane.add(new JLabel(message), gbc);
        } else {
            questionNumberLabel.setText("Question " + (dateSource.getCurrentQuestion() + 1));
            questionLabel.setText(currentQuestionAnswer.getQuestion());
            ActionListener listener = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (e.getSource() instanceof JRadioButton) {
                        JRadioButton btn = (JRadioButton) e.getSource();
                        Object indexValue = btn.getClientProperty("PromptIndex");
                        if (indexValue instanceof Integer) {
                            int index = (int) indexValue;
                            getCurrentQuestionAnswer().setUserAnswer(index);
                            nextButton.setEnabled(true);
                        }
                    }
                }
            };

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1;
            gbc.fill = gbc.HORIZONTAL;

            ButtonGroup bg = new ButtonGroup();
            String[] prompts = questionAnswer.getPrompts();
            for (int index = 0; index < prompts.length; index++) {
                JRadioButton btn = new JRadioButton(prompts[index]);
                btn.putClientProperty("PromptIndex", index);
                btn.addActionListener(listener);

                promptsPane.add(btn, gbc);
            }
        }
    }
}

The core functionality revolves around the nextQuestion and updateUIState methods. These are responsible for loading the next question, if one exists and updating the UI correspondingly.

Now, as I said, I don't have a SQL database to test against, so, instead, I created my own "test" datasource...

public class TestQuestionAnswerDataSource implements QuestionAnswerDataSource {

    private int currentQuestion = -1;
    private List<QuestionAnswer> questionAnswers;

    public TestQuestionAnswerDataSource() {
        questionAnswers = new ArrayList<>(8);
        questionAnswers.add(new DefaultQuestionAnswer("What is always coming, but never arrives?", new String[]{"Post", "Tomorrow", "Political promises", "Public transport"}, 1));
        questionAnswers.add(new DefaultQuestionAnswer("What can be broken, but is never held?", new String[]{"Light speed", "Your back", "Fingers", "A promise"}, 3));
        questionAnswers.add(new DefaultQuestionAnswer("If a plane crashes on the border between the United States and Canada, where do they bury the survivors?", new String[]{"United States", "Canada", "Under the rug", "Survivors are not buried"}, 3));
        questionAnswers.add(new DefaultQuestionAnswer("Is this a question?", new String[]{"Yes", "No", "Maybe", "Only if this is an answer"}, 3));
    }

    @Override
    public int getCurrentQuestion() {
        return currentQuestion;
    }

    @Override
    public int getQuestionCount() throws QuestionAnswerDataSourceException {
        return questionAnswers.size();
    }

    @Override
    public boolean hasMoreQuestions() {
        return currentQuestion + 1 < questionAnswers.size();
    }

    @Override
    public QuestionAnswer getNextQuestion() throws QuestionAnswerDataSourceException {
        if (!hasMoreQuestions()) {
            throw new QuestionAnswerDataSourceException("No more questions");
        }
        currentQuestion++;
        return questionAnswers.get(currentQuestion);
    }

}

This can then be plugged into the UI and allows for a controlled testing workflow...

QuestionAnswerDataSource dataSource = new TestQuestionAnswerDataSource();
JFrame frame = new JFrame();
frame.add(new QuestionAnswerPane(dataSource));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

Now, when you're ready, you can replace TestQuestionAnswerDataSource with SQLQustionAnswerDataSource and the UI should continue to operate without (????) issue

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文