结对子实验——小学生四则运算

实验开始时间:4月7日~4月9日

本次实验的组员分别是:郑泽成http://www.cnblogs.com/Oliver-zzc/,李天麟http://www.cnblogs.com/talent-demonic/

1.代码是在Eclipse环境下开发的

2.在这次实验中我负责了写四则运算的算术代码和检查算法

同伴负责面板的设计和监听事件的实现

3.实现扩展方向有:用户在第一次答题时,需要用户输入用户名;程序可以设置答题时间,时间设置为整数,单位为秒;答题结束可以显示用户答错的题目个数和答对的题目个数;PS:部分扩展功能能力有限不能全部实现,以后会进行改进。

总结:在本次实验当中,我觉得我们的java学习还不是太过于精通,需要以后的学习过程中好好增强。还有也让我感受到了,两个人写代码其实并不是想象中的轻松。因为每个人的思路不一样,懂得东西也不同,需要在编码过程中相互合作,相互协调和交流才能一起编出一个程序来。当中也有许多困难和疑惑,通过和宿舍的同学一起讨论和上网查找方法,解决了问题

package main;
import java.util.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;
import javax.swing.event.*;
import java.awt.event.*;
class Expression//表达式类,存放表达式
{
    int a;//第一个数
    int b;//第二个数
    int c;//正确答案
    int d;//输入答案
    char operator;//运算符
    boolean is_right;
    public Expression()
    {
        a=b=c=0;
        d = -1;
        is_right = false;
        operator = '+';
    } 
}
 
class NumberTooBigException extends Exception
{
    String message;
    public NumberTooBigException(String ErrorMessage)
    {
        message = ErrorMessage;
    }
    public String getMessage()
    {
        return message;
    }
}
 
public class Test
{
    Vector<Expression> v;
    public Test()
    {
        v = new Vector<Expression>();
    }
    public void produceExpression(int bit,char operator)
    {
        Expression temp = new Expression();
        temp.operator = operator;
        temp.a = (int)(Math.random() * Math.pow(10,bit));
        temp.b = (int)(Math.random() * Math.pow(10,bit));
        switch (operator) 
        {
            case '+': temp.c = temp.a + temp.b;break;
            case '-': temp.c = temp.a - temp.b;break;
            case '*': temp.c = temp.a * temp.b;break;
            case '/': temp.b = (temp.b == 0 ? //排除除法被除数为0的情况
                      temp.b = 1 +(int)(Math.random() * Math.pow(10,bit)-1): temp.b);
                      temp.c = temp.a / temp.b;break;
            default : mixExpression(temp,bit);//混合运算
        }
 
        v.add(temp);
    }
    //混合运算,产生随机数
    public void mixExpression(Expression temp,int bit)
    {
        int rand  = (int)(Math.random()*4);
        switch(rand)
        {
            case 1: temp.c = temp.a + temp.b;temp.operator = '+';break;
            case 2: temp.c = temp.a - temp.b;temp.operator = '-';break;
            case 3: temp.c = temp.a * temp.b;temp.operator = '*';break;
            case 0: temp.b = (temp.b == 0 ? //排除除法被除数为0的情况
                    temp.b = 1 +(int)(Math.random() * Math.pow(10,bit)-1): temp.b);
                    temp.c = temp.a / temp.b;temp.operator = '/';break;
            default :
        }
    }
 
    public  void writeInfo(int num,String userName)
    {
        File myFile = new File(userName + ".his");
        FileOutputStream fos;
        File saveUserNameAndScore = new File("UserNameAndScore.data");
        try 
        {
            fos = new FileOutputStream(myFile,true);
            PrintStream ps  = new PrintStream(fos);
            double score = 0;
            ps.println(String.format("%5s%5s%5s%5s%5s%10s%5s","","","","","正确答案","你的答案","判断"));
            ps.println();
            for(int i = 0 ;i < num ;i++)
            {
 
                ps.println(String.format("%5d%5s%5d%5s%10d%10d%10s",v.get(i).a,"+",
                v.get(i).b,"=",v.get(i).c,v.get(i).d,(v.get(i).is_right ? "正确":"错误")));
                ps.println();
                if(v.get(i).is_right)
                {
                    score += 100.0/num;
                }
            }
            ps.println("你的总分:" + score);
            ps.close();
            fos.close();
            //下面保存用户名和得分到UserNameAndScore.data文件;
            fos = new FileOutputStream(saveUserNameAndScore,true);
            ps = new PrintStream(fos);
            ps.println(userName);
            ps.println(score);
            ps.close();
            fos.close();
        }
        catch (Exception ex) 
        {
            System.out.println (ex.getMessage());
        }
 
    }
    public static void main(String[] s)
    {
        OverAllFrame oaf = new OverAllFrame("小学生四则运算练习器:");
    }
}
//主体框架


class OverAllFrame extends JFrame
{
    TimeThread timer;  //计时器线程
    Test ar ;//内部算法
    JPanel headPanel;//头面板
    JLabel welcomeLabel;//欢迎信息
    JLabel timeUse; //用时信息
    StartPanel st;
    String userName;
    RunningPanel rp;
    EndPanel ep;
    Vector<Expression> v;//存放算式
    
    
    public OverAllFrame(String s)
    {
        super(s);
        userName = JOptionPane.showInputDialog("请输入用户名","");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.initialize();
        setHeadPanel();
        this.setLayout(new BorderLayout());
        this.add(headPanel,BorderLayout.NORTH);
        this.add(st,BorderLayout.CENTER);
        this.setSize(500,400);
        this.setVisible(true);
        setLocationRelativeTo(null);
    }
    public void initialize()//初始化控件(主要面板)
    {
        ar = new Test();
        headPanel= new JPanel();
        welcomeLabel = new JLabel("欢迎!  学生:" + userName);
        st = new StartPanel();
        rp = new RunningPanel();
        ep = new EndPanel();
        timeUse = new JLabel();
    }
    
    
    public void setHeadPanel()
    {
        headPanel.setLayout(new FlowLayout());
        headPanel.add(welcomeLabel);
        headPanel.add(timeUse);
    }
    //开始面板
    class TimeThread extends Thread //计时器线程
    {
        int min;
        int sec;
        int millis;
        long oldTime;
        long timeUsed;
        long timeSeted;
        JLabel display;
        boolean stop = false;
        public TimeThread(long timeSeted,JLabel display) 
        {
            oldTime = System.currentTimeMillis();
            this.display = display;
            this.timeSeted = timeSeted;
            // TODO Auto-generated constructor stub
        }
        @Override
        public void run() {
            // TODO Auto-generated method stub
            super.run();
 
            do
            {
                timeUsed = System.currentTimeMillis() - oldTime;
                min = (int)(timeUsed/60000L);
                sec = (int)((timeUsed%60000L)/1000L);
                millis = (int)((timeUsed%60000L)%1000L);
                try {
                    sleep(11);
                } catch (InterruptedException e) {
                    // TODO: handle exception
                }
                display.setText("已用时:" + min+ ":" + sec +":" + millis );
                display.setVisible(true);
 
            }while(timeUsed <= timeSeted && !stop);
            if(!stop)//如果不是手动停止的就运行complete
                rp.complete();
        }
        public void setStop()
        {
            stop = true;
        }
    }
    class StartPanel extends JPanel
    {
        JPanel inputOptionPanel;         //输入选项面板①
        JPanel selectOperatorOptionPanel;//选择运算符面板②
        JPanel bottomPanel;              //底部面板③
 
        JLabel inputBitLabel;             //输入位数提示①-1        //输入位数区域①-2
        JLabel inputNumLabel;            //输入题目个数提示①-3        //输入题目个数区域①-4
        JLabel inputTimeLabel;           //输入做题时间提示①-5
        JPanel inputTimePanel;           //输入做题时间区域①-6
 
        ButtonGroup operatorGroup;
        JRadioButton addButton ;         //加法按钮②-1
        JRadioButton minusButton ;         //减法按钮②-2
        JRadioButton multiplyButton ;     //乘法按钮②-3
        JRadioButton divideButton ;         //除法按钮②-4
        JRadioButton mixButton     ;         //混合运算按钮②-5
 
        JLabel  errorInfo;               //错误信息③-1
        JButton startButton;             //开始按钮③-2
 
        JTextField inputByminutes;       //输入分钟区域①-6-1
        JLabel printMinute;                 //打印提示“分”①-6-2
        JTextField inputByseconds;       //输入秒钟区域①-6-3
        JLabel printSecond;              //打印提示“秒”①-6-4
        public StartPanel()
        {
            //this.setLayout(new GridLayout(0,1));
            this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
            this.initialize();
            this.setInputOptionPanel();
            this.setSelectOperatorOptionPanel();
            this.setBottomPanel();
            this.addStartEvent();
            this.add(inputOptionPanel);
            this.add(selectOperatorOptionPanel);
            this.add(bottomPanel);
        }
        public void initialize()              //初始化所有控件
        {
            inputOptionPanel = new JPanel();
            selectOperatorOptionPanel = new JPanel();
            bottomPanel = new JPanel();
            inputBitLabel = new JLabel("进行2位或两位以下运算:");
            inputNumLabel = new JLabel("将会产生4道题目");
            operatorGroup = new ButtonGroup();
            addButton = new JRadioButton("加法");
            minusButton = new JRadioButton("减法");
            multiplyButton = new JRadioButton("乘法");
            divideButton = new JRadioButton("除法");
            mixButton = new JRadioButton("混合");
            errorInfo = new JLabel();
            startButton = new JButton("开始做题!");    
            inputTimeLabel = new JLabel("输入做题时间:");
            inputTimePanel = new JPanel();
            inputByminutes = new JTextField();
            printMinute = new JLabel("分");
            inputByseconds = new JTextField();
            printSecond = new JLabel("秒");
        }
        //设置做题时间面板
        public void setInputTimePanel()
        {
            inputTimePanel.setLayout(new GridLayout(1,0));
            printMinute.setHorizontalAlignment(SwingConstants.CENTER);
            printSecond.setHorizontalAlignment(SwingConstants.CENTER);
            inputTimePanel.add(inputByminutes);
            inputTimePanel.add(printMinute);
            inputTimePanel.add(inputByseconds);
            inputTimePanel.add(printSecond);
        }
        //设置输入选项面板
        public  void setInputOptionPanel()
        {
            inputOptionPanel.setLayout(new GridLayout(3,2));
            inputBitLabel.setHorizontalAlignment(SwingConstants.CENTER);
            inputNumLabel.setHorizontalAlignment(SwingConstants.CENTER);
            inputTimeLabel.setHorizontalAlignment(SwingConstants.CENTER);
            inputOptionPanel.add(inputBitLabel);
            inputOptionPanel.add(inputNumLabel);
            inputOptionPanel.add(inputTimeLabel);
            setInputTimePanel();
            inputOptionPanel.add(inputTimePanel);
        }
        //设置选择运算符面板
        public void setSelectOperatorOptionPanel()
        {
            //selectOperatorOptionPanel.setLayout(new GridLayout(1,0));
            selectOperatorOptionPanel.setLayout(new BoxLayout(selectOperatorOptionPanel,BoxLayout.X_AXIS));
 
            operatorGroup.add(addButton);
            operatorGroup.add(minusButton);
            operatorGroup.add(multiplyButton);
            operatorGroup.add(divideButton);
            operatorGroup.add(mixButton);
            selectOperatorOptionPanel.add(addButton);
            selectOperatorOptionPanel.add(minusButton);
            selectOperatorOptionPanel.add(multiplyButton);
            selectOperatorOptionPanel.add(divideButton);
            selectOperatorOptionPanel.add(mixButton);
        }
        public void setBottomPanel()
        {
            bottomPanel.setLayout(new GridLayout(0,1));
            bottomPanel.add(errorInfo);
            bottomPanel.add(startButton);
        }
        //添加开始按钮处理事件
        public void addStartEvent()
        {
            startButton.addActionListener(new StartButtonListener());
        }
        //内部类,实现开始事件
        class StartButtonListener implements ActionListener
        {
            public void actionPerformed(ActionEvent e)
            {
                ar.v.clear();//清空向量
                char operator = '+';//默认加法
                if(minusButton.isSelected())
                {
                    operator = '-';
                }
                else if(multiplyButton.isSelected())
                {
                    operator = '*';
                }
                else if (divideButton.isSelected())
                {
                    operator = '/';
                }
                else if (mixButton.isSelected())//混合运算
                {
                    operator = '.';
                }
                try 
                {
                    int numOfEquation = Integer.parseInt("4");
                    int bigOfEquation = Integer.parseInt("2");
                    int minSeted = Integer.parseInt(inputByminutes.getText());
                    int secSeted = Integer.parseInt(inputByseconds.getText());
                    long millisSeted = (minSeted *60 + secSeted) * 1000;
                    timer = new TimeThread(millisSeted,timeUse);
                    timer.start();       
                    while(ar.v.size() < numOfEquation)
                    {
                        ar.produceExpression(bigOfEquation,operator);
                    }
                    OverAllFrame.this.v = ar.v;
                    rp.writeEquationToLabel();
 
                    OverAllFrame.this.st.setVisible(false);//开始面板调为不可见
                    OverAllFrame.this.add(rp,BorderLayout.CENTER);
                    OverAllFrame.this.setVisible(true);//更新窗口
                    OverAllFrame.this.rp.setVisible(true);//显示做题面板
                } 
                catch(NumberFormatException  ex)
                {
                    errorInfo.setText("输入数据类型错误!你必须输入数值数据!,请重新输入:");
                }
                catch(Exception ex)
                {
 
                }
 
            }
        }
    }
 
    //做题中的面板
    class RunningPanel extends JPanel
    {
        JPanel contentPanel;//存放题目和答案①
        JPanel buttonsPanel;//存放按钮②
        Vector<JLabel> expressionGroup;//显示题目①-1
        Vector<JTextField> answerGroup;//存放答案①-2
        JButton completeButton;  //完成②-3
        public RunningPanel()
        {
            this.setLayout(new BorderLayout());
            this.initialize();
            this.addItem();
            this.setContentPanel();
            this.setButtonsPanel();
        }
        public void initialize()//初始化
        {
            contentPanel = new JPanel();
            buttonsPanel = new JPanel();
            expressionGroup = new Vector<JLabel>();
            answerGroup     = new Vector<JTextField>();
            for(int i = 0; i < 4 ;i++)
            {
                expressionGroup.add(new JLabel());
                answerGroup.add(new JTextField());
            }
            completeButton = new JButton("完成!");
            completeButton.addActionListener(new CompleteButtonListener());
        }
        
        public void setContentPanel()
        {
            contentPanel.setLayout(new GridLayout(6,2));
            for(int i = 0; i < 4; i++)
            {
                contentPanel.add(expressionGroup.get(i));
                contentPanel.add(answerGroup.get(i));
            }
        }
      
        public void setButtonsPanel()
        {
            buttonsPanel.add(completeButton);
        }
        
        public void writeEquationToLabel()//写入算式
        {
            for(int i = 0; i < 4 ; i++)
            {
                    String temp = String.format("%5d%5s%5d%5s",v.get(i).a,
                                                v.get(i).operator,
                                                v.get(i).b,"=");
                    expressionGroup.get(i).setText(temp);
            }
        }
        
        
        public void addItem()//添加控件
        {
            this.add(contentPanel,BorderLayout.CENTER);
            this.add(buttonsPanel,BorderLayout.SOUTH);
        }
        
        public void writeInputToVector() throws NumberFormatException//写入答案进向量
        {
            for (int i = 0; i < 4 ;i++)
            {
                try 
                {
                    if(!answerGroup.get(i).getText().equals(""))//如果不是啥也没写的话
                    {
                        v.get(i).d = Integer.parseInt(answerGroup.get(i).getText());
                        if(v.get(i).d == v.get(i).c)
                            v.get(i).is_right = true;
                    }
                    //否则就是默认的-1
 
                } 
                catch(NumberFormatException  e)
                {
                    answerGroup.get(i).setText("输入数据类型错误!请重新输入:");
                    throw e;//必须这么写才能终止。。
                }
                catch(Exception e)
                {
                    answerGroup.get(i).setText("未知错误!请重新输入:");
                    throw e;//必须这么写才能终止。。
                }
            }
        }
        public void clearAnswer()//清空答案
        {
            for (int i = 0; i < 4;i++)
            {
                answerGroup.get(i).setText("");
            }
        }
        //写入答案进输入区,还原上下页做过的答案用
        public void writeAnswerTofield()
        {
            for(int  i = 0; i < 4; i ++)
            {
                if(v.get(i).d != -1)//说明有输入过值
                {
                    answerGroup.get(i).setText(Integer.toString(v.get(i).d));
                }
            }
        }
        public void complete()//完成做题,用户点击完成或者 是时间到了
        {
            try
            {
                //因为第一句可能会产生异常,不过在句中已经处理,这里加上
                //try是让它停止进入下一页
                timer.setStop();//计时器线程停止
                OverAllFrame.this.rp.writeInputToVector();//写入答案进向量
                OverAllFrame.this.ar.writeInfo(v.size(), userName);
                OverAllFrame.this.rp.setVisible(false);//设置做题界面不可见
                OverAllFrame.this.ep.setDisplayAnswer(); //设置要显示的结果
                OverAllFrame.this.add(ep,BorderLayout.CENTER);
                OverAllFrame.this.setVisible(true);
                OverAllFrame.this.ep.setVisible(true);//显示答案面板
 
            }
            catch(Exception e)
            {
                //do nothing
            }
 
        }
        class CompleteButtonListener implements ActionListener
        {
            public void actionPerformed(ActionEvent ae)
            {
                complete();
            }
        }
 
    }
    //显示结果面板
    class EndPanel extends JPanel
    {
        JScrollPane displayArea;//显示区域
        JPanel bottomArea;      //底部区域,存放按钮
        JTextArea displayAnswer;//显示答案和评分
        Font answerFont ; //字体属性
        public EndPanel()
        {
            this.setLayout(new BorderLayout());//边界布局
            this.initialize();
            this.addItem();
 
        }
 
        public void initialize()//初始化
        {
            answerFont = new Font("宋体",Font.PLAIN,15);
            displayAnswer = new JTextArea();
            displayAnswer.setFont(answerFont);//设置字体
            displayArea = new JScrollPane(displayAnswer);
            bottomArea  = new JPanel();
 
        }
        
        public void setDisplayAnswer()//添加答案
        {
            displayAnswer.setEditable(false);//只显示答案,不可编辑
            String temp ;
            temp = (String.format("%5s%5s%5s%5s%5s%10s%5s","","",
                    "","","	正确答案","你的答案","	判断")) + "
";
            displayAnswer.append(temp);
            for(int i = 0 ;i < 4;i++)
            {
                temp = (String.format("%5d%5s%5d%5s%10d%10d%10s",v.get(i).a,v.get(i).operator,
                                    v.get(i).b,"=",v.get(i).c,v.get(i).d,(v.get
                                        (i).is_right ? "正确":"错误")))+ "
";
                displayAnswer.append(temp);
               
            }
            displayAnswer.append(temp);
 
        }
        public void addItem()
        {
 
            this.add(displayArea,BorderLayout.CENTER);
        }
       
       
    }
}
原文地址:https://www.cnblogs.com/Oliver-zzc/p/4411076.html