小学生口算题答题系统———计应193第六组张淑雅
一、计划
使用java语言编写一个小学生口算题系统
技术难点:
①随机产生50个加减法算式,剔除减法算式差为负值,循环产生。
②显示一组算题,答题之后可以进行批改,同步计时(秒)。
③显示对错,统计正确率,统计时间。
二、开发
1、需求分析
用户故事
作为一名一年级小学生的家长,我希望制作一个出题软件,完成100以内的正整数的加减法题随机产生。以便减轻我的家庭负担。
2.生成设计文档
3.设计复审
设计出程序的整体框架的搭建
4.代码规范
注意代码的格式和命名规范,避免出错。
5.具体设计
这个项目是用Java语言做的,使用GUI技术和多线程技术,实现用户登录页面,使用户登录进行答题系统。使用GUI搭建页面,创建按钮,文本框等。随机产生100以内的正整数和加减符号结合随机生成50个加减算式。产生算式是要剔除减法算式中被减数比减数大的算式,避免出现负值。在答题页面进行同步计时,每答一道题可以进行批改对错。提交之后,弹出提示框,统计答题的正确率和做题时间。而且可以返回提示框返回首页页面再次答题。
6、具体编码
登录页面具体实现代码:
public class Login_Interface extends JFrame { private static final long serialVersionUID = 1L; //定义程序序列化,1L是默认定义 protected static String s1; protected static String s2; protected static String s3; private JLabel jl1 = new JLabel("欢迎来到数学答题系统"); private JLabel jl2 = new JLabel("请填写下列信息"); private JLabel jl3 = new JLabel(" "); private JLabel jl4 = new JLabel(" "); private JLabel JLName = new JLabel("用户名:"); private JLabel JLMagic = new JLabel("密 码:"); private TextField JTName = new TextField(20); private TextField JTMagic=new TextField(20); private JButton JB1 = new JButton("登录 "); private JButton JB2 = new JButton("重置"); private JPanel jp1 = new JPanel(); private JPanel jp2 = new JPanel(); private JPanel jp3 = new JPanel(); private JPanel jp4 = new JPanel(); private JPanel jp5 = new JPanel(); private JPanel jp6 = new JPanel(); private JPanel jp7 = new JPanel(); private void Event() { JB1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(JTName.getText().equals("") || JTMagic.getText().equals("")) { String s = "请输入用户名或密码!!!"; JOptionPane.showMessageDialog(null, s,"提示",JOptionPane.ERROR_MESSAGE); }else if(!JTName.getText().equals("admin") || !JTMagic.getText().equals("123456")) { String s = "用户名或密码错误!!!"; JOptionPane.showMessageDialog(null, s,"警告",JOptionPane.ERROR_MESSAGE); } else { setVisible(false); dispose(); s1 = JTName.getText(); s3 = JTMagic.getText(); new index(); } } }); JB2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JTName.setText(null); JTMagic.setText(null); } }); } public Login_Interface() { this.setTitle("欢迎来到数学答题系统"); this.setSize(600, 500); this.setLocationRelativeTo(null); //将此窗口置于屏幕的中央 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLayout(new BorderLayout(20,20)); jl1.setFont(new Font("黑体",Font.BOLD,35)); jl1.setForeground(Color.blue); jp1.add(jl1); jp1.setLayout(new GridBagLayout()); this.add(jp1,BorderLayout.NORTH); jl2.setFont(new Font("黑体",Font.BOLD,25)); jl2.setForeground(Color.red); jp2.add(jl2); JLName.setFont(new Font("黑体",Font.BOLD,20)); jp3.add(JLName); jp3.add(JTName); JLMagic.setFont(new Font("黑体",Font.BOLD,20)); JTMagic.setEchoChar('*'); jp4.add(JLMagic); jp4.add(JTMagic); jp6.add(jp2); jp6.add(jp3); jp6.add(jp4); jp6.add(jp5); jp6.setLayout(new GridLayout(4,2)); this.add(jp6,BorderLayout.CENTER); jp6.setBorder(BorderFactory.createLoweredBevelBorder()); jp7.add(jl4); jp7.add(JB1); jp7.add(jl3); jp7.add(JB2); this.add(jp7,BorderLayout.SOUTH); //美化界面 try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); } Event(); this.setVisible(true); } public static void main(String[] args) { new Login_Interface(); } }
系统首页具体实现代码:
public class index extends JFrame { private static final long serialVersionUID = 1L; //定义程序序列化,1L是默认定义 protected static String s1; protected static String s2; protected static String s3; private JLabel jl1 = new JLabel("欢迎来到数学答题系统"); private JLabel jl3 = new JLabel(" "); private JLabel jl4 = new JLabel(" "); private JButton JB1 = new JButton("开始答题"); private JButton JE = new JButton("退出登录"); private JPanel jp1 = new JPanel(); private JPanel jp2 = new JPanel(); private JPanel jp3 = new JPanel(); private JPanel jp4 = new JPanel(); private JPanel jp5 = new JPanel(); private JPanel jp6 = new JPanel(); private JPanel jp7 = new JPanel(); private void Event() { JB1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub setVisible(false); dispose(); new Test_Interface(); } }); JE.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub setVisible(false); dispose(); new Login_Interface(); } }); } public index() { this.setTitle("欢迎来到数学答题系统"); this.setSize(500, 450); this.setLocationRelativeTo(null); //将此窗口置于屏幕的中央 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLayout(new BorderLayout(20,20)); jl1.setFont(new Font("黑体",Font.BOLD,35)); jl1.setForeground(Color.blue); jp1.add(jl1); jp1.setLayout(new GridBagLayout()); this.add(jp1,BorderLayout.NORTH); jp7.add(JB1); jp7.add(JE); this.add(jp7,BorderLayout.SOUTH); //美化界面 try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); } Event(); this.setVisible(true); } }
答题页面具体实现代码:
public class Test_Interface extends JFrame{ private static final long serialVersionUID = 1L; //定义程序序列化,1L是默认定义 private int max = 50; private int a = 0; private int b = 0; private int c = 0; private int count = 1; private JLabel JLgross = new JLabel("共10页"); private JLabel JLpage = new JLabel(); //页码控制 private JLabel jl1 = new JLabel(" "); //插两个空格进去 private JLabel JLtime = new JLabel("倒计时:"); private JLabel JLhour = new JLabel(); private JLabel JLminute = new JLabel(); private JLabel JLseconds = new JLabel(); private JButton JB1 = new JButton("提交"); private JButton b1 = new JButton("首页"); private JButton b2 = new JButton("上一页"); private JButton b3 = new JButton("下一页"); private JButton b4 = new JButton("尾页"); private JButton b5 = new JButton("批改答案"); private JButton b6 = new JButton("返回"); private JLabel jl[] = new JLabel[50]; //50个题目标签 private JTextField jtf[] = new JTextField[50];//50个文本框,存储答案 private JTextField jta[] = new JTextField[50];//50个文本框,存储结果 private JPanel pnl1 = new JPanel(); private JPanel pnl2 = new JPanel(); private JPanel pnl3 = new JPanel(); private JPanel pnl4 = new JPanel(); static CardLayout care = new CardLayout(); int[] answer=new int[max]; String[] studentAnswer=new String[max]; public long time = 0; private void countDown() { Timer timer = new Timer(); timer.schedule(new TimerTask() { public void run() { time++; long hour = 0; long minute = (time - hour * 3600) / 60; long seconds = time - hour * 3600 - minute * 60; JLhour.setText(hour + "时"); JLminute.setText(minute + "分"); JLseconds.setText(seconds + "秒"); /** if( time == 0 ) { JB1.doClick(); //调用提交试卷按钮 }**/ } }, 0, 1000); } private void Event() { //提交试卷按钮 JB1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int correctAnswer=0; for(int i=0,k=0;i<max;i++,k++){ studentAnswer[i]=jtf[k].getText().trim(); try { if(Integer.parseInt(studentAnswer[i]) == answer[k]){ //将string字符串类型转换为integer整数类型 correctAnswer++; } }catch(NumberFormatException u) { } } int score = 100*(int)correctAnswer/max; String s="共50道题\n"; s=s+"答对"+correctAnswer+"道题\n"; s=s+"答错"+(max-correctAnswer)+"道题\n"; s=s+"成绩"+String.format("%d",score)+"分\n"; s=s+"正确率:"+correctAnswer*100/50+"%\n"; s=s+"答题时间:"+time+"秒"; // Object[] options ={ "确定", "取消" }; //自定义按钮上的文字 JOptionPane.showMessageDialog(null, s,"本次答题情况",JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(null, "即将返回首页面", "提示",JOptionPane.ERROR_MESSAGE); // JOptionPane.showOptionDialog(null, "即将返回首页面", "提示",JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); new index(); setVisible(false); dispose(); } }); //首页 b1.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ care.first(pnl3); count = 1; JLpage.setText("第" + count + "页"); } }); //前一页 b2.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ care.previous(pnl3); if ( count > 1 && count <=10) { count --; }else { count = 10 ; } JLpage.setText("第" + count + "页"); } }); //下一页 b3.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ care.next(pnl3); if ( count >= 1 && count < 10 ) { count ++; }else { count = 1 ; } JLpage.setText("第" + count + "页"); } }); //尾页 b4.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ care.last(pnl3); count = 10; JLpage.setText("第" + count + "页"); } }); b5.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ for(int i=0,k=0;i<max;i++,k++){ studentAnswer[i]=jtf[k].getText().trim(); try { if(Integer.parseInt(studentAnswer[i]) == answer[k]){ jta[k].setText("回答正确!!"); jta[k].setForeground(Color.GREEN); }else { jta[k].setText("回答错误!! 正确答案为:"+jl[k].getText()+answer[k]); jta[k].setForeground(Color.RED); } }catch(Exception u) { } } } }); b6.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ JOptionPane.showMessageDialog(null, "是否返回首页","提示",JOptionPane.ERROR_MESSAGE); new index(); setVisible(false); dispose(); } }); } public Test_Interface() { this.setTitle("开始答题"); this.setSize(830, 500); this.setLocationRelativeTo(null); //将此窗口置于屏幕的中央 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLayout(new BorderLayout(20,20)); //设置 各组件间水平垂直间隔为20像素 countDown(); pnl1.add(JLhour); pnl1.add(JLminute); pnl1.add(JLseconds); JLpage.setText("第" + count + "页"); pnl2.setLayout(new FlowLayout()); pnl2.add(JLgross); pnl2.add(JLpage);//页数 pnl2.add(jl1); pnl2.add(JLtime); pnl2.add(pnl1); pnl2.add(JB1); this.add(pnl2,BorderLayout.NORTH); pnl3.setLayout(care); this.add(pnl3,BorderLayout.CENTER); pnl3.setBorder(BorderFactory.createLoweredBevelBorder()); //边框 for(int i = 0 , k = 0; i < 10 ; i++ ) { JPanel p = new JPanel(); p.setLayout(new GridLayout(5,2,20,20)); //网格布局5行2列,水平垂直间距都设为20像素 for(int j = 0 ; j < 5 ; j++) { a=(int)(Math.random()*100+1); b=(int)(Math.random()*100+1); String random = ""; String[] doc = {"+", "-"}; int index = (int) (Math.random() * doc.length); random = doc[index]; if(random=="-") { if(a>b) { jl[k] = new JLabel(a + random + b + "="); jl[k].setFont(new Font("黑体",Font.BOLD,20)); p.add(jl[k]); answer[k] = a - b ; }else { jl[k] = new JLabel(b + random + a + "="); jl[k].setFont(new Font("黑体",Font.BOLD,20)); p.add(jl[k]); answer[k] = b - a ; } } else if(random=="+") { jl[k] = new JLabel(a + random + b + "="); jl[k].setFont(new Font("黑体",Font.BOLD,20)); p.add(jl[k]); answer[k] = a + b ; } jtf[k] = new JTextField(6); jta[k] = new JTextField(6); p.add(jtf[k]); p.add(jta[k]); jtf[k].setText(null); jtf[k].setText(null); k++; } pnl3.add(p); } pnl4.setLayout(new GridLayout(1,4)); pnl4.add(b1); pnl4.add(b2); pnl4.add(b3); pnl4.add(b4); pnl4.add(b5); pnl4.add(b6); this.add(pnl4, BorderLayout.SOUTH); //美化界面 try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); } Event(); setVisible(true); } // public static void main(String[] args){ // // new Test_Interface(); // // } }
7、代码复审
在测试过程中出现过许多错误,问题很多。使用了debag模式打断点进行纠错,一行一行的运行。然后将重复使用两次或两次以上的代码抽取成一个方法,减少代码的长度,增加可阅读性。
8、测试
运行结果:
三、报告
1、测试报告
在出现正确的运行结果之前,运行了好多次,出现了好多漏洞。反复改进,才有了正确结果。
2、事后总结
这个项目刚开始觉得这个项目挺复杂,现在再做一次这个项目,查了好多资料。观看了好多大学毕业生的设计报告,突然间理顺了思路,做每个项目都需要分层设计这,也是一个重要环节。因为经验少,还对内部原理不太清楚。希望在下次做项目时多改进。
工作所花时间百分比
口算题卡开发 |
预计时间 |
实际记录 |
计划 |
10 |
8 |
|
10 |
8 |
开发 |
91 |
86 |
|
10 |
8 |
|
8 |
7 |
|
8 |
7 |
|
5 |
5 |
|
10 |
13 |
|
32 |
25 |
|
8 |
10 |
|
10 |
11 |
报告 |
19 |
22 |
|
3 |
3 |
|
3 |
4 |
|
13 |
15 |
总共花费的时间 |
120 |
116 |