今天只有这一个work,算是一个小程序的说,是用到了
如何进行分层设计程序
文件输入流和输出流的使用
对象,是对象输入流和输出流的使用
熟悉了图形界面及其事件处理
给出的结果运行实例为
文本区域显示选择题,下面点击第几题,文本区域显示对应题目,选择ABCD,依次完成10道选择题,最后选择保存成绩。
10道题目的获取是从文本文件获得,题目有一定的格式,用#分隔
XXXXXXXXXXXXXXXXX?#A.XXX#B.XXX#C.XXX#D.XXX#B.XXX
首先确定的是两个实体类
学生类在最后保存成绩的时候用到了,Choice是这次的主角:问题,选项数组,正确答案。
package Java的简易考试系统;
/*
* 单项选择题实体类*/
public class Choice {
String question;
String[] answer;
String correct;
public Choice(String q,String[] a,String c){
super();
this.question=q;
this.answer=a;
this.correct=c;
}
public void setQues(String q) {
this.question=q;
}
public String getQues() {
return question;
}
public void setAns(String[] a) {
this.answer=a;
}
public String[] getAns() {
return answer;
}
public void setCorr(String c) {
this.correct=c;
}
public String getCorr() {
return correct;
}
}
package Java的简易考试系统;
import java.io.Serializable;
public class Student implements Serializable{
private String name;
private int score;
public Student(String n,int s){
super();
this.name=n;
this.score=s;
}
public String getName() {
return name;
}
public void setName(String n) {
this.name=n;
}
public int getScore() {
return score;
}
public void setScore(int s) {
this.score=s;
}
public String toString() {
return "Student[number="+name+",score="+score+"]";
}
}
两个实体类的编写都是很简单的,所以最主要就是要实现操作类。 先是单选题的操作类,主要写从文件中读取出题目,放入List类的集合里面。
package Java的简易考试系统;
/*
* 单选题操作类*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
public class ChoiceDao {
List<Choice> choices=new ArrayList<Choice>();
int[] rand=new int[4];
public List<Choice> getAllChoices(){
try{
readFromfile();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
return choices;
}
public void readFromfile() throws IOException {
Reader r=new FileReader(new File("D:/A-大三-Java学习/choicetest.txt")); //创建文件字符输入流
//使之带有缓冲功能
BufferedReader br=new BufferedReader(r);
String choiceString=null;
String[] choice=new String[6];
while ((choiceString=br.readLine())!=null){
choice=choiceString.split("#");
shuffle();
choices.add(new Choice(choice[0],new String[]{choice[rand[0]],choice[rand[1]],choice[rand[2]],choice[rand[3]]},choice[choice.length-1]));
}
}
//打乱题目顺序,用到了俩for循环
private void shuffle(){
//int[] rand=new int[4];
Random random=new Random();
for (int i=0;i<rand.length;i++){
rand[i]=random.nextInt(4)+1;
for (int j=0;j<=i-1;j++){
if (rand[i]==rand[j]){
i--;
break;
}
}
}
}
}
文件的读取用到了bufferedreader,是才认识到的然后看到while里面的split函数了没,很好的将字符串进行分割,放入数组
我在那个add()使用这里当时遇到了问题,一直参数不对,直接add字符串数组,后来才明白怎么add()
还使用了打乱题目顺序的方法,值得学习。
package Java的简易考试系统;
/*
* 学生操作类*/
public class StudentDao extends ObjectDao{
//具体实现保存学生
public static void saveStudent(Student student,String filename){
saveObject(student, filename);
}
public static Student readStudent(String filename) {
return (Student)readObject(filename);
}
public static int getScore(Choice choice,String answer) {
int score=0;
String correct=choice.getCorr();
if ("A".equals(answer))
score=judge(choice, 0, correct);
else if ("B".equals(answer))
score=judge(choice, 1,correct);
else if ("C".equals(answer))
score=judge(choice, 2, correct);
else if ("D".equals(answer))
score=judge(choice, 3, correct);
return score;
}
private static int judge(Choice c,int i,String coo) {
String userAnswer=c.getAns()[i]; //难得见到如此表达样子
if (coo.equals(userAnswer))
return 2;
return 0;
}
}
以上学生类操作,继承了对象操作类
package Java的简易考试系统;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/*对象保存和读取通用类*/
public class ObjectDao {
//保存对象
public static void saveObject(Object ob,String fileName){
ObjectOutputStream oos=null;
try {
FileOutputStream fos=new FileOutputStream(new File("D:/A-大三-Java学习/"+fileName+".txt"));
oos=new ObjectOutputStream(fos);
oos.writeObject(ob);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException r){
r.printStackTrace();
} finally{
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//读取对象
public static Object readObject(String fileName){
ObjectInputStream ois=null;
Object ob=null;
try{
FileInputStream fis=new FileInputStream(new File("D:/A-大三-Java学习/"+fileName+".txt"));
ois=new ObjectInputStream(fis);
ob=ois.readObject();
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
} catch (ClassNotFoundException e){
e.printStackTrace();
} finally {
try {
ois.close();
} catch (IOException e2) {
e2.printStackTrace();
}
}
return ob;
}
}
这两个操作主要完成的就是对象的保存和读取,另外学生多了一个操作就是判断答题是否正确最终UI设计及其事件处理还是挺小有难度。
package Java的简易考试系统;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class ChoiceWindowTest extends JFrame{
private List<Choice> choiceList=new ArrayList<Choice>();
private JButton[] no=new JButton[10];
private JComboBox[] choices=new JComboBox[10];
private ChoiceDao choicedao=new ChoiceDao();
private Choice choice=null;
int j=0;
private int score;
public static void main(String[] args) {
new ChoiceWindowTest("选择题");
}
public ChoiceWindowTest(String title){
super(title);
//设置窗口居中
Toolkit tk=Toolkit.getDefaultToolkit();
Dimension d=tk.getScreenSize();
setSize(d.width/2,d.height/2);
setLocation(d.width/4, d.height/4);
//设置窗口大小不可调整
setResizable(false);
//创建10行15列的文本域组件
final JTextArea choiceArea=new JTextArea(10,15);
choiceArea.setText("请选择题号,然后在相应题号下面作答");
//设置不可编辑
choiceArea.setEditable(false);
//添加到jf容器的中央区域
this.add(choiceArea);
//创建2行1列的中央容器
JPanel timu=new JPanel();
timu.setLayout(new GridLayout(2, 1));
//创建1行10列的子容器来存放题号按钮
JPanel noPanel=new JPanel();
noPanel.setLayout(new GridLayout(1, 10));
//创建1行10列的子容器来存放选项下拉
JPanel choicePanel=new JPanel();
choicePanel.setLayout(new GridLayout(1, 10));
//获取所有单选题
choiceList=choicedao.getAllChoices();
for (int i=0;i<no.length;i++){
//创建10个按钮并添加到noPanel
no[i]=new JButton("第"+(i+1)+"题");
noPanel.add(no[i]);
no[i].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
choiceArea.setText(" ");
if (e.getActionCommand().equals("第10题")){
j=9;
choice=choiceList.get(9);
}
else{
//第二题,e.getActionCommand().charAt(1)取出的是字符'2'
//49是'1','2'-'1'得出应该取得的下标是1
j=e.getActionCommand().charAt(1)-49;
choice=choiceList.get(e.getActionCommand().charAt(1)-49);
}
//在Area区域追加问题和选项
choiceArea.append(choice.getQues()+"\n");
choiceArea.append("A."+choice.getAns()[0]+"\n");
choiceArea.append("B."+choice.getAns()[1]+"\n");
choiceArea.append("C."+choice.getAns()[2]+"\n");
choiceArea.append("D."+choice.getAns()[3]+"\n");
}
});
//创建下拉表并添加到对应的choicePanel
choices[i]=new JComboBox(new String[]{"-","A","B","C","D"});
choicePanel.add(choices[i]);
}
timu.add(noPanel);
timu.add(choicePanel);
this.add(timu,"South");
//紧凑显示
this.pack();
//设置单击”关闭“按钮什么都不做
//this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
setVisible(true);
}
//处理窗口事件
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
//如果窗口正在关闭
if (e.getID()==WindowEvent.WINDOW_CLOSING){
//弹出确认对话框
int result=JOptionPane.showConfirmDialog(this, "保存结果吗?\n必须一次性做完所有题\n是 ,覆盖以前结果\n否,不保存任何内容","保存",JOptionPane.YES_NO_CANCEL_OPTION);
if (result==JOptionPane.YES_OPTION){
String name=JOptionPane.showInputDialog("请输入您的学号:");
//计算成绩
computeScore();
Student stu=new Student(name, score);
//保存结果
StudentDao.saveStudent(stu, name); //文件名为输入的序号
JOptionPane.showInternalMessageDialog(this, "成功保存结果","消息",JOptionPane.INFORMATION_MESSAGE);
System.exit(1);
} else if (result==JOptionPane.NO_OPTION){
JOptionPane.showInternalMessageDialog(this, "结果不保存","消息",JOptionPane.INFORMATION_MESSAGE);
System.exit(1);
} else if (result==JOptionPane.CANCEL_OPTION){
}
}
else{
super.processWindowEvent(e);
}
}
//计算得分
public void computeScore() {
for (int i=0;i<choices.length;i++){
Choice ch=choiceList.get(i);
//获取下拉列表用户选择的答案
String a=(String)choices[i].getSelectedItem();
score+=StudentDao.getScore(ch, a);
}
}
}
在定义显示部分的jpanel这里,才明白怎么可以很规范布局,题号,选项,显示区,都是很层次分明的。题号的鼠标事件里面,if那里现在也没明白是干什么用的......
哦是获取choiceList对应的下标,就是题号,里面的题,因为10会越界。
发现,一定要搞明白choice和choiceList,这只要明明白白了,很简单的。
遗憾的是,成功保存和不保存那里应该还是有小问题的,并且保存的文件打开显示全是乱码。但这都不影响今天的小锻炼。
版权声明:本文为zy_dream原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。