質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.35%

二択問題の作り方について質問です。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,343

Hanamarunanngo

score 11

以下の二択問題のプログラムについて質問です。
これは、swingを用いた二択問題です。将来的には四択問題にするつもりです。
プログラミング初心者なため、とても回りくどい書き方ですみません。
これのプログラムをもっと簡潔に書きたいのですが、どのようにすればいいのか分かりません。
何かアドバイスをください。よろしくお願いします。

import javax.swing.*;
import java.awt.CardLayout;
import java.awt.BorderLayout;
import java.awt.event.*;

public class sample extends JFrame implements ActionListener{

  JPanel cardPanel;
  CardLayout layout;
  int n = 0;

  public static void main(String[] args){
    sample frame = new sample();

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setBounds(10, 10, 300, 200);
    frame.setTitle("タイトル");
    frame.setVisible(true);
  }

  sample(){
    /* 問題カード1 */
    JPanel card1 = new JPanel();
    card1.add(new JLabel("質問1"));
    JButton btn1 = new JButton("btn1");
    card1.add(btn1);
    JButton btn2 = new JButton("btn2");
    card1.add(btn2);

    /* 問題カード2 */
    JPanel card2 = new JPanel();
    card2.add(new JLabel("質問2"));
    JButton btn3 = new JButton("btn3");
    card2.add(btn3);
    JButton btn4 = new JButton("btn4");
    card2.add(btn4);

    /* 問題カード3 */
    JPanel card3 = new JPanel();
    card3.add(new JLabel("質問3"));
    JButton btn5 = new JButton("btn5");
    card3.add(btn5);
    JButton btn6 = new JButton("btn6");
    card3.add(btn6);



    /* ボタンアクション*/
    btn1.addActionListener(this);
    btn1.setActionCommand("btn1");
    btn2.addActionListener(this);
    btn2.setActionCommand("btn2");
    btn3.addActionListener(this);
    btn3.setActionCommand("btn3");
    btn4.addActionListener(this);
    btn4.setActionCommand("btn4");
    btn5.addActionListener(this);
    btn5.setActionCommand("btn5");
    btn6.addActionListener(this);
    btn6.setActionCommand("btn6");

    cardPanel = new JPanel();
    layout = new CardLayout();
    cardPanel.setLayout(layout);

    cardPanel.add(card1, "btn1");
    cardPanel.add(card1, "btn2");
    cardPanel.add(card2, "btn3");
    cardPanel.add(card2, "btn4");
    cardPanel.add(card3, "btn5");
    cardPanel.add(card3, "btn6");
    cardPanel.add(card1, "質問1");
    cardPanel.add(card2, "質問2");
    cardPanel.add(card3, "質問3");


    /* カード移動用ボタン(前へ,次へ) */
    JButton prevButton = new JButton("前へ");
    prevButton.addActionListener(this);
    prevButton.setActionCommand("前へ");

    JButton nextButton = new JButton("次へ");
    nextButton.addActionListener(this);
    nextButton.setActionCommand("次へ");

    JPanel btnPanel = new JPanel();
    btnPanel.add(prevButton);
    btnPanel.add(nextButton);

    getContentPane().add(cardPanel, BorderLayout.CENTER);
    getContentPane().add(btnPanel, BorderLayout.PAGE_END);
  }

  public void actionPerformed(ActionEvent e){
    String cmd = e.getActionCommand();

    /* 点数 */
    if (cmd.equals("btn1")){
      n += 1;
    }else if (cmd.equals("btn2")){
      n = n;
    }
    if (cmd.equals("btn4")){
      n += 1;
    }else if (cmd.equals("btn3")){
      n = n;
    }
    if (cmd.equals("btn5")){
      n += 1;
    }else if (cmd.equals("btn6")){
      n = n;
    }

    /* 解説 */
    if (cmd.equals("btn1")||cmd.equals("btn2")){
      String s=Integer.toString(n); 
      JLabel label1 = new JLabel("解説1,正解数は"+s+"問です。");
      JOptionPane.showMessageDialog(this, label1);
    }
    if (cmd.equals("btn3")||cmd.equals("btn4")){
      String s=Integer.toString(n); 
      JLabel label2 = new JLabel("解説2,正解数は"+s+"問です。");
      JOptionPane.showMessageDialog(this, label2);
    }
    if (cmd.equals("btn5")||cmd.equals("btn6")){
      String s=Integer.toString(n); 
      JLabel label3 = new JLabel("解説3,正解数は"+s+"問です。これで問題は終了です。");
      JOptionPane.showMessageDialog(this, label3);
    }


    /* カード移動用ボタン(前と次) */
    if (cmd.equals("前へ")){
      layout.previous(cardPanel);
    }else if (cmd.equals("次へ")){
      layout.next(cardPanel);
    }
  }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • LouiS0616

    2017/08/16 21:45

    コードはバッククオート三つで括ってください。よくわからない場合は、マークダウン記法について調べてみてください。これをしているかどうかで、回答の量と質が変わってきます。

    キャンセル

回答 1

checkベストアンサー

0

とりあえず、次の点の改善をお勧めします。

  • リスナークラスを複数用意すること
    『次へ』『前へ』を処理するクラスと、答えの選択を処理するクラスは分割すべきです。
    一概に言えないことではありますが、actionPerformed内での条件分岐は避けたいところです。
  • 配列やリストを利用すること
    それぞれの問題に対する選択肢は、[問題数][選択肢数]の配列で管理できます。
    配列にすることで、似たような処理を簡潔に書くことができます。
    また、答えも配列で管理するようにすれば、問題を追加したときも柔軟に対応できるでしょう。
    (私の例では独自クラスの配列としています)

適当ですが、作ってみました。

public class Question {
    private String question;
    private String[] answerList;
    private int answerNum;
    private String comment;

    public Question(String question, String[] answerList, int answerNum, String comment) {
        this.question = question;
        this.answerList = answerList;
        this.answerNum = answerNum;
        this.comment = comment;
    }

    public String getQuestion() {
        return question;
    }
    public String[] getAnswerList() {
        return answerList;
    }
    public String getComment() {
        return comment;
    }

    public boolean isCorrect(String answer) {
        return answer.equals(answerList[answerNum]);
    }
}
import javax.swing.*;
import java.awt.CardLayout;
import java.awt.BorderLayout;
import java.awt.event.*;

public class Sample extends JFrame{
    private int correctedNum = 0;
    private int answeredNum = 0;

    private final Question[] questions = {
            new Question("質問1", new String[]{"選択肢1", "選択肢2"}, 0, "解説1"),
            new Question("質問2", new String[]{"選択肢3", "選択肢4"}, 1, "解説2"),
            new Question("質問3", new String[]{"選択肢5", "選択肢6"}, 0, "解説3"),
    };

    public static void main(String[] args){
        new Sample("タイトル");
    }

    private Sample(String title){
        super(title);

        //
        // CardPanel
        JPanel cardPanel = new JPanel();
        CardLayout layout = new CardLayout();
        cardPanel.setLayout(layout);

        for(Question question: questions) {
            JPanel questionCard = new JPanel();
            questionCard.add(new JLabel(question.getQuestion()));

            AnswerChecker answerChecker = new AnswerChecker(question);
            for(String answer: question.getAnswerList()) {
                JButton button = new JButton(answer);
                questionCard.add(button);
                button.addActionListener(answerChecker);
            }

            cardPanel.add(questionCard);
        }
        getContentPane().add(cardPanel, BorderLayout.CENTER);
        QuestionChooser questionChooser = new QuestionChooser(layout, cardPanel);

        //
        // CtrlPanel
        JPanel ctrlPanel = new JPanel();

        JButton prevButton = new JButton("前へ");
        prevButton.addActionListener(questionChooser);
        prevButton.setActionCommand("previous");

        JButton nextButton = new JButton("次へ");
        nextButton.addActionListener(questionChooser);
        nextButton.setActionCommand("next");

        ctrlPanel.add(prevButton);
        ctrlPanel.add(nextButton);

        //
        // FrameLayout
        add(ctrlPanel, BorderLayout.PAGE_END);

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setBounds(10, 10, 300, 200);
        setVisible(true);
    }

    private class QuestionChooser implements ActionListener {
        private CardLayout layout;
        private JPanel panel;

        QuestionChooser(CardLayout layout, JPanel panel) {
            this.layout = layout;
            this.panel = panel;
        }

        public void actionPerformed(ActionEvent e) {
            String cmd = e.getActionCommand();

            if( cmd.equals("next") ) {
                layout.next(panel);
            }
            else if( cmd.equals("previous")) {
                layout.previous(panel);
            }
        }
    }

    private class AnswerChecker implements ActionListener {
        private Question question;

        AnswerChecker(Question question) {
            this.question = question;
        }

        public void actionPerformed(ActionEvent e) {
            ++answeredNum;

            String selectedAnswer = ((JButton)e.getSource()).getText();
            if(question.isCorrect(selectedAnswer)) {
                ++correctedNum;
            }

            String comment = question.getComment() + "正答数は" + correctedNum + "/" + answeredNum + "です";
            showMessage(comment);
        }

        private void showMessage(String str) {
            JOptionPane.showMessageDialog(null, new JLabel(str));
        }
    }
}

構造は突貫ですし、命名はいい加減です。参考程度にお願いします。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/18 03:28

    こんにちは。返信遅くなりすみません。すばらしい解答ありがとうございます。参考にさせていただきます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る