四则运算生成程序——GUI支持和部分功能改进

项目成员:张金生     张政

工程地址:

https://coding.net/u/jx8zjs/p/paperOne/git

ssh://git@git.coding.net:jx8zjs/paperOne.git

 

需求:

  1.GUI支持:用户界面新增支持 Windows GUI,同时保留原有命令行下所有功能。

  2.配置文件:提供用户可用文本编辑器修改的配置文件,在其中包括用户名、总答题数、答错题数。

  3.错题本:可回放做错的题目,提供再次练习的机会/删除特定错题。

 

变更:

  1.支持倒计时:答题模式出题以后会自动计时,如果用未在规定时间内答完题目则会自动被提交试卷,答题时间和题目数量等相关。

  2.出题数目:变更前的版本会因为出题数量过多而界面显示不下,已改进为滚动模式防止溢出。

  3.错题本:错题本完善,可以记录错题,数量,甚至从错题本中抽取题目重做,也可以将错题本中的题目选择性删除。

  4.更详细的配置内容显示和编辑:记录用户名、总答题数、答错题数,可以编辑这些信息。

设计:

  1.倒计时:使用单例模式线程,每秒缩减答题时间一秒,倒计时时间到则触发提交按钮完成抢卷功能,选择单例模式也是防止多次生成题目导致倒计时速度加快的问题。

  2.变更前使用的Jpanel控件和MigLayout,这样可以方便显示题目并且可以控制题目格式布局,不过题目过大需要手动调节窗口,否则会有部分题目超出浏览范围。改进后使用JScrollPane,并设置为MigLayout,同样达到了控制布局的效果,也能将原来显示不下的题目通过滚动条拖拽的方式显示出来。

  3.打开错题本可以看到每道错题前均有复选框用于删除题目,错题删除采用JCheckBox在题目前显示,根据勾选情况获取到题目的编号进行删除,最后再重写到错题本中。

  4.点击编辑信息按钮则在工作区显示编辑的项目,提交即可。

部分代码实现:

 1.1倒计时实现:

 1 class MyThread extends Thread {
 2     private MyThread(){
 3         
 4     }
 5     private static MyThread instance =null;
 6     public static MyThread getInstance(){
 7         if(instance==null){
 8             instance = new MyThread();
 9         }
10         return instance;
11     }
12     public void run() {
13         while (MainWindow.time > 0) {
14             MainWindow.time--;
15             MainWindow.lblTime.setText(MainWindow.time + "");
16             try {
17                 Thread.sleep(1000);
18             } catch (Exception e) {
19                 e.printStackTrace();
20             }
21             if (MainWindow.subOnClick == 1) {
22                 return;
23             }
24 
25         }
26 
27         MainWindow.submitButton.doClick();
28 
29     }
30 }

1.2倒计时的使用:生成题目后加入此段代码,保证只创建一个计时线程,并且线程不会被重复启动

1 try{
2                 MyThread.getInstance().start();
3                 }catch (Exception e1) {
4                     // TODO: handle exception
5                 }

2.带有滚动条的题目显示面板:然后题目加入到包裹在JScrollpane下的Jpanel中,减少对原有代码的修改量

1         private JScrollPane scrollPane = new JScrollPane();
2         scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
3         scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
4         frmPaperone.getContentPane().add(scrollPane, BorderLayout.CENTER);
5 
6         scrollPane.add(panelMain);
7         panelMain.setLayout(new MigLayout("", "[][grow]", "[][]"));
8         scrollPane.setViewportView(panelMain);

3.错题本的编辑和题目删除:

 1 // 错题本按钮
 2         buttonWrong.addActionListener(new ActionListener() {
 3             @Override
 4             public void actionPerformed(ActionEvent e) {
 5                 // 初始化
 6                 subOnClick = 1;
 7                 panelMain.removeAll();
 8                 frmPaperone.repaint();
 9                 int m = 0;
10                 int num = Wrong.size();
11                 for (int i = 0; i < num; i++) {
12                     String[] wrong = Wrong.get(i);
13                     JCheckBox chckbxNewCheckBox = new JCheckBox("");
14                     // chckbxNewCheckBox.setText(wrong[0] + "=" + wrong[1]);
15                     panelMain.add(chckbxNewCheckBox, "cell 0 " + m + ",alignx trailing");
16 
17                     JLabel wrongBar = new JLabel("");
18                     panelMain.add(wrongBar, "cell 1 " + m + ",alignx 0");
19                     wrongBar.setText(wrong[0] + "=" + wrong[1]);
20                     m++;
21                 }
22                 // 删除按钮
23                 ArrayList<Integer> al = new ArrayList<>();
24                 btnDelete.addActionListener(new ActionListener() {
25                     public void actionPerformed(ActionEvent e) {
26 
27                         Component[] compnent = panelMain.getComponents();
28                         for (int i = 0; i < num * 2; i++) {
29                             try {
30                                 JCheckBox tmp = (JCheckBox) compnent[i];
31                                 if (tmp.isSelected()) {
32                                     al.add(i / 2);
33                                 }
34                             } catch (Exception e1) {
35                                 continue;
36                             }
37                         }
38                         for (int d = al.size() - 1; d >= 0; d--) {
39                             Wrong.remove(Wrong.get(al.get(d)));
40                         }
41                         messageBar.setText("删除成功!");
42                         RewriteNote();
43                         al.clear();
44                         frmPaperone.repaint();
45                         buttonWrong.doClick();
46                     }
47                 });
48 
49                 panelMain.add(btnDelete, "cell 1 " + m + ",alignx trailing");
50 
51             }
52         });

4.编辑用户信息:

 1         // 修改信息按钮
 2 
 3         btnEdit.addActionListener(new ActionListener() {
 4             @Override
 5             public void actionPerformed(ActionEvent e) {
 6                 panelMain.removeAll();
 7                 panelMain.add(lblUserNameEdit, "cell 0 0,alignx trailing");
 8 
 9                 textFieldUs.setText(username);
10                 panelMain.add(textFieldUs, "cell 1 0,alignx trailing");
11                 textFieldUs.setColumns(10);
12 
13                 panelMain.add(lblNumRightEdit, "cell 0 1,alignx trailing");
14 
15                 panelMain.add(NumSumEdit, "cell 1 1,alignx trailing");
16                 NumSumEdit.setText(SumOfA + "");
17 
18                 panelMain.add(lblNumWrongEdit, "cell 0 2,alignx trailing");
19 
20                 panelMain.add(NumWrongEdit, "cell 1 2,alignx trailing");
21                 NumWrongEdit.setText(SumOfE + "");
22 
23                 panelMain.add(reButton, "cell 0 3,alignx trailing");
24                 panelMain.add(saveButton, "cell 1 3,alignx trailing");
25                 subOnClick = 1;
26                 panelMain.repaint();
27             }
28         });
29 
30 // 保存按钮
31         saveButton.addActionListener(new ActionListener() {
32             @Override
33             public void actionPerformed(ActionEvent e) {
34                 panelMain.removeAll();
35 
36                 username = textFieldUs.getText();
37                 messageBar.setText("用户名已修改为" + username);
38                 UserName.setText(username);
39                 RewriteNote();
40 
41                 frmPaperone.repaint();
42             }
43 
44         });
45 
46         // 重置按钮
47         reButton.addActionListener(new ActionListener() {
48             @Override
49             public void actionPerformed(ActionEvent e) {
50                 panelMain.removeAll();
51 
52                 SumOfA = 0;
53                 SumOfE = 0;
54                 Wrong.clear();
55                 messageBar.setText("重置成功");
56                 NumSum.setText(SumOfA + "");
57                 NumWrong.setText(SumOfE + "");
58                 RewriteNote();
59 
60                 frmPaperone.repaint();
61 
62             }
63 
64         });

运行截图:

 打开程序选择编辑按钮

将用户名修改

变更成功

 出题10道,简单难度答题时间60秒,7秒后变为53秒

简单难度50道题目,总答题时间为260秒,侧边滚动条可以拖拽显示原本超出屏幕的内容。

打开错题本

删除其中的前三道题目

删除错题本选中的错题后将剩余的题目作为试卷出题,达到错题重做的目的。

 难度设置

结对体会:

 面对不同的需求可能两个人会有不同的解决方案,也许会想出非常简单的设计方法让其实现简单化。在设计程序的交互上也采取尽量不弹框的原则,将要提示的内容显示在程序的状态栏上,省去用户的冗余点击事件也算是友好交互的探索。

 花费时间较长的问题:排版(Layout)问题。

 

工程地址:

https://coding.net/u/jx8zjs/p/paperOne/git

ssh://git@git.coding.net:jx8zjs/paperOne.git

 

posted @ 2016-10-20 00:04  张小生  阅读(491)  评论(8编辑  收藏  举报