四则运算结对编程
Coding.net仓库地址: https://git.dev.tencent.com/yangmt735/calculate.git
一、功能设计
- 选择出题或做题。
- 定制出题要求
- 出题后做题
- 全部完成后判断对错,并给出分数和时间
二、实现
Command类:对命令行参数进行分析调用
isInteger(String s):判断字符串是否为数字
createFile类:生成对应的文本文件
fileCreate(int n,int lower,int upper,int o,int c,int b):根据参数生成符合要求的文件
formula类:根据需求生成对应的算式
Bracket_AS(int lower,int upper,int o):产生有括号的加减算式,调用decide1(),decide(),work();
Bracket(int lower,int upper,int o):产生有括号的四则运算式,调用numberB(),work(),operator();
AddSubtract(int lower,int upper,int o):产生简单加减算式,调用decide1(),decide();
Arithmetic(int lower,int upper,int o):产生四则运算式,调用numberA(),operator(),work();
calculate类:对算式进行相应的计算
numberA(int key,int num,int result,int lower,int upper):产生无括号情况下的数
numberB(int key,int num,int result,int lower,int upper):产生有括号情况下的数
decide0(int x,int min,int max):产生加数
decide1(int x,int min,int max):产生减数
decide2(int x,int min,int max):产生除数
decide3(int x,int min,int max):产生乘数
operator(int num,int middle2,int middle3):限制乘除法出现条件
stack类:用于算式计算
work(String s,int lower,int upper,int op):由中缀表达式转为后缀表达式
doCal(int a,int b,String stmp):判断弹出的符号并计算
三、部分代码展示
具体实现是根据之前的代码修改而来,这里展示界面部分代码
1、出题做题选择界面
public class RadioButtonDemo extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
Font f = new Font("楷体", Font.BOLD, 19);
private JRadioButton question, homework;
// 选择模式
public RadioButtonDemo() {
ImageIcon flag = new ImageIcon("img/3.jpg");
setIconImage(flag.getImage());
ImageIcon background = new ImageIcon("img/4.jpg");
JLabel label = new JLabel(background);
label.setBounds(0, 0, background.getIconWidth(), background.getIconHeight());
/*
* 主界面获得容器JPanel
*/
getLayeredPane().add(label, new Integer(Integer.MIN_VALUE));
JPanel jp = (JPanel) getContentPane();
/*
* JPanel对象才可以调用setOpaque(false);设置是否透明
*/
jp.setOpaque(false);
JPanel jpanel = new JPanel(new BorderLayout());
jpanel.setOpaque(false);
JPanel jpRadioButtons = new JPanel(new FlowLayout(FlowLayout.CENTER, 30, 25));
jpRadioButtons.setOpaque(false);
jpRadioButtons.add(question = new JRadioButton("出题"));
jpRadioButtons.add(homework = new JRadioButton("做题"));
question.setFont(f);
homework.setFont(f);
question.setOpaque(false);
homework.setOpaque(false);
JPanel p = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
JButton submit = new JButton("确认");
p.add(submit);
p.setOpaque(false);
jpanel.add(jpRadioButtons, BorderLayout.CENTER);
jpanel.add(p, BorderLayout.SOUTH);
ButtonGroup group = new ButtonGroup();
group.add(question);
group.add(homework);
add(jpanel);
submit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (homework.isSelected())// 选择出题
{
dispose();
homework frame = new homework("名字");
frame.setTitle("登录");
frame.setSize(400, 160);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
} else if (question.isSelected())// 选择做题
{
// TODO Auto-generated method stub
dispose();
Design frame1 = new Design();
frame1.setTitle("练习题生成器");
frame1.setSize(720, 230);
frame1.setLocationRelativeTo(null);
frame1.setResizable(false);
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setVisible(true);
} else {
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "请选择一项再点击确认!", "提示",
JOptionPane.INFORMATION_MESSAGE);
return;
}
}
});
}
}
2、选择出题界面
public class Design extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
Font f = new Font("楷体", Font.BOLD, 19);
JTextField n = new JTextField(4);
JTextField lower = new JTextField(4);
JTextField upper = new JTextField(4);
JComboBox<String> o;
JCheckBox c = new JCheckBox("乘除法");
JCheckBox b = new JCheckBox("括号");
JButton submit = new JButton("确认");
JButton cancel = new JButton("取消");
// 出题参数页面
public Design() {
ImageIcon flag = new ImageIcon("img/3.jpg");
setIconImage(flag.getImage());
ImageIcon background = new ImageIcon("img/2.jpg");
JLabel label = new JLabel(background);
label.setBounds(0, 0, background.getIconWidth(), background.getIconHeight());
/*
* 主界面获得容器JPanel
*/
getLayeredPane().add(label, new Integer(Integer.MIN_VALUE));
JPanel jp = (JPanel) getContentPane();
/*
* JPanel对象才可以调用setOpaque(false);设置是否透明
*/
jp.setOpaque(false);
JPanel jpanel = new JPanel(new BorderLayout());
jpanel.setOpaque(false);
JPanel p1 = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 20));
JLabel M_n = new JLabel("题数(必填)");
M_n.setFont(f);
p1.add(M_n);
p1.add(n);
JLabel M_lower = new JLabel("数值下限(必填)");
p1.add(M_lower);
M_lower.setFont(f);
p1.add(lower);
JLabel M_upper = new JLabel("数值上限(必填)");
p1.add(M_upper);
M_upper.setFont(f);
p1.add(upper);
p1.setOpaque(false);
JPanel p2 = new JPanel(new FlowLayout(FlowLayout.CENTER, 18, 20));
JLabel M_o = new JLabel("运算符数量");
p2.add(M_o);
M_o.setFont(f);
String[] sum = new String[10];
for (int i = 1; i < 11; i++) {
sum[i - 1] = " " + i;
}
o = new JComboBox<String>(sum);
o.setFont(new Font("楷体", Font.BOLD, 16));
o.setMaximumRowCount(4);
p2.add(o);
c.setFont(f);
c.setOpaque(false);
p2.add(c);
b.setFont(f);
b.setOpaque(false);
p2.add(b);
p2.setOpaque(false);
JPanel p3 = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 20));
p3.add(submit);
p3.add(cancel);
p3.setOpaque(false);
jpanel.add(p1, BorderLayout.NORTH);
jpanel.add(p2, BorderLayout.CENTER);
jpanel.add(p3, BorderLayout.SOUTH);
add(jpanel);
M_n.addMouseListener(new nListener());
M_lower.addMouseListener(new lowerListener());
M_upper.addMouseListener(new upperListener());
c.addMouseListener(new cListener());
b.addMouseListener(new bListener());
submit.addActionListener(new submitListener());
cancel.addActionListener(new cancelListener());
}
public class nListener implements MouseListener {
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
setTitle("题数范围为1-10000");
}
@Override
public void mouseExited(MouseEvent e) {
}
}
public class lowerListener implements MouseListener {
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
setTitle("下限范围为1-100");
}
@Override
public void mouseExited(MouseEvent e) {
}
}
public class upperListener implements MouseListener {
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
setTitle("上限范围为50-1000");
}
@Override
public void mouseExited(MouseEvent e) {
}
}
public class cListener implements MouseListener {
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
setTitle("勾选时,上界数值需大于下界的平方");
}
@Override
public void mouseExited(MouseEvent e) {
}
}
public class bListener implements MouseListener {
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
setTitle("勾选时,操作符数量需要大于1");
}
@Override
public void mouseExited(MouseEvent e) {
}
}
public class submitListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String m = "题数与数值上下限为必填项,请按标题提示输入正整数!";
String m2 = "创建文件成功!";
int n0, lower0, upper0, o0, c0, b0;
o0 = 1;
c0 = 0;
b0 = 0;
try {
n0 = Integer.parseInt(n.getText());
lower0 = Integer.parseInt(lower.getText());
upper0 = Integer.parseInt(upper.getText());
if (n0 < 1 || n0 > 10000) {
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "题数范围为1-10000", "提示",
JOptionPane.INFORMATION_MESSAGE);
return;
}
if (lower0 < 1 || lower0 > 100) {
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "下界范围为1-100", "提示",
JOptionPane.INFORMATION_MESSAGE);
return;
}
if (upper0 < 50 || upper0 > 1000) {
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "上界范围为50-1000", "提示",
JOptionPane.INFORMATION_MESSAGE);
return;
}
if (upper0 < (2 * lower0)) {
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "上界必须大于两倍下界", "提示",
JOptionPane.INFORMATION_MESSAGE);
return;
}
} catch (NumberFormatException e2) {
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), m, "提示", JOptionPane.INFORMATION_MESSAGE);
return;
}
o0 = o.getSelectedIndex() + 1;
if (c.isSelected()) {
c0 = 1;
}
if (b.isSelected()) {
b0 = 1;
}
if (o0 == 1 && b0 == 1) {
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "括号需要操作符数量大于1", "提示",
JOptionPane.INFORMATION_MESSAGE);
return;
}
if (c0 == 1 && upper0 < (lower0 * lower0)) {
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "乘除法需要上界数值大于下界的平方", "提示",
JOptionPane.INFORMATION_MESSAGE);
return;
}
createFile.fileCreate(n0, lower0, upper0, o0, c0, b0);
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), m2, "提示", JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
}
}
public class cancelListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String m1 = "您已经取消创建文件,将退出程序。";
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), m1, "提示", JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
}
}
}
3、做题界面
public class homework extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
public static List<Integer> answer0 = new ArrayList<Integer>();
JTextField answer = new JTextField(4);
JTextField name0 = new JTextField(4);
public static String name = "匿名";
JButton submit = new JButton("确认");
static int count = 0;
public static List<String> wrong = new ArrayList<String>();
static int wrongNum = 0;
static long endTime;
Font f = new Font("楷体", Font.BOLD, 19);
// 答題
public homework() throws InterruptedException {
ImageIcon background = new ImageIcon("img/1.jpg");
JLabel label = new JLabel(background);
ImageIcon flag = new ImageIcon("img/3.jpg");
setIconImage(flag.getImage());
label.setBounds(0, 0, background.getIconWidth(), background.getIconHeight());
/*
* 主界面获得容器JPanel
*/
getLayeredPane().add(label, new Integer(Integer.MIN_VALUE));
JPanel jp = (JPanel) getContentPane();
/*
* JPanel对象才可以调用setOpaque(false);设置是否透明
*/
jp.setOpaque(false);
JPanel jpanel = new JPanel(new BorderLayout());
jpanel.setOpaque(false);
JPanel p1 = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 20));
JLabel message = new JLabel();
message.setSize(360, 160);
message.setFont(new Font("楷体", Font.BOLD, 20));
dataDeal.JlabelSetText(message, getmessage() + "=");
p1.add(message);
p1.add(answer);
p1.setOpaque(false);
JPanel p2 = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
p2.add(submit);
p2.setOpaque(false);
jpanel.add(p1, BorderLayout.CENTER);
jpanel.add(p2, BorderLayout.SOUTH);
add(jpanel);
submit.addActionListener(new submitListener1());
}
// 用戶名
public homework(String name1) {
ImageIcon background = new ImageIcon("img/4.jpg");
JLabel label = new JLabel(background);
ImageIcon flag = new ImageIcon("img/3.jpg");
setIconImage(flag.getImage());
label.setBounds(0, 0, background.getIconWidth(), background.getIconHeight());
/*
* 主界面获得容器JPanel
*/
getLayeredPane().add(label, new Integer(Integer.MIN_VALUE));
JPanel jp = (JPanel) getContentPane();
/*
* JPanel对象才可以调用setOpaque(false);设置是否透明
*/
jp.setOpaque(false);
JPanel jpanel = new JPanel(new BorderLayout());
jpanel.setOpaque(false);
JPanel p1 = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 20));
JLabel user = new JLabel("用户名:");
user.setFont(f);
user.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
setTitle("请使用英文字符或数字");
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
});
p1.add(user);
p1.add(name0);
p1.setOpaque(false);
JPanel p2 = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
p2.add(submit);
p2.setOpaque(false);
jpanel.add(p1, BorderLayout.CENTER);
jpanel.add(p2, BorderLayout.SOUTH);
add(jpanel);
submit.addActionListener(new submitListener2());
}
// 結果
public homework(int size) throws IOException {
ImageIcon flag = new ImageIcon("img/3.jpg");
setIconImage(flag.getImage());
long spentTime = (endTime - fileread.startTime) / 1000;
int size0 = wrong.size() / 2;
int size1 = size - size0;
int goal = size1 * 100 / size;
String text = "<p style='font-family:楷体; font-size:19'>" + name + " 本次用时<span style='color:red'><strong> "
+ dataDeal.getTimeStrBySecond(spentTime) + " </strong></span>,得分<span style='color:red'><strong> "
+ goal + " </strong></span>分。<br>";
if (size0 == 0) {
text += "你总共答了<span style='color:red'><strong> " + size
+ " </strong></span>道题,并全部答对!<span style='color:red'><strong>恭喜!</strong></span></p>";
} else {
text += "你总共答了<span style='color:red'><strong> " + size
+ " </strong></span>道题,答对<span style='color:red'><strong> " + size1
+ " </strong></span>道,答错<span style='color:red'><strong> " + size0
+ " </strong></span>道,分别为:</p><p><table border=0>";
for (int i = 0; i < (size0 * 2); i++) {
text += "<tr><td style='font-family:楷体; font-size:19'><strong>" + wrong.get(i++)
+ " </strong></td><td width='180' style='font-family:楷体; font-size:19;color:red'><strong> "
+ wrong.get(i) + "</strong></td></tr>";
}
}
text += "</table></p>";
text += "<p style='font-family:楷体; font-size:19'>" + createFile.record(name, goal) + "</p>";
JTextPane textarea = new JTextPane();
textarea.setContentType("text/html");
textarea.setText(text);
textarea.setEditable(false);
JScrollPane textAreascrollPane = new JScrollPane(textarea);
add(textAreascrollPane, BorderLayout.CENTER);
}
private String getmessage() {
String message = fileread.s.get(count);
return message;
}
class submitListener1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
String lineTxt = getmessage();
int temp = 0;
try {
temp = Integer.parseInt(answer.getText());
} catch (NumberFormatException e2) {
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "请输入一个整数", "提示",
JOptionPane.INFORMATION_MESSAGE);
return;
}
answer0.add(temp);
int result = fileread.result.get(count);
int answer = homework.answer0.get(count++);
if (result != answer) {
wrong.add(lineTxt + " = " + answer);
wrong.add("正确答案:" + result);
wrongNum++;
}
int size = fileread.s.size();
if (count < size) {
homework frame = null;
try {
frame = new homework();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
frame.setTitle("做题");
frame.setSize(480, 180);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
} else {
endTime = System.currentTimeMillis();
homework frame2 = null;
try {
frame2 = new homework(size);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
frame2.setTitle("结果");
frame2.setSize(600, 400);
frame2.setLocationRelativeTo(null);
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame2.setVisible(true);
}
dispose();
}
}
class submitListener2 implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (!name0.getText().equals("")) {
name = name0.getText();
}
// System.out.println(name);
dispose();
String temppath = fileread.pathh();
String filePath = temppath;
fileread.readTxtFile(filePath);
}
}
}
四、界面展示
1、出题做题选择界面
2、选择出题界面
选中特定框时有提示输入要求
3、出题成果
4、做题用户名界面
5、选择题目文件界面,限制txt文件
6、题目上传成功并开始计时页面
7、做题界面
8、用户第一次做题界面
9、用户再次做题界面
五、结对的好处
我是和室友结对编程,一个人可能会比较懒,打着打着就不想打了,或者遇到不会解决的问题,而两个人能互相监督,互相讨论,一起解决问题。因为是室友所以时间安排都大致相同,两个人交流也基本不会产生分歧,但两个人的能力都不是很好,所以有的问题都不会解决,但两个人的话不会那么烦躁,不会首先想要放弃,而是一起努力去解决。
六、PSP
PSP2.1 | 任务内容 | 计划共完成需要的时间(h) | 实际完成需要的时间(h) |
---|---|---|---|
Planning | 计划 | 0.5 | 0.5 |
· Estimate | · 估计这个任务需要多少时间,并规划大致工作步骤 | 0.5 | 0.5 |
Development | 开发 | 30 | 41 |
· Analysis | · 需求分析(包括学习新技术) | 5 | 6 |
·Design Spec | · 生成设计文档 | 0 | 0 |
· Design Review | · 设计复审 (和同事审核设计文档) | 0 | 0 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 1 | 1 |
· Design | · 具体设计 | 1 | 1.5 |
· Coding | · 具体编码 | 10 | 20 |
· Code Review | · 代码复审 | 2 | 2.5 |
· Test | · 测试(自我测试,修改代码,提交修改) | 11 | 10 |
Reporting | 报告 | 2 | 3 |
· Test Report | · 测试报告 | 0 | 0 |
· Size Measurement | · 计算工作量 | 0.5 | 0.5 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 1.5 | 2.5 |
七、总结
这次我开始的时候是想做网页版的,但做好基本页面之后发现JSP不太会,跟后端的连接总出问题,于是后来改为做GUI版的了。虽然java的GUI我也不太熟,但之前上课的时候讲过,重新查资料学习会比较快。这次基本上也是边学边打,GUI的函数很多,写界面的时候基本都是查资料才写出来的,所以在编程上花费了很多时间。但因为是两个人一起打,相互鼓励,就没有上一次那么烦躁。之前学习GUI的时候,我一直以为自己用不到,所以没有认真去学,导致这次学习了很久,我才觉得不能忽视那些知识,你不知道什么时候就能用上,多学习总是没错的。