我正在编写一个软件,可以对用户进行音符测验,尽管我会省略音乐细节。由于我的程序非常大,我编写了一个单独的程序作为概念证明并解决我的问题。
简单的程序应该像这样工作:在main方法中,随机选择一个数字(1或2)。该数字被设置为 GUI 中 jlabel 中的文本。然后,用户按下两个数字按钮之一。然后,用户必须按另一个j按钮以确认其选择。主要方法比较问答变量。如果数字相等,jlabel 中的文本将更改为"正确"。否则,它将更改为"不正确"。然后,用户必须按第四个按钮才能获得下一个问题。然后重复该方法,用户应该能够根据需要进行任意数量的练习。
我的测试类,其中包含我的主方法
package test;
import java.util.Random;
public class Test {
protected static int question;
protected static int answer;
protected static boolean next = false;
protected static boolean sure = false;
protected static boolean exit = false;
protected static Random random = new Random();
public static void main(String[] args) {
GUI.gUI();
while(!exit){//while
question = random.nextInt(2) + 1;
GUI.lblNewLabel.setText("" + question);
while(!next){//next
while(!sure) {//sure
answer = Other.other();
}//sure
sure = false;
if(question == answer) {
GUI.lblNewLabel.setText("correct");
}
else {
GUI.lblNewLabel.setText("incorrect");
}
}//next
next = false;
}//exit
}
}
我的图形用户界面
package test;
import java.awt.EventQueue;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.event.*;
public class GUI extends JFrame {
private static final long serialVersionUID = 1L;
protected static int answerGUI;
protected static JLabel lblNewLabel = new JLabel("New label");
private JPanel contentPane;
/**
* Launch the application.
*/
public static void gUI() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
GUI frame = new GUI();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public GUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
BTNListener btnlistener = new BTNListener();
lblNewLabel.setBounds(39, 25, 46, 14);
contentPane.add(lblNewLabel);
JButton btn1 = new JButton("No. 1");
btn1.setBounds(39, 158, 89, 23);
contentPane.add(btn1);
btn1.addActionListener(btnlistener);
JButton btn2 = new JButton("No. 2");
btn2.setBounds(157, 157, 89, 23);
contentPane.add(btn2);
btn2.addActionListener(btnlistener);
JButton btnAreYouSure = new JButton("Are you sure?");
btnAreYouSure.setBounds(38, 197, 99, 23);
contentPane.add(btnAreYouSure);
btnAreYouSure.addActionListener(btnlistener);
JButton btnNext = new JButton("Next");
btnNext.setBounds(159, 197, 89, 23);
contentPane.add(btnNext);
btnNext.addActionListener(btnlistener);
JButton btnExit = new JButton("Exit");
btnExit.setBounds(269, 198, 89, 23);
contentPane.add(btnExit);
btnExit.addActionListener(btnlistener);
}
protected class BTNListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand() == "No. 1") {
Other.answer = 1;
}
else if(e.getActionCommand() == "No. 2") {
Other.answer = 2;
}
if(e.getActionCommand() == "Are you sure?") {
Test.sure = true;
}
if(e.getActionCommand() == "Next") {
Test.next = true;
}
if(e.getActionCommand() == "Exit") {
Test.exit = true;
}
}
}
}
我的其他课程
package test;
public class Other {
protected static int answer;
protected static int other() {
return answer;
}
}
我决定我需要另一个类,所以 main 方法有另一个方法可以作为序列的一部分调用,尽管我想这个方法可以在 GUI 中编写。
我包含确认按钮的原因之一是,在第一次传递之后,Other 类中的答案变量已经有一个值,因此在第二次传递时,此值会立即传递给 Test 中的答案变量,并且用户无法更改该值。
由于程序是现在编写的,jlabel 显示问题值,并且按钮按下似乎都没有做任何事情。我尝试使用do...而循环相反,它在无限循环并且不允许用户回答之前工作了一次。
发布的代码有太多问题,所以我完全重写了它。 为了实现它,我使用了简化的MVC模式。
为方便和简单起见,可以将以下代码复制粘贴到一个名为 MVC_Controller.java 的文件中并运行。 请注意代码中的许多注释。
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Label;
import java.util.Random;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
/*The controller process the user requests.
* It listeners that are called when the View detects a user interaction.
* Based on the user action, the Controller calls methods in the View and Model
* to accomplish the requested action.
*/
class MVC_Controller{
private MVC_Model model;
private MVC_View view;
MVC_Controller(MVC_View view,MVC_Model model) {
this.model=model;
this.view=view;
//observe view buttons
view.getConfirmationButton().addActionListener(e -> confirmationButtonPressed());
view.getNextButton().addActionListener(e -> setNewQuestion());
setNewQuestion(); //initialize view with a question
view.setVisible();
}
//respond to confirmation button click
private void confirmationButtonPressed() {
model.setAnswer(view.getAnswer());
if(model.isCorrectAnswer()) {
view.setInfo("Well done !");
}else {
view.setInfo("Wrong answer !");
}
}
//respond to next button click
private void setNewQuestion() {
view.clear();
model.newQuestion();
view.setInfo("Select button ");
view.updateFromModel();
}
/*In practice you would probably want to have this in a
* Separate Main class
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
MVC_Model model = new MVC_Model();
MVC_View view = new MVC_View(model);
new MVC_Controller(view, model);
}
});
}
}
/*Model contains the information for the view and information from the view
* as well as the logic.
* The model is independent of the user interface.
*/
class MVC_Model {
private int question,answer = 0;
private Random rnd = new Random();
MVC_Model() {
newQuestion();
}
//set question to 1 or 2.
void newQuestion() {
question = (rnd.nextInt(99) > 49) ? 2 : 1 ;
answer = 0;
}
int getQuestion() { return question;}
int getAnswer() { return answer; }
void setQuestion(int question) { this.question = question; }
void setAnswer(int answer) { this.answer = answer; }
boolean isCorrectAnswer() { return question == answer; }
}
/*View only contains the user interface part*/
class MVC_View {
private MVC_Model model;
private JTextField question = new JTextField(2);
private JToggleButton button1 = new JToggleButton("1"); //on - off toggle buttons
private JToggleButton button2 = new JToggleButton("2");
private JButton confirm = new JButton("Confirm");
private JButton next = new JButton("Next");
private JLabel info = new JLabel();
private JFrame frame;
MVC_View(MVC_Model model){
this.model = model;
ButtonGroup bGroup = new ButtonGroup(); //add buttons to group so
bGroup.add(button1);bGroup.add(button2); //only one can be selected
JPanel topPanel = new JPanel(); //uses FlowLayout by default. Do not use null layouts
//add components to top panel
topPanel.add(new Label("Question: ")); //add a label to indicate question
topPanel.add(question); topPanel.add(button1); topPanel.add(button2);
topPanel.add(confirm); topPanel.add(next);
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0)); //set layout manager to left align
bottomPanel.add(new Label("Information: ")); //add a label to indicate information
bottomPanel.add(info);
frame = new JFrame("MVC Model Demo");
frame.add(topPanel, BorderLayout.NORTH); //uses BorderLayout by default
frame.add(bottomPanel, BorderLayout.SOUTH); //uses BorderLayout by default
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
}
void setInfo(String text) { info.setText(text); }
JButton getConfirmationButton() { return confirm; }
JButton getNextButton() { return next; }
int getAnswer() {
if(button1.isSelected()) {
return 1;
}else if (button2.isSelected()){
return 2;
}
return 0; //no button is selected
}
//rest all gui
void clear() {
button1.setSelected(false);
button2.setSelected(false);
question.setText("");
info.setText("");
}
//update view from model
void updateFromModel() {
question.setText(String.valueOf(model.getQuestion()));
}
void setVisible() { frame.setVisible(true); }
}