工程地址:
https://coding.net/u/jx8zjs/p/paperOne/git
ssh://git@git.coding.net:jx8zjs/paperOne.git
需求:
1.GUI支持:用户界面新增支持 Windows GUI,同时保留原有命令行下所有功能。
2.配置文件:提供用户可用文本编辑器修改的配置文件,在其中包括用户名、当前难度、总答题数、答错题数、答对题数。
3.错题本:可回放做错的题目,提供再次练习的机会/删除特定错题。
设计:
1.GUI编程可以使用windowbuilder辅助编写;
2.配置文件可以在程序运行时读入并初始化设定,并且在用户答题之后点击按钮同时将错题记录下来并保存到文件中;
3.回放错题时,将错题保存在arraylist中,删除时根据指定删除特定行,并在用户提交时将新的错题集覆盖写入错题本中。
运行:
由于提供了图形化界面,操作提示更加通俗易懂,具体效果会在后面结果中展示。需要注意的是,答题结果以及部分错误提示会在窗口正下方展示,而不是以弹窗的方式。
代码:
1.初始参数声明:主要定义了窗口、问题、答案等。
1 private JFrame frmPaperone; 2 private JTextField textFieldNum; 3 4 QuestionGen qg = new QuestionGen(); 5 6 ArrayList<String[]> questions = new ArrayList<String[]>(); 7 ArrayList<JTextField> answers = new ArrayList<JTextField>(); 8 9 public MainWindow() { 10 initialize(); 11 }
2.设置窗口:包括标签、按钮、输入框、排列方式等等。
1 frmPaperone = new JFrame(); 2 frmPaperone.setTitle("PaperOne出题助手"); 3 frmPaperone.setBounds(100, 100, 761, 496); 4 frmPaperone.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 5 frmPaperone.getContentPane().setLayout(new BorderLayout(0, 0)); 6 JPanel panelConfig = new JPanel(); 7 frmPaperone.getContentPane().add(panelConfig, BorderLayout.NORTH); 8 JLabel lblNewLabel = new JLabel("出题难度"); 9 panelConfig.add(lblNewLabel); 10 JComboBox<String> comboBoxComplex = new JComboBox<String>(); 11 comboBoxComplex.setModel(new DefaultComboBoxModel<String>(new String[] { "简单", "普通", "中等", "复杂" })); 12 panelConfig.add(comboBoxComplex); 13 JLabel label = new JLabel("出题数量"); 14 panelConfig.add(label); 15 textFieldNum = new JTextField(); 16 textFieldNum.setText("10"); 17 panelConfig.add(textFieldNum); 18 textFieldNum.setColumns(10); 19 JLabel label_1 = new JLabel("运行模式"); 20 panelConfig.add(label_1); 21 JComboBox<String> comboBoxMode = new JComboBox<String>(); 22 comboBoxMode.setModel(new DefaultComboBoxModel<String>(new String[] { "答题模式", "打印模式" })); 23 panelConfig.add(comboBoxMode); 24 JLabel label_2 = new JLabel("答题时间"); 25 panelConfig.add(label_2); 26 JSpinner spinnerMinute = new JSpinner(); 27 panelConfig.add(spinnerMinute); 28 JLabel label_3 = new JLabel("分"); 29 panelConfig.add(label_3); 30 JSpinner spinnerSecond = new JSpinner(); 31 panelConfig.add(spinnerSecond); 32 JLabel label_4 = new JLabel("秒"); 33 panelConfig.add(label_4); 34 JPanel panelStatus = new JPanel(); 35 frmPaperone.getContentPane().add(panelStatus, BorderLayout.SOUTH); 36 JLabel messageBar = new JLabel(" "); 37 panelStatus.add(messageBar); 38 JPanel panelMain = new JPanel(); 39 frmPaperone.getContentPane().add(panelMain, BorderLayout.CENTER); 40 panelMain.setLayout(new MigLayout("", "[][grow]", "[][]"));
3.设置按钮动作:点击“开始出题”按钮之后要进行的操作,包括检测用户输入的设置是否合法、根据用户选择的难度出题、检测用户选择的模式(答题模式或打印模式)、答题模式下判断对错 等等。值得注意的是,在点击按钮时需要清空原本遗留的数据,比如Arraylist、JPanel等。
1 JButton buttonStart = new JButton("开始出题"); 2 buttonStart.addMouseListener(new MouseAdapter() { 3 public void mouseClicked(MouseEvent event) { 4 frmPaperone.repaint(); 5 messageBar.setText(""); 6 String numstr = textFieldNum.getText(); 7 int complex = comboBoxComplex.getSelectedIndex(); 8 int mode = comboBoxMode.getSelectedIndex(); 9 panelMain.removeAll(); //初始化 10 questions.clear(); 11 answers.clear(); 12 if (isNumeric(numstr)) { //后续操作均是在用户输入合法条件下进行的 13 int num = Integer.parseInt(numstr); 14 for (int n = 0; n < num; n++) { 15 String[] question = new String[2]; 16 switch (complex) { //判断用户选择的出题难度 17 case 0: { 18 question[0] = qg.generateSimpleQuestion(); 19 break; 20 } 21 case 1: { 22 question[0] = qg.generateCommonQuestion(); 23 break; 24 } 25 case 2: { 26 question[0] = qg.generateMediumQuestion(); 27 break; 28 } 29 case 3: { 30 question[0] = qg.generateComplexQuestion(); 31 break; 32 } 33 default: 34 } 35 try { 36 question[0] = "Question " + (n + 1) + " :" + question[0]; 37 question[1] = qg.answer; 38 questions.add(question); 39 } catch (Exception e) { 40 e.printStackTrace(); 41 } 42 } 43 switch (mode) { //判断用户所选的模式 44 case 0: { 45 for (int m = 0; m < num; m++) { 46 JLabel questionBar = new JLabel(" "); 47 panelMain.add(questionBar, "cell 0 " + m + ",alignx trailing"); 48 JTextField answerBar = new JTextField("", 20); 49 panelMain.add(answerBar, "cell 1 " + m + " ,alignx trailing"); 50 questionBar.setText(questions.get(m)[0]); 51 answers.add(answerBar); 52 } 53 JButton saveButton = new JButton("保存到错题本"); 54 saveButton.addMouseListener(new MouseAdapter() { 55 public void mouseClicked(MouseEvent event) { 56 57 } 58 }); 59 saveButton.setVisible(false); 60 panelStatus.add(saveButton); 61 62 JButton sudmitButton = new JButton("提交"); 63 sudmitButton.addMouseListener(new MouseAdapter() { //判断对错 64 public void mouseClicked(MouseEvent event) { 65 String faultQuestion = new String(""); 66 String correctAnswer = new String(""); 67 for (int s = 0; s < num; s++) { 68 String answer = new String(); 69 answer = answers.get(s).getText(); 70 if (!answer.trim().equals(questions.get(s)[1])) { 71 faultQuestion += (" " + (s + 1)); 72 correctAnswer += (" " + questions.get(s)[1]); 73 } 74 System.out.println(answers.get(s).getText()); 75 } 76 if (faultQuestion.isEmpty() || faultQuestion == "") { 77 messageBar.setText("恭喜你全部答对啦!真是个天才!"); 78 saveButton.setVisible(false); 79 } else { 80 messageBar.setText("很遗憾,你的第" + faultQuestion + "题答错了.正确答案分别是:" + correctAnswer); 81 saveButton.setVisible(true); 82 } 83 } 84 }); 85 panelMain.add(sudmitButton); 86 87 88 break; 89 } 90 case 1: { 91 for (int m = 0; m < num; m++) { 92 JLabel questionBar = new JLabel(" "); 93 panelMain.add(questionBar); 94 questionBar.setText(questions.get(m)[0] + "=" + questions.get(m)[1]); 95 } 96 break; 97 } 98 default: 99 } 100 } else { 101 messageBar.setText("请输入数字!"); 102 } 103 } 104 }); 105 panelConfig.add(buttonStart); 106 }
4.判断输入合法性的函数。
1 public static boolean isNumeric(String str) { 2 Pattern pattern = Pattern.compile("[0-9]*"); 3 return pattern.matcher(str).matches(); 4 }
结果:
1.主界面:
2.答题模式:
3.全部答对时:
4.计算结果有误时:
5.打印模式:
体会:
争论点:
1.打印方式 最初想法是逐个答题,答一道提交一道,然后再出下一道题;因为对用户不友好,故讨论新的展示方式;
2.判断对错 主要是关于如何保存题目以及对应的答案的探讨。
花费时间较长的问题:排版(Layout)问题。