繁体   English   中英

java GUI 中按钮内的按钮

[英]Buttons within buttons in java GUI

我想在 java gui 中的按钮内创建按钮,所以我有一堆按钮,在这些按钮中还有更多按钮,但是每当我尝试为这些按钮创建一个 for 循环时,什么都没有发生。 这是我的代码

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.ImageIcon;
import java.net.URL;
import java.awt.Dimension;
import javax.swing.JOptionPane;
import java.awt.*;
import javax.swing.ImageIcon;
import java.awt.Dimension;


public class Elements extends JPanel implements ActionListener {

  JButton c_one[] = new JButton[4];
  JButton c_two[] = new JButton[4];
  JButton c_three[] = new JButton[4];
  JButton c_four[] = new JButton[4];
  JButton THINGY [] = new JButton[1];

  // buttons for column one row 0
  JButton btn1 = new JButton("Nicosia");
  JButton btn2 = new JButton("Mumbai");
  JButton btn3 = new JButton("Dubait");
  JButton btn4 = new JButton("Romania");
  // buttons for column one row 1
  JButton btna = new JButton("semihemidemisemiquaver ");
  JButton btnb = new JButton("semidemiquaver");
  JButton btnc = new JButton("qaver");
  JButton btnd = new JButton("stop note");
  // button column one row 2
  JButton btne = new JButton("23 ");
  JButton btnf = new JButton("27");
  JButton btng = new JButton("72");
  JButton btnh = new JButton("4");
  // button colooum one row 3
  JButton btnE = new JButton("Pinky");
  JButton btnF = new JButton("Cotten Candy");
  JButton btnG = new JButton("Lady");
  JButton btnH = new JButton(" The Other Tide.");
  // button column two row 0
  JButton btn10 = new JButton("\tEverything about you");
  JButton btn20 = new JButton("All about the thing in the janitors closet");
  JButton btn30 = new JButton("If Dubait  is real or not");
  JButton btn40 = new JButton("12");
  // button column two row 1
  JButton btn00 = new JButton("$63,645, ");
  JButton btn01 = new JButton("$120 000");
  JButton btn02 = new JButton("$15");
  JButton btn03 = new JButton("$64 200");
  // button column two row 2
  JButton btn04 = new JButton("True ");
  JButton btn05 = new JButton("False");
  // button column two row 3
  JButton btnaa = new JButton("\tMr. Penny");
  JButton btnbb = new JButton("Mr. Dime");
  JButton btncc = new JButton("Mr. Nickel");
  JButton btndd = new JButton("Mr.Dollar");
  // button column three row 1
  JButton btn06 = new JButton("\tDr. Harold Shipman");
  JButton btn07 = new JButton("Jesse James.");
  JButton btn08 = new JButton("Pablo Escobar");
  JButton btn09 = new JButton("Al Capone");
  // button column three row 2
  JButton btnaaa = new JButton("\tTrue");
  JButton btnbbb = new JButton("False");
  JButton btnddd = new JButton("Only in the bladder");
  // button column three row 3
  JButton btnEE = new JButton("20% ");
  JButton btnFF = new JButton("6 to 9%,");
  JButton btnGG = new JButton("11-17%");
  JButton btnHH = new JButton("34%");
  // button column three row 4
  JButton question11 = new JButton("Does stretching delay muscle soreness");
  JButton btn12 = new JButton("Stretching before or after exercise does NOT reduce muscle soreness ");
  JButton btn13 = new JButton("Stretching before or after exercise DOES reduce soreness");

  // JPanel.setBackground(Color.YELLOW);
  int PE = 0;
  GridBagConstraints constraints = new GridBagConstraints(); // this variable will set the coordinates of each button
  String icon[] = { "ont.jpg", "oet.jpg", "cm.jpg","riddles.jpg","stw.jpg" };

  public Elements() {

    setLayout(new GridBagLayout());

    constraints.insets = new Insets(5, 5, 5, 5); // borders

    for (int k = 0; k < (c_one.length); k++) {
      c_one[k] = new JButton();
      constraints.gridx = 0;
      ++constraints.gridy;
      c_one[k].setIcon(
          new ImageIcon(new ImageIcon(icon[0]).getImage().getScaledInstance(150, 100, java.awt.Image.SCALE_SMOOTH)));
      add(c_one[k], constraints);
      c_one[k].addActionListener(this);
    }

    constraints.gridy = -1; // setting the gridy to be negative one so the loop will iterate starting at
                            // gridy = 0
    for (int j = 0; j < (c_two.length); j++) {
      c_two[j] = new JButton();
      constraints.gridx = 1;
      ++constraints.gridy;
      c_two[j].setIcon(
          new ImageIcon(new ImageIcon(icon[1]).getImage().getScaledInstance(150, 100, java.awt.Image.SCALE_SMOOTH)));
      add(c_two[j], constraints);
      c_two[j].addActionListener(this);
    }

    // gridy = 0;
    constraints.gridy = -1;

    for (int m = 0; m < (c_three.length); m++) {
      c_three[m] = new JButton();
      constraints.gridx = 2;
      ++constraints.gridy;
      c_three[m].setIcon(
          new ImageIcon(new ImageIcon(icon[2]).getImage().getScaledInstance(150, 100, java.awt.Image.SCALE_SMOOTH)));
      add(c_three[m], constraints);
      c_three[m].addActionListener(this);
    }
   constraints.gridy = -1; // setting the gridy to be negative one so the loop will iterate starting at
                            // gridy = 0
    for (int j = 0; j < (c_four.length); j++) {
   c_four[j] = new JButton();
      constraints.gridx = 3;
      ++constraints.gridy;
      c_four[j].setIcon(
          new ImageIcon(new ImageIcon(icon[3]).getImage().getScaledInstance(150, 100, java.awt.Image.SCALE_SMOOTH)));
      add(c_four[j], constraints);
      c_four[j].addActionListener(this);
    }
       constraints.gridy = -1; // setting the gridy to be negative one so the loop will iterate starting at
                            // gridy = 0
    for (int j = 0; j < (THINGY.length); j++) {
      THINGY[j] = new JButton();
      constraints.gridx = 6;
      ++constraints.gridy;
      THINGY[j].setIcon(
          new ImageIcon(new ImageIcon(icon[4]).getImage().getScaledInstance(150, 100, java.awt.Image.SCALE_SMOOTH)));
      add(THINGY[j], constraints);
      THINGY[j].addActionListener(this);
    }
    JButton pointsEarned = new JButton("Points Earned");
    constraints.fill = GridBagConstraints.VERTICAL;
    constraints.ipady = 20;
    constraints.gridx = 3;
    constraints.gridy = 0;
    constraints.anchor = GridBagConstraints.PAGE_START;
    add(pointsEarned, constraints);
  }

  @Override
  public void actionPerformed(ActionEvent e) {

    if (e.getSource() == c_one[0]) {
      System.out.println(" For 200 points. What is the capital of Cyprus?");
      JFrame frame = new JFrame("200");
      JPanel panel = new JPanel();
      panel.setBounds(55, 55, 400, 200);
      panel.setBackground(Color.BLUE);
      JButton question1 = new JButton("For 200 points. What is the capital of Cyprus?");
      question1.setBounds(50, 100, 160, 80);
      question1.setBackground(Color.ORANGE);
      panel.add(question1);
      btn2.setBounds(50, 100, 80, 30);
      btn2.setBackground(Color.ORANGE);
      btn1.setBounds(50, 100, 80, 30);
      btn1.setBackground(Color.ORANGE);
      panel.add(btn1);
      panel.add(btn2);
      btn3.setBounds(50, 100, 80, 30);
      btn3.setBackground(Color.ORANGE);
      panel.add(btn3);
      btn4.setBounds(50, 100, 80, 30);
      btn4.setBackground(Color.ORANGE);
      panel.add(btn4);
      frame.add(panel);
      frame.setSize(535, 250);
      frame.setLayout(null);
      frame.setVisible(true);

    } else if (e.getSource() == c_one[1]) {
      System.out
          .println("For 400 points. What is a note that is played for half the duration of a thirty second note?");
      JFrame frame2 = new JFrame("400");
      JPanel panel = new JPanel();
      panel.setBounds(55, 55, 400, 200);
      panel.setBackground(Color.BLUE);
      JButton question2 = new JButton("In music, a hundred twenty-eighth note is known as?");
      question2.setBounds(50, 100, 160, 80);
      question2.setBackground(Color.ORANGE);
      panel.add(question2);
      btna.setBounds(50, 100, 80, 30);
      btna.setBackground(Color.ORANGE);
      btnb.setBounds(50, 100, 80, 30);
      btnb.setBackground(Color.ORANGE);
      panel.add(btna);
      panel.add(btnb);
      btnc.setBounds(50, 100, 80, 30);
      btnc.setBackground(Color.ORANGE);
      panel.add(btnc);
      btnd.setBounds(50, 100, 80, 30);
      btnd.setBackground(Color.ORANGE);
      panel.add(btnd);
      frame2.add(panel);
      frame2.setSize(535, 250);
      frame2.setLayout(null);
      frame2.setVisible(true);
    }

    if (e.getSource() == c_one[2]) {
      JFrame frame3 = new JFrame("600");
      JPanel panel = new JPanel();
      panel.setBounds(55, 55, 400, 200);
      panel.setBackground(Color.BLUE);
      JButton question3 = new JButton("How many times was Caesar stabbed by his senators?");
      question3.setBounds(50, 100, 160, 80);
      question3.setBackground(Color.ORANGE);
      panel.add(question3);
      btne.setBounds(50, 100, 80, 30);
      btne.setBackground(Color.ORANGE);
      btnf.setBounds(50, 100, 80, 30);
      btnf.setBackground(Color.ORANGE);
      panel.add(btne);
      panel.add(btnf);
      btng.setBounds(50, 100, 80, 30);
      btng.setBackground(Color.ORANGE);
      panel.add(btng);
      btnh.setBounds(50, 100, 80, 30);
      btnh.setBackground(Color.ORANGE);
      panel.add(btnh);
      frame3.add(panel);
      frame3.setSize(535, 250);
      frame3.setLayout(null);
      frame3.setVisible(true);
    } else if (e.getSource() == c_one[3]) {
      JFrame frame4 = new JFrame("800");
      JPanel panel = new JPanel();
      panel.setBounds(55, 55, 400, 200);
      panel.setBackground(Color.BLUE);
      JButton question4 = new JButton("Louisiana is home to a rare pink dolphin named:");
      question4.setBounds(50, 100, 160, 100);
      question4.setBackground(Color.ORANGE);
      panel.add(question4);
      btnE.setBounds(50, 100, 80, 30);
      btnE.setBackground(Color.ORANGE);
      btnF.setBounds(50, 100, 80, 30);
      btnF.setBackground(Color.ORANGE);
      panel.add(btnE);
      panel.add(btnF);
      btnG.setBounds(50, 100, 80, 30);
      btnG.setBackground(Color.ORANGE);
      panel.add(btnG);
      btnH.setBounds(50, 100, 80, 30);
      btnH.setBackground(Color.ORANGE);
      panel.add(btnH);
      frame4.add(panel);
      frame4.setSize(535, 250);
      frame4.setLayout(null);
      frame4.setVisible(true);
    }
    // array 2
    if (e.getSource() == c_two[0]) {
      JFrame frame = new JFrame("200");
      JPanel panel = new JPanel();
      panel.setBounds(55, 55, 400, 200);
      panel.setBackground(Color.BLUE);
      JButton question1 = new JButton("What do teachers know?");
      question1.setBounds(50, 100, 160, 80);
      question1.setBackground(Color.ORANGE);
      panel.add(question1);
      btn10.setBounds(50, 100, 80, 30);
      btn10.setBackground(Color.ORANGE);
      btn20.setBounds(50, 100, 80, 30);
      btn20.setBackground(Color.ORANGE);
      panel.add(btn10);
      panel.add(btn20);
      btn30.setBounds(50, 100, 80, 30);
      btn30.setBackground(Color.ORANGE);
      panel.add(btn30);
      btn40.setBounds(50, 100, 80, 30);
      btn40.setBackground(Color.ORANGE);
      panel.add(btn40);
      frame.add(panel);
      frame.setSize(535, 250);
      frame.setLayout(null);
      frame.setVisible(true);
    } else if (e.getSource() == c_two[1]) {
      System.out.println("Who is my physics teacher");
      JFrame frame2 = new JFrame("400");
      JPanel panel = new JPanel();
      panel.setBounds(55, 55, 400, 200);
      panel.setBackground(Color.BLUE);
      JButton question2 = new JButton("Who is my physics teacher?");
      question2.setBounds(50, 100, 160, 80);
      question2.setBackground(Color.ORANGE);
      panel.add(question2);
      btnaa.setBounds(50, 100, 80, 30);
      btnaa.setBackground(Color.ORANGE);
      btnbb.setBounds(50, 100, 80, 30);
      btnbb.setBackground(Color.ORANGE);
      panel.add(btnaa);
      panel.add(btnbb);
      btncc.setBounds(50, 100, 80, 30);
      btncc.setBackground(Color.ORANGE);
      panel.add(btncc);
      btndd.setBounds(50, 100, 80, 30);
      btndd.setBackground(Color.ORANGE);
      panel.add(btndd);
      frame2.add(panel);
      frame2.setSize(535, 250);
      frame2.setLayout(null);
      frame2.setVisible(true);

    }
    if (e.getSource() == c_two[2]) {
      JFrame frame4 = new JFrame("600");
      JPanel panel = new JPanel();
      panel.setBounds(55, 55, 400, 200);
      panel.setBackground(Color.BLUE);
      JButton question4 = new JButton("How much do teachers get payed on average");
      question4.setBounds(50, 100, 160, 100);
      question4.setBackground(Color.ORANGE);
      panel.add(question4);
      btn00.setBounds(50, 100, 80, 30);
      btn00.setBackground(Color.ORANGE);
      btn01.setBounds(50, 100, 80, 30);
      btn01.setBackground(Color.ORANGE);
      panel.add(btn00);
      panel.add(btn01);
      btn02.setBounds(50, 100, 80, 30);
      btn02.setBackground(Color.ORANGE);
      panel.add(btn02);
      btn03.setBounds(50, 100, 80, 30);
      btn03.setBackground(Color.ORANGE);
      panel.add(btn03);
      frame4.add(panel);
      frame4.setSize(535, 250);
      frame4.setLayout(null);
      frame4.setVisible(true);

    } else if (e.getSource() == c_two[3]) {
      JFrame frame3 = new JFrame("800");
      JPanel panel = new JPanel();
      panel.setBounds(55, 55, 600, 800);
      panel.setBackground(Color.BLUE);
      JButton question3 = new JButton("For every 10 Canadian teachers, at least 4 have endured violence from students");
      question3.setBounds(50, 100, 160, 180);
      question3.setBackground(Color.ORANGE);
      panel.add(question3);

      btn04.setBounds(50, 100, 80, 30);
      btn04.setBackground(Color.ORANGE);
      btn05.setBounds(50, 100, 80, 30);
      btn05.setBackground(Color.ORANGE);
      panel.add(btn04);
      panel.add(btn05);
      frame3.add(panel);
      frame3.setSize(800, 500);
      frame3.setLayout(null);
      frame3.setVisible(true);
    }
    // array 3
    if (e.getSource() == c_three[0]) {
      JFrame frame = new JFrame("200");
      JPanel panel = new JPanel();
      panel.setBounds(55, 55, 400, 200);
      panel.setBackground(Color.BLUE);
      JButton question1 = new JButton("The most prolific modern serial killer is:");
      question1.setBounds(50, 100, 160, 80);
      question1.setBackground(Color.ORANGE);
      panel.add(question1);
      btn06.setBounds(50, 100, 80, 30);
      btn06.setBackground(Color.ORANGE);
      btn07.setBounds(50, 100, 80, 30);
      btn07.setBackground(Color.ORANGE);
      panel.add(btn06);
      panel.add(btn07);
      btn08.setBounds(50, 100, 80, 30);
      btn08.setBackground(Color.ORANGE);
      panel.add(btn08);
      btn09.setBounds(50, 100, 80, 30);
      btn09.setBackground(Color.ORANGE);
      panel.add(btn09);
      frame.add(panel);
      frame.setSize(535, 250);
      frame.setLayout(null);
      frame.setVisible(true);
    } else if (e.getSource() == c_three[1]) {
      JFrame frame2 = new JFrame("400");
      JPanel panel = new JPanel();
      panel.setBounds(55, 55, 400, 200);
      panel.setBackground(Color.BLUE);
      JButton question2 = new JButton("Urine is sterile\t");
      question2.setBounds(50, 100, 160, 80);
      question2.setBackground(Color.ORANGE);
      panel.add(question2);
      btnaaa.setBounds(50, 100, 80, 30);
      btnaaa.setBackground(Color.ORANGE);
      btnbbb.setBounds(50, 100, 80, 30);
      btnbbb.setBackground(Color.ORANGE);
      panel.add(btnaaa);
      panel.add(btnbbb);
      btnddd.setBounds(50, 100, 80, 30);
      btnddd.setBackground(Color.ORANGE);
      panel.add(btnddd);
      frame2.add(panel);
      frame2.setSize(535, 250);
      frame2.setLayout(null);
      frame2.setVisible(true);

    }
    if (e.getSource() == c_three[2]) {
      JFrame frame4 = new JFrame("600");
      JPanel panel = new JPanel();
      panel.setBounds(55, 55, 400, 200);
      panel.setBackground(Color.BLUE);
      JButton question4 = new JButton("The Amazon rainforest provides ___% of Earth's oxygen. ");
      question4.setBounds(50, 100, 160, 100);
      question4.setBackground(Color.ORANGE);
      panel.add(question4);
      btnEE.setBounds(50, 100, 80, 30);
      btnEE.setBackground(Color.ORANGE);
      btnFF.setBounds(50, 100, 80, 30);
      btnFF.setBackground(Color.ORANGE);
      panel.add(btnEE);
      panel.add(btnFF);
      btnGG.setBounds(50, 100, 80, 30);
      btnGG.setBackground(Color.ORANGE);
      panel.add(btnGG);
      btnHH.setBounds(50, 100, 80, 30);
      btnHH.setBackground(Color.ORANGE);
      panel.add(btnHH);
      frame4.add(panel);
      frame4.setSize(535, 250);
      frame4.setLayout(null);
      frame4.setVisible(true);

    } else if (e.getSource() == c_three[3]) {
      JFrame frame3 = new JFrame("800");
      JPanel panel = new JPanel();
      panel.setBounds(55, 55, 600, 800);
      panel.setBackground(Color.BLUE);
      question11.setBounds(50, 100, 160, 180);
      question11.setBackground(Color.ORANGE);
      panel.add(question11);
      btn12.setBounds(50, 100, 80, 30);
      btn12.setBackground(Color.ORANGE);
      btn13.setBounds(50, 100, 80, 30);
      btn13.setBackground(Color.ORANGE);
      panel.add(btn12);
      panel.add(btn13);
      frame3.add(panel);
      frame3.setSize(800, 300);
      frame3.setLayout(null);
      frame3.setVisible(true);

    }
  }
}

这是我的代码的屏幕截图: 在此处输入图像描述

和按钮的图片在此处输入图像描述

我希望它在单击按钮后说出您的正确或其他内容,例如,在第二个屏幕截图中,有一个标记为 Nicosia 它的 btn1 的按钮,所以我希望 btn 1 这样做,我尝试了 if else 但它不起作用; 我做了 if(e.getSource()==btn1){System.out.println("correct")}

因此,在您的代码上花费了我可能喜欢的更多时间,您问题的基本答案是 - 使用ActionListener ,检查按下了哪个按钮并验证问题的答案。

关于这里,你应该对我尖叫“是的,但是如何?”。 这是您的实际问题开始的地方。

问题是,您已经将数据(问题/选项/答案)耦合到 UI 的距离太远了,这对您来说并不容易。 相反,您需要将数据(问题/选项/答案)与 UI 分离,以便 UI 变得更加愚蠢(并且可重用)并依赖模型/数据来告诉它需要知道的内容。

以下答案使用:

  • 依赖注入
  • 观察者模式
  • 单一责任原则
  • 信息隐藏(AKA 封装)

软件工程原理。 它旨在将“模型”(实际上是模型)与 UI 分离,这样您实际上只需要 3 个面板来呈现所有数据(问题面板被动态重用)

让我们从一些基本数据开始......

public interface Question {
    public int getPoints();
    public String getPrompt();
    public String[] getOptions();
    public boolean isCorrect(String answer);
}

public interface Quiz {
    public int getScore();
    public String[] getCatagories();
    public Question[] getQuestionsForCatagory(String category);
    public boolean didAnswerQuestion(Question question, String answer);
}

注意:可以通过第二个interface或实现“隐藏” Question中的isCorrect方法,但我想当我结束时,你的头已经在旋转了

好的,所以这些定义了我们需要能够构建“测验”的基本的合同要求

应该注意的是,可以在Quiz中添加一个观察者,这可以在分数变化时生成通知,但我将把它留给你

使用这样的interface的目的是隐藏实现细节。 这意味着我们可以从文件(如 XML 和/或 JSON)或数据库甚至某种云服务中获取测验信息。

说到实现,让我们从简单的事情开始

public class DefaultQuiz implements Quiz {

    private Map<String, List<Question>> questions = new HashMap<>();
    private int score;

    public void add(String category, Question[] questions) {
        this.questions.put(category, Arrays.asList(questions));
    }

    @Override
    public boolean didAnswerQuestion(Question question, String answer) {
        if (question.isCorrect(answer)) {
            score += question.getPoints();
            return true;
        }
        
        return false;
    }

    @Override
    public int getScore() {
        return score;
    }

    @Override
    public String[] getCatagories() {
        Set<String> keys = questions.keySet();
        return keys.toArray(new String[keys.size()]);
    }

    @Override
    public Question[] getQuestionsForCatagory(String category) {
        List<Question> values = questions.get(category);
        return values.toArray(new Question[values.size()]);
    }

    public static Quiz build() {
        DefaultQuiz quiz = new DefaultQuiz();
        quiz.add("Oddly Niche Topics", new Question[]{
            new DefaultQuestion(200, "What is the capital of Cyprus?", new String[]{"Nicosia", "Mumbai", "Dubait", "Romania"}, 0),
            new DefaultQuestion(400, "What is a note that is played for half the duration of a thirty second note?", new String[]{"demisemiquaver", "semidemiquaver", "qaver", "stop note"}, 0),
            new DefaultQuestion(600, "How many times was Caesar stabbed by his senators?", new String[]{"23", "27", "72", "4"}, 0),
            new DefaultQuestion(800, "Louisiana is home to a rare pink dolphin named?", new String[]{"Pinky", "Cotten Candy", "Lady", "The Other Tide."}, 0),
        });
        quiz.add("Ominously Enough Teachers", new Question[]{
            new DefaultQuestion(200, "What do teachers know?", new String[]{"Everything about you", "All about the thing in the janitors closet", "If Dubait  is real or not", "12"}, 0),
            new DefaultQuestion(400, "Who is my physics teacher?", new String[]{"Mr. Penny", "Mr. Dime", "Mr. Nickel", "Mr. Dollar"}, 0),
            new DefaultQuestion(600, "How much do teachers get payed on average?", new String[]{"$63,645", "$120,000", "$15", "$64,200"}, 0),
            new DefaultQuestion(800, "For every 10 Canadian teachers, at least 4 have endured violence from students?", new String[]{"True", "False"}, 0),
        });
        quiz.add("Common Miconceptions", new Question[]{
            new DefaultQuestion(200, "The most prolific modern serial killer is?", new String[]{"Everything about you", "All about the thing in the janitors closet", "If Dubait  is real or not", "12"}, 0),
            new DefaultQuestion(400, "Urine is sterile?", new String[]{"Mr. Penny", "Mr. Dime", "Mr. Nickel", "Mr. Dollar"}, 0),
            new DefaultQuestion(600, "The Amazon rainforest provides ___% of Earth's oxygen", new String[]{"$63,645", "$120,000", "$15", "$64,200"}, 0),
            new DefaultQuestion(800, "Apparently this is where the quiz ends", new String[]{"True", "True"}, 0),
        });
        quiz.add("Riddles", new Question[]{
            new DefaultQuestion(200, "What is the meaning of live?", new String[]{"42", "Eat, Drink, Sleep, Repeat", "Grow, get a meaningness job, work till you die", "Parties"}, 0),
            new DefaultQuestion(400, "What's black and white and red all over?", new String[]{"A news paper", "A pengiun with a knife", "A panda with a knife"}, 0),
            new DefaultQuestion(600, "Is this question pointless?", new String[]{"Yes", "No", "Depends on your point of view"}, 0),
            new DefaultQuestion(800, "Why are you stil here?", new String[]{"Pubs are closed", "I want to learn more"}, 0),
        });
        
        return quiz;
    }
}

public class DefaultQuestion implements Question {

    private int points;
    private String prompt;
    private List<String> options;
    private String answer;

    public DefaultQuestion(int points, String prompt, String[] options, int answer) {
        this.points = points;
        this.prompt = prompt;
        this.options = Arrays.asList(options);
        this.answer = options[answer];
    }

    public int getPoints() {
        return points;
    }

    public String getPrompt() {
        return prompt;
    }

    public String[] getOptions() {
        Collections.shuffle(options);
        return options.toArray(new String[options.size()]);
    }

    @Override
    public boolean isCorrect(String answer) {
        return this.answer.equals(answer);
    }

}

所以,这个默认实现有一个简单的build方法,它根据我从你的问题中提取的信息构建一个测验。

需要注意的一点是,每次调用DefaultQuestion#getOptions时,选项都是随机的,所以你知道,实际上必须阅读答案

现在,UI 分为三个部分,“类别窗格”、“问答窗格”和“控制器”

前两个很容易理解,controller 需要更多考虑。

让我们从前两个开始...

public class QuizCategoriesPane extends JPanel {
    
    public static interface Observer {
        public void askQuestion(QuizCategoriesPane source, Quiz quize, Question question);
    }
    
    private Quiz quiz;
    private Observer observer;
    
    public QuizCategoriesPane(Quiz quiz, Observer observer) {
        this.quiz = quiz;
        this.observer = observer;
        String[] categories = quiz.getCatagories();
        
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;
        gbc.gridheight = GridBagConstraints.REMAINDER;
        gbc.insets = new Insets(4, 4, 4, 4);
        gbc.anchor = GridBagConstraints.NORTH;
        
        for (String category : categories) {
            add(makeCategoryPaneFor(category, quiz.getQuestionsForCatagory(category)), gbc);
        }
        
        JButton spinButton = buildButton();
        spinButton.setText("Spin the wheel");
        gbc.fill = GridBagConstraints.HORIZONTAL;
        add(spinButton, gbc);
    }

    public Quiz getQuiz() {
        return quiz;
    }
    
    protected JPanel makeCategoryPaneFor(String category, Question[] questions) {
        JPanel panel = new JPanel(new GridLayout(-1, 1, 4, 4));
        for (Question question : questions) {
            panel.add(makeButtonForQuestion(category, question));
        }
        return panel;
    }
    
    protected JButton makeButtonForQuestion(String category, Question question) {
        JButton btn = buildButton();
        btn.setText(category);
        // I'd prefer to use a Action, but I'm probably already pushing you
        // beyond your limits
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                observer.askQuestion(QuizCategoriesPane.this, getQuiz(), question);
            }
        });
        
        return btn;
    }
    
    protected JButton buildButton() {
        JButton btn = new JButton();
        btn.setContentAreaFilled(false);
        btn.setBorderPainted(false);
        btn.setBackground(Color.BLUE);
        btn.setForeground(Color.YELLOW);  
        btn.setOpaque(true);
        btn.setBorder(new EmptyBorder(32, 32, 32, 32));
        return btn;
    }
    
}

public class QuestionPane extends JPanel {
    
    public static interface Obsever {
        public void didAnswerQuestion(QuestionPane source);
    }
    
    private Quiz quiz;
    private Question question;
    
    private QuestionPane(Quiz quiz, Question question, Obsever obsever) {
        this.question = question;
        setLayout(new BorderLayout());
        
        add(new JLabel("<html>For " + question.getPoints() + " Points<br><h1>" + question.getPrompt() + "</h1></html>"), BorderLayout.NORTH);
        
        JPanel options = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.weightx = 1;
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        
        ButtonGroup bg = new ButtonGroup();
        for (String option : question.getOptions()) {
            JRadioButton button = new JRadioButton("<html><h2>" + option + "</h2></html>");
            button.setActionCommand(option);
            bg.add(button);
            options.add(button, gbc);
        }
        add(options);
        
        JPanel actionPane = new JPanel(new GridBagLayout());
        gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.weightx = 1;
        gbc.anchor = GridBagConstraints.LINE_END;
        
        JButton answerButton = new JButton("Answer");
        answerButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String answer = bg.getSelection().getActionCommand();
                if (quiz.didAnswerQuestion(question, answer)) {
                    JOptionPane.showMessageDialog(QuestionPane.this, "Correct");
                } else {
                    JOptionPane.showMessageDialog(QuestionPane.this, "Incorrect");
                }
                obsever.didAnswerQuestion(QuestionPane.this);
            }
        });
        actionPane.add(answerButton, gbc);
        
        add(actionPane, BorderLayout.SOUTH);
    }
}

“控制器”负责管理“类别”和“问题/答案”UI 的呈现。 因为 UI 相对复杂,它们被分成单独的类,这允许它们只负责完成一项工作,而不会因功能负担过重,而这实际上并不是他们的责任。

controller 可能看起来像……

public class QuizPane extends JPanel {

    private CardLayout cardLayout;
    
    public QuizPane(Quiz quiz) {
        setBorder(new EmptyBorder(16, 16, 16, 16));
        cardLayout = new CardLayout();
        setLayout(cardLayout);
        
        QuizCategoriesPane.Observer quizObserver = new QuizCategoriesPane.Observer() {
            @Override
            public void askQuestion(QuizCategoriesPane source, Quiz quize, Question question) {
                QuestionPane qp = new QuestionPane(quiz, question, new QuestionPane.Obsever() {
                    @Override
                    public void didAnswerQuestion(QuestionPane source) {
                        remove(source);
                        cardLayout.show(QuizPane.this, "categories");
                    }
                });
                add(qp, "question");
                cardLayout.show(QuizPane.this, "question");
            }
        };
        
        add(new QuizCategoriesPane(quiz, quizObserver), "categories");
    }
    
}

它有一个非常基本的职责,向用户显示类别,当用户选择一个类别时,通过观察者通知,显示问题。 当用户回答问题时,通过观察者通知,再次显示类别。

正如我之前所说,有人需要告诉类别窗格分数已经改变,我建议这可以通过Quiz本身的观察者模式来完成,因为这使它独立于所有其他工作流程。 而且,不,我不会这样做。

现在,显然,这需要更多的工作,例如,没有办法跟踪哪些问题已经呈现给用户,还有其他事情需要你弄清楚

可运行示例

在此处输入图像描述

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.ButtonGroup;
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.border.EmptyBorder;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Quiz quiz = DefaultQuiz.build();
                JFrame frame = new JFrame();
                frame.add(new QuizPane(quiz));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static interface Question {
        public int getPoints();
        public String getPrompt();
        public String[] getOptions();
        public boolean isCorrect(String answer);
    }

    public static interface Quiz {
        public int getScore();
        public String[] getCatagories();
        public Question[] getQuestionsForCatagory(String category);
        public boolean didAnswerQuestion(Question question, String answer);
    }

    public static class DefaultQuiz implements Quiz {

        private Map<String, List<Question>> questions = new HashMap<>();
        private int score;

        public void add(String category, Question[] questions) {
            this.questions.put(category, Arrays.asList(questions));
        }

        @Override
        public boolean didAnswerQuestion(Question question, String answer) {
            if (question.isCorrect(answer)) {
                score += question.getPoints();
                return true;
            }

            return false;
        }

        @Override
        public int getScore() {
            return score;
        }

        @Override
        public String[] getCatagories() {
            Set<String> keys = questions.keySet();
            return keys.toArray(new String[keys.size()]);
        }

        @Override
        public Question[] getQuestionsForCatagory(String category) {
            List<Question> values = questions.get(category);
            return values.toArray(new Question[values.size()]);
        }

        public static Quiz build() {
            DefaultQuiz quiz = new DefaultQuiz();
            quiz.add("Oddly Niche Topics", new Question[]{
                new DefaultQuestion(200, "What is the capital of Cyprus?", new String[]{"Nicosia", "Mumbai", "Dubait", "Romania"}, 0),
                new DefaultQuestion(400, "What is a note that is played for half the duration of a thirty second note?", new String[]{"demisemiquaver", "semidemiquaver", "qaver", "stop note"}, 0),
                new DefaultQuestion(600, "How many times was Caesar stabbed by his senators?", new String[]{"23", "27", "72", "4"}, 0),
                new DefaultQuestion(800, "Louisiana is home to a rare pink dolphin named?", new String[]{"Pinky", "Cotten Candy", "Lady", "The Other Tide."}, 0),
            });
            quiz.add("Ominously Enough Teachers", new Question[]{
                new DefaultQuestion(200, "What do teachers know?", new String[]{"Everything about you", "All about the thing in the janitors closet", "If Dubait  is real or not", "12"}, 0),
                new DefaultQuestion(400, "Who is my physics teacher?", new String[]{"Mr. Penny", "Mr. Dime", "Mr. Nickel", "Mr. Dollar"}, 0),
                new DefaultQuestion(600, "How much do teachers get payed on average?", new String[]{"$63,645", "$120,000", "$15", "$64,200"}, 0),
                new DefaultQuestion(800, "For every 10 Canadian teachers, at least 4 have endured violence from students?", new String[]{"True", "False"}, 0),
            });
            quiz.add("Common Miconceptions", new Question[]{
                new DefaultQuestion(200, "The most prolific modern serial killer is?", new String[]{"Everything about you", "All about the thing in the janitors closet", "If Dubait  is real or not", "12"}, 0),
                new DefaultQuestion(400, "Urine is sterile?", new String[]{"Mr. Penny", "Mr. Dime", "Mr. Nickel", "Mr. Dollar"}, 0),
                new DefaultQuestion(600, "The Amazon rainforest provides ___% of Earth's oxygen", new String[]{"$63,645", "$120,000", "$15", "$64,200"}, 0),
                new DefaultQuestion(800, "Apparently this is where the quiz ends", new String[]{"True", "True"}, 0),
            });
            quiz.add("Riddles", new Question[]{
                new DefaultQuestion(200, "What is the meaning of live?", new String[]{"42", "Eat, Drink, Sleep, Repeat", "Grow, get a meaningness job, work till you die", "Parties"}, 0),
                new DefaultQuestion(400, "What's black and white and red all over?", new String[]{"A news paper", "A pengiun with a knife", "A panda with a knife"}, 0),
                new DefaultQuestion(600, "Is this question pointless?", new String[]{"Yes", "No", "Depends on your point of view"}, 0),
                new DefaultQuestion(800, "Why are you stil here?", new String[]{"Pubs are closed", "I want to learn more"}, 0),
            });

            return quiz;
        }
    }

    public static class DefaultQuestion implements Question {

        private int points;
        private String prompt;
        private List<String> options;
        private String answer;

        public DefaultQuestion(int points, String prompt, String[] options, int answer) {
            this.points = points;
            this.prompt = prompt;
            this.options = Arrays.asList(options);
            this.answer = options[answer];
        }

        public int getPoints() {
            return points;
        }

        public String getPrompt() {
            return prompt;
        }

        public String[] getOptions() {
            Collections.shuffle(options);
            return options.toArray(new String[options.size()]);
        }

        @Override
        public boolean isCorrect(String answer) {
            return this.answer.equals(answer);
        }

    }

    public static class QuizPane extends JPanel {

        private CardLayout cardLayout;

        public QuizPane(Quiz quiz) {
            setBorder(new EmptyBorder(16, 16, 16, 16));
            cardLayout = new CardLayout();
            setLayout(cardLayout);

            QuizCategoriesPane.Observer quizObserver = new QuizCategoriesPane.Observer() {
                @Override
                public void askQuestion(QuizCategoriesPane source, Quiz quize, Question question) {
                    QuestionPane qp = new QuestionPane(quiz, question, new QuestionPane.Obsever() {
                        @Override
                        public void didAnswerQuestion(QuestionPane source) {
                            remove(source);
                            cardLayout.show(QuizPane.this, "categories");
                        }
                    });
                    add(qp, "question");
                    cardLayout.show(QuizPane.this, "question");
                }
            };

            add(new QuizCategoriesPane(quiz, quizObserver), "categories");
        }

    }

    public static class QuizCategoriesPane extends JPanel {

        public static interface Observer {
            public void askQuestion(QuizCategoriesPane source, Quiz quize, Question question);
        }

        private Quiz quiz;
        private Observer observer;

        public QuizCategoriesPane(Quiz quiz, Observer observer) {
            this.quiz = quiz;
            this.observer = observer;
            String[] categories = quiz.getCatagories();

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.fill = GridBagConstraints.BOTH;
            gbc.gridheight = GridBagConstraints.REMAINDER;
            gbc.insets = new Insets(4, 4, 4, 4);
            gbc.anchor = GridBagConstraints.NORTH;

            for (String category : categories) {
                add(makeCategoryPaneFor(category, quiz.getQuestionsForCatagory(category)), gbc);
            }

            JButton spinButton = buildButton();
            spinButton.setText("Spin the wheel");
            gbc.fill = GridBagConstraints.HORIZONTAL;
            add(spinButton, gbc);
        }

        public Quiz getQuiz() {
            return quiz;
        }

        protected JPanel makeCategoryPaneFor(String category, Question[] questions) {
            JPanel panel = new JPanel(new GridLayout(-1, 1, 4, 4));
            for (Question question : questions) {
                panel.add(makeButtonForQuestion(category, question));
            }
            return panel;
        }

        protected JButton makeButtonForQuestion(String category, Question question) {
            JButton btn = buildButton();
            btn.setText(category);
            // I'd prefer to use a Action, but I'm probably already pushing you
            // beyond your limits
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    observer.askQuestion(QuizCategoriesPane.this, getQuiz(), question);
                }
            });

            return btn;
        }

        protected JButton buildButton() {
            JButton btn = new JButton();
            btn.setContentAreaFilled(false);
            btn.setBorderPainted(false);
            btn.setBackground(Color.BLUE);
            btn.setForeground(Color.YELLOW);  
            btn.setOpaque(true);
            btn.setBorder(new EmptyBorder(32, 32, 32, 32));
            return btn;
        }

    }

    public static class QuestionPane extends JPanel {

        public static interface Obsever {
            public void didAnswerQuestion(QuestionPane source);
        }

        private Quiz quiz;
        private Question question;

        private QuestionPane(Quiz quiz, Question question, Obsever obsever) {
            this.question = question;
            setLayout(new BorderLayout());

            add(new JLabel("<html>For " + question.getPoints() + " Points<br><h1>" + question.getPrompt() + "</h1></html>"), BorderLayout.NORTH);

            JPanel options = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1;
            gbc.anchor = GridBagConstraints.FIRST_LINE_START;

            ButtonGroup bg = new ButtonGroup();
            for (String option : question.getOptions()) {
                JRadioButton button = new JRadioButton("<html><h2>" + option + "</h2></html>");
                button.setActionCommand(option);
                bg.add(button);
                options.add(button, gbc);
            }
            add(options);

            JPanel actionPane = new JPanel(new GridBagLayout());
            gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1;
            gbc.anchor = GridBagConstraints.LINE_END;

            JButton answerButton = new JButton("Answer");
            answerButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String answer = bg.getSelection().getActionCommand();
                    if (quiz.didAnswerQuestion(question, answer)) {
                        JOptionPane.showMessageDialog(QuestionPane.this, "Correct");
                    } else {
                        JOptionPane.showMessageDialog(QuestionPane.this, "Incorrect");
                    }
                    obsever.didAnswerQuestion(QuestionPane.this);
                }
            });
            actionPane.add(answerButton, gbc);

            add(actionPane, BorderLayout.SOUTH);
        }
    }
}

暂无
暂无

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

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