课程设计
实验目的:
1.掌握使用Java语言开发一个系统的思路
2.掌握面向对象程序设计的思想
实验内容:
任务一单机版考试系统的设计
子任务1 设计内容
本系统可以进行任何标准化考试,提供了身份验证、试题选取,查看分数,计时器,试题显示读取试题,计算分数等功能。此考试系统,对各专业课程的问卷进行整理入库,以便在需要的时候能够及时、方便、快速的对学生进行各级测试,从而使考试过程趋于简单化,减少教师在这方面的工作负担。
在以往的教学中,教师通过考试来检验学生的学习成果,而这就需要教师进行大量的工作,编写试题,排版,印刷,还要对学生的考卷进行解析,不仅耗费了大量的时间也花费了大量的精力。这种繁重的工作严重的影响了教师的工作效率,这些都成为教学现代化发展的严重阻碍。在此情况下,急需一个应用计算机来进行标准化考试的系统来实现教务工作的自动化或半自动化管理。
本系统适用各级院校的考试项目,其主要功能分为:
身份验证——可以检测用户的身份。
试题选择——在此可以对考试题进行选择,找到你所要的试题类型。
查分系统——用于教师或学生对所答题进行核对。
计时系统——对考试的时间进行规定,可以根据所需来自己制定。
试题显示——对考生多进行的考试内容惊醒显示的区域。
本系统适合各级院校的标准考试,可以有效的提高教师的工作效率。
整个系统的开发过程严格遵循软件工程的要求,做到模块化设计。
子任务2 设计要求
根据本系统的需要本系统可以进行任何标准化考试,提供了试题选取,查看分数,计时器,试题显示读取试题,计算分数等功能。此考试系统,对各专业课程的问卷进行整理入库,以便在需要的时候能够及时、方便、快速的对学生进行各级测试,从而使考试过程趋于简单化,减少教师在这方面的工作负担。
1、用户可以选择一套标准化考试试题。
2、每套试题的考试用时由试题文件或试题数据库给出。
3、开始读取试题后,计时器开始计划时,用户提交答案后,可以读取下一道题目。
4、一个提示栏显示所剩余的考试时间,当规定时间用尽后,用户将不能再读取任何题目。
5、为了增加模拟考试练习的灵活性,用户也可以选择暂停计时。
6、用户答完一个题目后,可以查看该题目的正确答案和目前所得分数。
子任务3 总体设计
本标准化考试系统由4个java源文件和若干个试题文件组成。
试题文件为文本文件,名字任意,扩展名为txt。
(1)文件内容必须遵守如下的书写规范:
1)试题文件的第一行是全部试题的答案,答案之间不可以有空格。
2)第二行是试题文件的考试用时,如0:36:45
3)第道题目之间用“**”开头的字符串分割。
4)最后一行是endend
如下例所示:
AADAB
1:12:48
1、有关Java语言的说法中,哪种是错误的()
A、Java是高级语言
B、Java是编译型语言
C、Java是结构化设计语言
D、
Java是移植性强的语言
*******************************************
2、Java用来定义一个新类时,所使用的关键字为()
A、class
B、public
C、struct
D、class 或struct
*******************************************
3、一个可以独立运行的Java应用程序( )
A、可以有一个或多个main方法
B、最多只能有两个main方法
C、可以有一个
或零个main方法D、只能有一个main方法
*******************************************
4、设x=40 则y=(++x)+1和y=(x++)+1的结果,使y分别为( )
A、42,42
B、41,41
C、41,42
D、42,41
*******************************************
5、设数组Array由以下语句定义
int Array=new int[10],则数组最后一个元素的正确引用方法为( )
A、Array[10]
B、Array[9]
C、array[10]
D、array[9]
*******************************************
endend
任务二单机版考试系统的开发
子任务1 身份验证Login类
该任务完成标准化考试系统的身份验证功能。
1、成员变量
成员变量的定义见表9-1。
表9-1 定义成员变量
表9-1 主要成员变量
2、成员方法
成员方法的定义见表9-2。
表9-2 定义成员方法
表9-2 主要成员方法
3、部分代码段
……
try{
stmt = con.createStatement();
ps = con.prepareStatement("select PWD from LoginRecord where ID=?");
ps.setString(1, ID);
rs = ps.executeQuery();
if(rs.next()){
if(rs.getString("PWD").equals(PWD)){
new JavaTest();
System.out.println("OK");
} else
JOptionPane.showMessageDialog( null , "你输入的密码错误!",
"登录失败" , JOptionPane.ERROR_MESSAGE) ;
} else{
JOptionPane.showMessageDialog( null , "你输入的用户名错误!", "登录失败" , JOptionPane.ERROR_MESSAGE) ;
}
} catch(final SQLException e){
System.err.println("SQLException:" + e.getMessage());
} finally{
if(stmt != null){
try{
stmt.close();
} catch(final SQLException e) {
}
}
if(con != null){
try{
con.close();
} catch(final SQLException e) {
}
}
}
……
子任务2 考试系统JavaTest类
1、成员变量
成员变量的定义见表9-3。
表9-3 定义成员变量
表9-3 主要成员变量
2、成员方法
成员方法的定义见表9-4。
表9-4 定义成员方法
表9-4 主要成员方法
3、部分代码
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JavaTest extends JFrame implements ActionListener{ TestArea testPanel=null;
Container con=null;
private JMenu File = new JMenu("文件");
private JMenu Edit = new JMenu("编辑");
private JMenu Help = new JMenu("帮助");
JMenuItem Open = new JMenuItem("打开");
JMenuItem Exit = new JMenuItem("退出");
public JavaTest(){
super("标准化模拟考试");
testPanel=new TestArea();
con=getContentPane();
con.add(testPanel,BorderLayout.CENTER);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
}
setVisible(true);
setBounds(60,40,660,460);
con.validate();
validate();
// 添加菜单栏
JMenuBar JMB = new JMenuBar();
File.add(Open);
File.add(Exit);
JMB.add(File);
JMB.add(Edit);
JMB.add(Help);
setJMenuBar(JMB);
Open.addActionListener(this);
Exit.addActionListener(this);
// 添加结束
}
}
子任务3 考试区域TestArea类
1、成员变量
成员变量的定义见表9-5。
表9-5 定义成员变量
2、成员方法
成员方法的定义见表9-6。
表9-6 定义成员方法
表9-6 主要成员方法
3、文本文件方式部分代码
public TestArea(){
list= new Choice();
String currentdir=System.getProperty("user.dir");
System.out.println(currentdir);
File dir=new File(currentdir);
FileName fileTxt=new FileName("txt");
String fileName[]=dir.list(fileTxt);
for(int i=0;i list.add(fileName[i]); } testplay=new JTextArea(15,12); testplay.setLineWrap(true); testplay.setWrapStyleWord(true); testplay.setFont(new Font("TimesRoman",Font.PLAIN,14)); testplay.setForeground(Color.blue); messagearea=new JTextArea(8,8); messagearea.setForeground(Color.blue); messagearea.setLineWrap(true); messagearea.setWrapStyleWord(true); countTime=new Thread(this); String s[]={"A","B","C","D"}; box=new JCheckBox[4]; for(int i=0;i<4;i++){ box[i]=new JCheckBox(s[i]); } pauseorcontinuetime=new JButton("暂停计时"); pauseorcontinuetime.addActionListener(this); commitresult=new JButton("提交该题答案"); readnext=new JButton("读取第一题"); readnext.setForeground(Color.blue); commitresult.setForeground(Color.blue); viewscore=new JButton("查看分数"); viewscore.setForeground(Color.blue); commitresult.setEnabled(false); commitresult.addActionListener(this); readnext.addActionListener(this); viewscore.addActionListener(this); list.addItemListener(this); readtests=new ReadTestquestion(); JPanel pAddbox=new JPanel(); for(int i=0;i<4;i++){ pAddbox.add(box[i]); } Box boxH1=Box.createVerticalBox(), boxH2=Box.createV erticalBox(), baseBox=Box.createHorizontalBox(); boxH1.add(new JLabel("选择试题文件")); boxH1.add(list); boxH1.add(new JScrollPane(messagearea)); boxH1.add(viewscore); timeShow=new JTextField(20); timeShow.setHorizontalAlignment(SwingConstants.RIGHT); timeShow.setEditable(false); JPanel p1=new JPanel(); p1.add(new JLabel("剩余时间:")); p1.add(timeShow); p1.add(pauseorcontinuetime); boxH1.add(p1); boxH2.add(new JLabel("试题内容:")); boxH2.add(new JScrollPane(testplay)); JPanel p2=new JPanel(); p2.add(pAddbox); p2.add(commitresult); p2.add(readnext); boxH2.add(p2); baseBox.add(boxH1); baseBox.add(boxH2); setLayout(new BorderLayout()); add(baseBox,BorderLayout.CENTER); welcomeLabel=new JLabel("欢迎考试,提高英语水平",JLabel.CENTER); welcomeLabel.setFont(new Font("隶书",Font.PLAIN,24)); welcomeLabel.setForeground(Color.blue); add(welcomeLabel,BorderLayout.NORTH); } public void itemStateChanged(ItemEvent e){ timeShow.setText(null); iclosetime=false; ipausetime=false; pauseorcontinuetime.setText("暂停计时"); String name=(String)list.getSelectedItem(); readtests.setFilename(name); readtests.settestover(false); time=readtests.getTime(); if(countTime.isAlive()){ iclosetime=true; countTime.interrupt(); } countTime=new Thread(this); messagearea.setText(null); testplay.setText(null); readnext.setText("读取第一题"); commitresult.setEnabled(false); readnext.setEnabled(true); welcomeLabel.setText("欢迎考试,你选择的试题:"+readtests.getFilename()); } public void actionPerformed(ActionEvent e){ if(e.getSource()==readnext){ readnext.setText("读取下一题"); commitresult.setEnabled(true); String contentTest=readtests.getTestContent(); testplay.setText(contentTest); messagearea.setText(null); readnext.setEnabled(false); try{ countTime.start(); } catch(Exception event) { } } if(e.getSource()==commitresult){ readnext.setEnabled(true); commitresult.setEnabled(false); String answer="?"; for(int i=0;i<4;i++){ if(box[i].isSelected()){ answer=box[i].getText(); box[i].setSelected(false); break; } } readtests.setSelection(answer); } if(e.getSource()==viewscore){ int score=readtests.getScore(); String messages=readtests.getMessages(); messagearea.setText("分数:"+score+"\n"+messages); } if(e.getSource()==pauseorcontinuetime){ if(ipausetime==false){ pauseorcontinuetime.setText("继续计时"); ipausetime=true; } else if(ipausetime==true) { pauseorcontinuetime.setText("暂停计时"); ipausetime=false; countTime.interrupt(); } } } public synchronized void run(){ while(true){ if(time<=0){ iclosetime=true; countTime.interrupt(); commitresult.setEnabled(false); readnext.setEnabled(false); timeShow.setText("用时尽,考试结束"); } else if(readtests.gettestover()){ iclosetime=true; timeShow.setText("考试效果:分数*剩余时间(秒)= "+1.0*readtests.getScore()*(time/1000)); countTime.interrupt(); commitresult.setEnabled(false); readnext.setEnabled(false); } else if(time>=1) { time=time-1000; long leftTime=time/1000; long leftHour=leftTime/3600; long leftMinute=(leftTime-leftHour*3600)/60; long leftSecond=leftTime%60; timeShow.setText(""+leftHour+"小时"+leftMinute+"分"+leftSecond+"秒"); } try{ Thread.sleep(1000); } catch(InterruptedException ee) { if(iclosetime==true) return ; } while(ipausetime==true){ try{ wait(); } catch(InterruptedException ee) { if(ipausetime==false) { notifyAll(); } } } } } 子任务4 读取试题ReadTestquestion类 1、成员变量 成员变量的定义见表9-7。 表9-7 定义成员变量 表9-7 主要成员变量 2、成员方法 成员方法的定义见表9-8。 表9-8 定义成员方法 表9-8 主要成员方法 3、文本文件方式部分代码 import java.io.*; import java.util.*; public class ReadTestquestion{ String filename="", correctAnswer="", testContent="" , selection="" ; int score=0; long time=0; boolean testover=false; File f=null; FileReader in=null; BufferedReader read=null; public void setFilename(String name){ filename=name; score=0; selection=""; try{ if(in!=null&&read!=null){ in.close(); read.close(); } f=new File(filename); in=new FileReader(f); read=new BufferedReader(in); correctAnswer=(read.readLine()).trim(); String temp=(read.readLine()).trim() ; StringTokenizer token=new StringTokenizer(temp,":"); int hour=Integer.parseInt(token.nextToken()) ; int minute=Integer.parseInt(token.nextToken()); int second=Integer.parseInt(token.nextToken()); time=1000*(second+minute*60+hour*60*60); } catch(Exception e) { testContent="没有选择试题"; } } public String getFilename(){ return filename; } public long getTime(){ return time; } public void settestover(boolean b){ testover=b; } public boolean gettestover(){ return testover; } public String getTestContent(){ try{ String s=null; StringBuffer temp=new StringBuffer(); if(read!=null){ while((s=read.readLine())!=null){ if(s.startsWith("**")) break; temp.append("\n"+s); if(s.startsWith("endend")){ in.close(); read.close(); testover=true; } } testContent=new String(temp); }else{ testContent=new String("没有选择试题"); } } catch(Exception e) { testContent="试题内容为空,考试结束!!"; } return testContent; } public void setSelection(String s){ selection=selection+s; } public int getScore(){ score=0; int length1=selection.length(); int length2=correctAnswer.length(); int min=Math.min(length1,length2); for(int i=0;i try{ if(selection.charAt(i)==correctAnswer.charAt(i)) score++; } catch(StringIndexOutOfBoundsException e) { i=0; } } return score; } public String getMessages(){ int length1=selection.length(); int length2=correctAnswer.length(); int length=Math.min(length1,length2); String message="正确答案:"+correctAnswer.substring(0,length)+"\n"+ "你的回答:"+selection+"\n"; return message; } } 任务三 单机版考试系统的发布和布署 使用jar.exe 工具将项目中的字节码文件压缩成JAR 文件,来发布本案例的应用程序。 编写一个清单文件Manifestfiles 如下。 Manifest-Version: 1.0 Main-Class: Login.class Created-By: 1.2.2(Sun Microsystems Inc.) 将清单文件命名为moon.mf ,保存到项目目录中。 在编写清单文件时, Manifest-Version: 和1.0;Main-Class: 和Login.class ;Created-By: 和1.2.2(Sun Microsystems Inc.)之间必须有且只有一个空格。 步骤2 使用如下命令生成JAR 文件。 jar cfm Login.jar moon.mf .class c 表示要生成一个新的JAR 文件;f 表示要生成的JAR 文件的名字;m 表示文件清单的名字。 步骤3 为了防止.jar 文件与解压缩软件做关联,而进行自解压,而无法运行本案例的Java 程序。因此需创建一个bat 文件,内容如下: javaw -jar Login.jar 将文件保存为Login.bat 。 步骤4 创建一个帮助文件help.txt ,内容如下: 用户可以用鼠标双击Login.jar 或Login.bat 来运行本软件,但是如果用户的计算机上安装了中文版的WinRAR 解压缩软件,交将.jar 文件与该解压缩软件做了关联,那么,用鼠标双击Login.jar 文件时,WinRAR 解压缩软件会自动运行进行解压缩操作,这时用户可以双击Login.bat 来运行本案例的软件。 步骤5 将Login.jar 以及若干试题文件和试题库拷贝到任何一个安装了java 运行环境的计算机上。 步骤6 若是数据库方式的试题文件读取,需将数据库进行布署。(使用JDBC —ODBC 数据源设置,参考第8章内容) 步骤7 用鼠标双击就可以运行该Java 应用程序了。 任务四 单机版考试系统的测试 步骤1 用户身份验证。 图9-3 应用程序初始界面 运行该应用程序,弹出如图9-3界面。输入错误用户名或密码,弹出如图9-4界面。 图9-4 登录失败界面 用户名和密码正确时,进入考试系统如图9-5所示。 图9-5 考试系统界面 步骤2 选取试题。 单击左侧选择试题文件下拉列表框,选择一个试题文件t2.txt ,如图9-6如示: 单击“读取第一题按钮”,界面如图9-7所示: 图9-7 读取第一题步骤3选择答案。 选择界面下方的单选按钮D选项,如图9-8如示: 图9-8 答案选择 步骤4提交试题答案。 单击“提交该题答案”按钮,如下图9-9所示: 图9-9 提交答案 “提交该题答案”按钮呈灰色,处于不可用状态。 步骤5读取连续的题目。 单击“读取下一题”按钮,刚会读取连续的题目,如图9-10所示: 直到试题内容为空,如图9-11所示: 图9-11 试题文件为空 步骤6计时与暂停计时。 如上图左侧剩余时间文本区一直显示用户完成该试题剩余时间,可通过单击“暂停计时”按钮暂停计时。此时该按钮显示为“继续计时”,如图9-12所示,直到单击“继续计时”按 钮,系统才继续计时。 图9-12 暂停计时 步骤7查看分数。 单击“查看分数”按钮,在界面左侧显示分数,如图9-13所示。 图9-13 查看分数 步骤8退出系统。 考试结束,单击右上角“并闭”按钮或“文件”菜单→“退出”菜单项,考试系统则安全退 出。