[英]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 变得更加愚蠢(并且可重用)并依赖模型/数据来告诉它需要知道的内容。
以下答案使用:
软件工程原理。 它旨在将“模型”(实际上是模型)与 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.