JAVA课程设计报告(标准化考试系统)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

课程设计报告
( 2012-- 2013年度第2学期)
标准化考试系统
专业 计算机科学与技术
学生姓名 班级 学

指导教师 完成日期
2013.7
标准化考试系统
目录
目录 (2)
1 概述 (3)
1.1 课程设计目的 (3)
1.2 课程设计内容与要求 (3)
2 系统需求分析 (4)
2.1 系统目标 (4)
2.2 主体功能 (4)
2.3 开发环境 (4)
3 系统总体设计 (5)
3.1 系统的功能模块划分 (5)
3.2 系统流程图 (6)
4 系统详细设计 (7)
4.1 客户端模块设计 (7)
4.1.1 用户登录模块设计(ClientLogin类) (7)
4.1.2 选择试卷模块设计(GetTestFile类) (11)
4.1.3 回答试卷查询模块设计(ClientTestArea类) (15)
4.2 服务器端模块设计 (23)
4.2.1 Server类 (23)
4.2.2 ServerThread类 (25)
4.2.3 ReadTestquestion类 (29)
5 代码调试 (30)
6 软件发布 (31)
7 小结 (32)
参考文献 (33)
Java语言与面向对象技术课程设计
标准化考试系统
1 概述
1.1 课程设计目的
1、加深对《Java语言与面向对象技术》课程基础知识的理解,掌握Java语言面向对象程序设计的开发方法和步骤;
2、进一步理解面向对象程序设计的思想和方法,利用Java语言进行程序设计的能力;
3、课程设计将课本上的理论知识和实际应用相结合,锻炼学生发现问题、分析问题和解决问题的能力。

加强学生研发、编写、调试程序的能力;
4、培养学生在项目开发中团队合作精神、创新意识及能力;
5、提高学生科技论文写作能力,规范完成课程设计报告。

1.2 课程设计内容与要求
设计C/S模式的标准化考试系统,即客户端和服务器端都是Java应用程序,具体要求如下:
(1)用户单击选项卡中的“登录”将出现登录界面。

用户在登录界面输入学号、姓名以及服务器的IP,并请求服务器建立套接字链接。

用户登录的目的是为了将自己的基本信息存放到服务器上,以便服务器记录用户的考试成绩。

因此,用户和服务器建立连接后,服务器将创建一个和用户相关的一个文件,该文件的名字由用户的学号、姓名以及用户所在客户端机器的IP所组成。

(2)单击端选项卡中的“选择试卷”将出现选择试卷界面。

如果用户成功登录,即和服务器建立连接并在服务器端创建了和其相关的文件,那么,用户再选择
标准化考试系统
试卷界面可以将服务器上的试卷文件的名字存放到客户端界面中的下拉式列表中,然后再在下拉列表中选择一个试卷文件的名字提交给服务器。

(3)单击端选项卡中的“答卷”将出现答卷界面。

如果用户成功登录,并且用户通过“选择试卷”界面选择了一套试卷,那么用户在答卷界面可以从服务器读入所选试卷的内容,而且在“答卷”界面可以提交自己的答案给服务器、服务器将用户提交的答案存入用户登录时服务器所创建的和该用户相关的文件中。

提交答案后,在“答卷”界面可以查询分数。

2 系统需求分析
2.1 系统目标
通过本系统能够实现用户登录,选择试卷,完成试卷,查询分数等功能。

2.2 主体功能
A.C/S模式,即客户端与服务器端都是Java应用程序;
B.输入服务器IP地址,连接服务器功能;
C.登录验证功能;
D.学生可以选择所要做的试题;
E.开始考试;
F.完成考试后,学生可以查看自己的分数、试题、正确答案、分值以及自己所选择的答案;
2.3 开发环境
MyEclipse
Java语言与面向对象技术课程设计
3 系统总体设计
3.1 系统的功能模块划分
本系统主要有以下几个功能模块:用户登录,选择试卷,完成试卷,查询分数等。

用户登录选















退出系统
标准化考试系统
客户端窗口
标准化考试系统
3.2 系统流程图
N
Y
开始
输入信息
连接服务器
连接成功 显示登录成功
选择试卷
显示试卷
回答试卷
提交试卷
查看分数
退出
Java语言与面向对象技术课程设计
4 系统详细设计
4.1 客户端模块设计
4.1.1 用户登录模块设计(ClientLogin类)
1、效果图
2、类的主要成员变量和方法
1)成员变量
a、verfyMess是String对象,该字符串的前缀为“学生”,后缀是用户输入学号、姓名以及客户端的IP。

用户登录时需将verifyMess提交给服务器。

b、inputNumber、inputName和inputServerIP是JtextField创建的文本框,用于用户输入学号、姓名和服务器的IP.。

c、hintMess是JLabel创建的标签,用于显示某些提示信息。

d、startCon是JButton创建的对象,该按钮将当前容器注册为自己的ActionEvent 事件监视器。

2)方法
a、ClientLogin()是构造方法,用来创建clientLogin类。

b、actionPerformed(ActionEvent)方法是ClientLogin类实现ActionListener接口中的方法。

ClientLogin创建的容器startCon按钮的ActionEvent事件监视器,当用户单击该按钮时,容器将执行actionPerformed(ActionEvent)方法进行相应的操作。

标准化考试系统
3、主要程序代码
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import .*;
import javax.swing.*;
public class ClientLogin extends JPanel implements ActionListener{
String verifyMess;
JTextField inputNumber,inputName,inputServerIP;
JLabel hintMess;
JButton startCon;
String number,name,IP;
public ClientLogin(){
inputNumber=new JTextField(10);
inputName =new JTextField(10);
hintMess=new JLabel("请输入学号、姓名和服务器的IP",JLabel.CENTER);
hintMess.setFont(new Font("隶书",Font.BOLD,18));
inputServerIP=new JTextField(10);
startCon=new JButton("提交");
startCon.addActionListener(this);
Box box1=Box.createHorizontalBox();
box1.add(new JLabel("输入学号:",JLabel.CENTER));
box1.add(inputNumber);
Box box2=Box.createHorizontalBox();
box2.add(new JLabel("输入姓名:",JLabel.CENTER));
box2.add(inputName);
Box box3=Box.createHorizontalBox();
box3.add(new JLabel("输入IP:"));
box3.add(inputServerIP);
Box box4=Box.createHorizontalBox();
box4.add(new JLabel("单击提交按钮",JLabel.CENTER));
box4.add(startCon);
Box boxH=Box.createVerticalBox();
boxH.add(box1);
Java语言与面向对象技术课程设计
boxH.add(box2);
boxH.add(box3);
boxH.add(box4);
JPanel pCenter=new JPanel();
pCenter.add(boxH);
pCenter.setBackground(new Color(210,210,110));
setLayout(new BorderLayout());
add(pCenter,BorderLayout.CENTER);
JPanel pNorth=new JPanel();
pNorth.setBackground(Color.green);
pNorth.add(hintMess);
add(pNorth,BorderLayout.NORTH);
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==startCon){
number=inputNumber.getText().trim();
name=inputName.getText().trim();
if(number.length()>0&&name.length()>0){
IP=inputServerIP.getText().trim();
try{
LoginThread thread=new LoginThread(hintMess);
if(!(thread.isAlive())){
thread=new LoginThread(hintMess);
thread.makeConnection(number,name,IP);
thread.start();
}
}
catch (Exception ee){
hintMess.setText("无法连接"+ee);
}
}
else{
JOptionPane.showMessageDialog(this,"必须输入学号和姓名","警告",
JOptionPane.WARNING_MESSAGE);
标准化考试系统
}
}
}
}
class LoginThread extends Thread{
Socket socket;
InetSocketAddress socketAddress;
DataInputStream in;
DataOutputStream out;
JLabel hintMess;
LoginThread(JLabel hint){
hintMess=hint;
}
public void makeConnection(String number,String name,String IP) throws IOException { InetAddress address=InetAddress.getByName(IP);
socketAddress=new InetSocketAddress(address,6666);
socket=new Socket();
socket.connect(socketAddress);
in=new DataInputStream(socket.getInputStream());
out=new DataOutputStream(socket.getOutputStream());
out.writeUTF("学生"+number+""+name);
}
public void run(){
String s=null;
while(true){
try{
s=in.readUTF();
if(s.startsWith("成功登录:")){
String verifyMess=s.substring(s.indexOf(":")+1);
GetTestFile.setVerifyMess(verifyMess);
ClientTestArea.setVerifyMess(verifyMess);
GetTestFile.setSocketAddress(socketAddress);
ClientTestArea.setSocketAddress(socketAddress);
hintMess.setText(s);
String tishi="成功登录,请单击左侧的\"选择试卷界面\"";
JOptionPane.showMessageDialog(null,tishi,"操作提示",
JOptionPane.PLAIN_MESSAGE);
if(socket.isClosed()) return;
}
if(s.startsWith("已经成功登录了")){
hintMess.setText(s);
String tishi="已经成功登录了,请单击左侧的\"选择试卷界面\"";
JOptionPane.showMessageDialog(null,tishi,"操作提示",
JOptionPane.PLAIN_MESSAGE);
if(socket.isClosed()) return;
}
}
catch (Exception ee){
hintMess.setText("服务器暂时关闭了,稍后再请求连接");
return;
}
}
}
}
4.1.2 选择试卷模块设计(GetTestFile类)
1、效果图
2、类的主要成员变量和方法
1)成员变量
a、hintMess是JLabel创建的标签,用于显示某些提示信息。

b、list是JComboBox创建的下拉列表,用于显示从服务器得到的试卷文件的名字。

c、getTestFile和submit是JButton创建的对象,其上的名字分别为“列出试卷的名字”和“提交”,该两个按钮都将当前容器注册为自己的ActionEvent事件监视器。

2)方法
a、GetTestFile()是构造方法,用来创建getTestFile类。

b、actionPerformed(ActionEvent)方法是GetTestFile类实现ActionListener接口中的方法。

GetTestFile创建的容器getTestFile和submit按钮的ActionEvent事件监视器,当用户单击getTestFile和submit按钮按钮时,容器都将执行actionPerformed(ActionEvent)方法进行相应的操作。

3、主要程序代码
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import .*;
public class GetTestFile extends JPanel implements ActionListener,Runnable{
static String verifyMess;
static InetSocketAddress socketAddress;
String fileName;
JLabel hintMess;
JButton getTestFile,submit;
JComboBox list;
Socket socket;
DataInputStream in;
DataOutputStream out;
Thread thread;
int n=0;
public GetTestFile(){
hintMess=new JLabel("单击\"列出试卷名字\"按纽从服务器得到试卷的名字");
hintMess.setBackground(Color.green);
getTestFile=new JButton("列出试卷名字");
getTestFile.setBackground(Color.green);
submit=new JButton("提交");
submit.setBackground(Color.orange);
getTestFile.addActionListener(this);
submit.addActionListener(this);
list=new JComboBox();
Box box1=Box.createHorizontalBox();
box1.add(new JLabel("单击\"列出\"按纽:",JLabel.CENTER));
box1.add(getTestFile);
Box box2=Box.createHorizontalBox();
box2.add(new JLabel("选择试卷:",JLabel.CENTER));
box2.add(list);
box2.add(submit);
Box boxH=Box.createVerticalBox();
boxH.add(box1);
boxH.add(box2);
thread=new Thread(this);
JPanel pCenter=new JPanel();
pCenter.add(boxH);
setLayout(new BorderLayout());
pCenter.setBackground(Color.pink);
add(pCenter,BorderLayout.CENTER);
JPanel pNorth=new JPanel();
pNorth.add(hintMess);
add(pNorth,BorderLayout.NORTH);
}
public static void setVerifyMess(String mess){
verifyMess=mess;
}
public static void setSocketAddress(InetSocketAddress address){
socketAddress=address;
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==getTestFile){
list.removeAllItems();
try { makeConnection(); //见后面的makeConnection()方法
out.writeUTF("列出文件:"+verifyMess);
if(!(thread.isAlive())){
thread=new Thread(this);
thread.start();
}
}
catch(Exception ee){
JOptionPane.showMessageDialog(this,"请登录","操作提示",
JOptionPane.PLAIN_MESSAGE);
}
}
if(e.getSource()==submit){
n=list.getItemCount();
if(n>=1){
fileName=(String)list.getSelectedItem();
File file=new File(fileName);
ClientTestArea.setExaminationFile(file);
String tishi="您已经选择了"+fileName+"试卷,请单击左侧的\"答卷界面\"";
JOptionPane.showMessageDialog(this,tishi,"操作提示",
JOptionPane.PLAIN_MESSAGE);
}
}
}
private void makeConnection() throws IOException {
socket=new Socket();
socket.connect(socketAddress);
in=new DataInputStream(socket.getInputStream());
out=new DataOutputStream(socket.getOutputStream());
}
public void run(){
String s=null;
while(true){
try{
s=in.readUTF();
if(s.startsWith("列出文件:")){
String listItem=s.substring(s.indexOf(":")+1);
list.addItem(listItem);
}
if(s.startsWith("已经全部列出:")){
hintMess.setText("试卷名字已经全部列出,请在列表中选择试卷");
hintMess.setBackground(Color.green);
break;
}
if(s.startsWith("请登录")){
JOptionPane.showMessageDialog(this,"请登录","操作提示",
JOptionPane.PLAIN_MESSAGE);
break;
}
}
catch (Exception ee){}
}
}
}
4.1.3 回答试卷查询模块设计(ClientTestArea类)
1、效果图
2、类的主要成员变量和方法
1)成员变量
a、hintMess是JLabel创建的标签,用于显示某些提示信息。

b、examineArea是JPanel创建的容器,用于显示试题和答题卡。

c、handAnswer,startTest和lookScore是JButton创建的对象,其上的名字分别为“提交答案”、“显示试卷”和“查看分数”,这三个按钮都将当前容器注册为自己的ActionEvent事件监视器。

2)方法
a、ClientTestArea()是构造方法,用来创建clientTestArea类。

b、actionPerformed(ActionEvent)方法是ClientTestArea类实现ActionListener接口中的方法。

ClientTestArea创建的容器是handAnswer,startTest和lookScore按钮的ActionEvent事件监视器,当用户单击handAnswer,startTest和lookScore按钮时,容器都将执行actionPerformed(ActionEvent)方法进行相应的操作。

3、主要程序代码
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import .*;
import java.util.*;
public class ClientTestArea extends Panel implements ActionListener,Runnable{ static String verifyMess;
static InetSocketAddress socketAddress;
static File examinationFile;
ArrayList<JRadioButton> choiceList;
Socket socket;
DataInputStream in;
DataOutputStream out;
Thread thread;
static JPanel examineArea;
JLabel hintMess;
JButton handAnswer,startTest,lookScore;
public ClientTestArea(){
thread=new Thread(this);
choiceList=new ArrayList<JRadioButton>();
examineArea=new JPanel();
examineArea.setForeground(Color.blue);
handAnswer=new JButton("提交答案");
startTest=new JButton("显示试卷");
lookScore=new JButton("查看分数");
handAnswer.setEnabled(false);
lookScore.setEnabled(false);
hintMess=new JLabel("单击\"显示试卷\"按纽从服务器得到试卷");
startTest.addActionListener(this);
handAnswer.addActionListener(this);
lookScore.addActionListener(this);
setLayout(new BorderLayout());
JPanel pCenter=new JPanel();
pCenter.setBackground(Color.yellow);
pCenter.setLayout(new BorderLayout());
pCenter.add(new JScrollPane(examineArea),BorderLayout.CENTER);
add(pCenter,BorderLayout.CENTER);
JPanel pSouth=new JPanel();
pSouth.setBackground(Color.blue);
pSouth.add(handAnswer);
pSouth.add(startTest);
pSouth.add(lookScore);
add(pSouth,BorderLayout.SOUTH);
JPanel pNorth=new JPanel();
pNorth.setBackground(Color.green);
pNorth.add(hintMess);
add(pNorth,BorderLayout.NORTH);
}
public static void setVerifyMess(String mess){
verifyMess=mess;
}
public static void setSocketAddress(InetSocketAddress address){
socketAddress=address;
}
public static void setExaminationFile(File f){
examinationFile=f;
examineArea.removeAll();
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==startTest){
choiceList.clear();
lookScore.setEnabled(false);
try{ makeConnection();
examineArea.removeAll();
out.writeUTF("显示试卷:"+verifyMess+"#"+examinationFile.getName());
String m="读入的试题:"+examinationFile+"将刷新当前的试题,是否确认继续";
int ok=JOptionPane.showConfirmDialog(this,m,"确认对话框",
JOptionPane.YES_NO_OPTION,RMATION_MESSAGE);
if(ok==JOptionPane.YES_OPTION){
if(!(thread.isAlive())){
thread=new Thread(this);
thread.start();
}
handAnswer.setEnabled(true);
}
}
catch(Exception exp){
JOptionPane.showMessageDialog(this,"您未登录或选择试卷","操作提示",
JOptionPane.PLAIN_MESSAGE);
}
}
if(e.getSource()==handAnswer){
String m="只有一次提交答案的机会!,一旦提交将无法继续答题,是否确认提交答案";
int ok=JOptionPane.showConfirmDialog(this,m,"确认对话框",
JOptionPane.YES_NO_OPTION,RMATION_MESSAGE);
if(ok==JOptionPane.YES_OPTION){
StringBuffer str=new StringBuffer();
for(int i=0;i<choiceList.size();i++){
JRadioButton box=choiceList.get(i);
if(box.isSelected())
str.append(box.getText());
}
String myAnswer=new String(str);
try{ makeConnection();
out.writeUTF("提交的答案:"+verifyMess+"#"+myAnswer);
handAnswer.setEnabled(false);
lookScore.setEnabled(true);
}
catch(Exception exp){
JOptionPane.showMessageDialog(this,"您未登录或选择试卷","操作提示",
JOptionPane.PLAIN_MESSAGE);
}
}
}
if(e.getSource()==lookScore){
StringBuffer str=new StringBuffer();
for(int i=0;i<choiceList.size();i++){
JRadioButton box=choiceList.get(i);
if(box.isSelected())
str.append(box.getText());
}
String myAnswer=new String(str);
try{ makeConnection();
out.writeUTF("查看得分:"+verifyMess+"#"+myAnswer+"*"+examinationFile.getName());
if(!(thread.isAlive())){
thread=new Thread(this);
thread.start();
}
}
catch(Exception exp){
JOptionPane.showMessageDialog(this,"您未登录或选择试卷","操作提示",
JOptionPane.PLAIN_MESSAGE);
}
}
}
private void makeConnection() throws IOException {
socket=new Socket();
socket.connect(socketAddress);
in=new DataInputStream(socket.getInputStream());
out=new DataOutputStream(socket.getOutputStream());
}
public void run(){
while(true){
String s=null;
try{
s=in.readUTF();
if(s.startsWith("试卷内容:")){
String content=s.substring(s.indexOf(":")+1);
StringReader read=new StringReader(content);
BufferedReader in= new BufferedReader(read);
String str=null;
int number=0;
while((str=in.readLine())!=null){ //计算出题目总数
if(str.trim().startsWith("答题卡"))
number++;
}
examineArea.setLayout(new GridLayout(number,2));//第2列上放置答题卡
JTextArea [] text=new JTextArea[number];
for(int i=0;i<text.length;i++){
text[i]=new JTextArea(4,10);
text[i].setLineWrap(true);
text[i].setWrapStyleWord(true);
text[i].setFont(new Font("宋体",Font.BOLD,14));
}
in.close();
out.close();
read=new StringReader(content);
in= new BufferedReader(read);
int i=0;
while((str=in.readLine())!=null){
if(!(str.trim().startsWith("答题卡")))
text[i].append(str+"\n"); //text[i]中显示第i题的内容else{
examineArea.add(new JScrollPane(text[i]));
i++;
JRadioButton [] box=new JRadioButton[4];
ButtonGroup group=new ButtonGroup();
String [] choiceChar={"A","B","C","D"};
for(int k=0;k<4;k++){
box[k]=new JRadioButton(choiceChar[k],true);
group.add(box[k]);
}
JPanel pAddbox=new JPanel();
pAddbox.setBackground(Color.yellow);
pAddbox.setBorder(BorderFactory.createRaisedBevelBorder());
FlowLayout flow=new FlowLayout();
flow.setAlignment(FlowLayout.LEFT);
flow.setHgap(5);
pAddbox.setLayout(flow);
pAddbox.add(new JLabel("答题卡:"));
for(int k=0;k<4;k++){
pAddbox.add(box[k]);
choiceList.add(box[k]);
}
examineArea.add(pAddbox);
}
}
examineArea.repaint();
validate();
in.close();
out.close();
hintMess.setText("祝考出好成绩");
return;
}
if(s.startsWith("分数")){
JOptionPane.showMessageDialog(this,s,"查询提示",JOptionPane.PLAIN_MESSAGE);
return;
}
}
catch(Exception e){
JOptionPane.showMessageDialog(this,""+e,"异常提示",JOptionPane.PLAIN_MESSAGE);
return;
}
}
}
}
4.2 服务器端模块设计
4.2.1 Server类
标准化考试服务器端的主类,负责响应客户的连接请求、建立和客户的套接字链接,并负责在服务器端创建和用户相关的文件。

1、效果图
2、类的主要成员变量和方法
1)成员变量
a、server是ServerSocket对象,负责等待接收客户的套接请求,当有客户请求套接字连接时,server将接受用户的请求,并调用accept()方法返回服务器端所建立的Socket对象you,即建立服务器端套接字的连接。

b、You是Socket对象,该对象是驻留在服务器端的套接字对象,由server调用accept()方法返回。

c、loginStudent是LinkedList<String>链表对象,负责存储用户登录的基本信息。

d、youAddress是InetAddress对象,负责存放客户端的IP。

2)方法
a、Server()是构造方法。

b、Server对象调用startServer(int port)方法响应客户的请求。

c、main方法是程序运行的入口方法。

3、主要程序代码
import .*;
import java.util.*;
import java.io.*;
public class Server{
ServerSocket server;
Socket you;
LinkedList<String> loginStudent;
InetAddress yourAddress;
public Server(){
System.out.println("我是服务器端程序,负责处理用户的连接请求");
loginStudent=new LinkedList<String>();
}
public void startServer(int port){
while(true){
try{
server=new ServerSocket(port);
}
catch(IOException e1){
System.out.println("正在监听:");
}
try{ System.out.println("等待用户呼叫.");
you=server.accept();
yourAddress=you.getInetAddress();
System.out.println("客户的IP:"+yourAddress);
}
catch (IOException e){}
if(you!=null) {
new ServerThread(you,yourAddress,loginStudent).start();
}
else
continue;
}
}
public static void main(String args[]){
Server server=new Server();
server.startServer(6666);
}
}
4.2.2 ServerThread类
1、效果图
ServerThread类驻留在服务器端,没有可显示的效果图。

2、主要成员变量和方法
1)成员变量
a、loginStudent是LinkedList<String>链表对象,该链表每个节点存放一个用户登录的基本信息,即负责存储verifyMess对象。

b、verifyMess是String字符串,由用户登录时提交学号、姓名和客户端IP组成。

c、socket是Socket对象。

d、readTest是ReadTestquestion对象,负责读取试卷文件。

e、yourAddress是InetAddress对象,负责存放客户端的IP。

2)方法
a、ServerThread(Socket,InetAddress,LinkedList<String>list)是构造方法,当使用该构造方法创建线程时,通过该方法的参数Server类中的you、yourAddress和loginStudent对象传递给ServerThread类中的相应对象。

b、Run()方法是ServerThread类重写父类Thread的方法,给出了怎样响应用户请求的具体内容。

3、主要程序代码
import java.io.*;
import .*;
import java.util.*;
public class ServerThread extends Thread{
LinkedList<String> loginStudent;
String verifyMess;
InetAddress yourAddress;
Socket socket=null;
DataOutputStream out=null;
DataInputStream in=null;
ReadTestquestion readTest=null;
File currentDir,dirStudent;
boolean isLogin=false;
ServerThread(Socket t,InetAddress s,LinkedList<String> list){
socket=t;
yourAddress=s;
loginStudent=list;
currentDir=new File(System.getProperty("user.dir"));
dirStudent=new File(currentDir,"Student");
dirStudent.mkdir();
try{ in=new DataInputStream(socket.getInputStream());
out=new DataOutputStream(socket.getOutputStream());
}
catch (IOException e){}
readTest=new ReadTestquestion();
}
public void run(){
String s="";
while(true){
try{ s=in.readUTF();
if(s.startsWith("学生")){
verifyMess=s+""+yourAddress;
File file=new File(dirStudent,s+".txt");//存储学生信息的文件
file.delete(); //删除旧的文件
byte [] bb=verifyMess.getBytes();
if(!(file.exists())){
RandomAccessFile outNumber=new RandomAccessFile(file,"rw");
outNumber.write(bb);
outNumber.close();
}
if(loginStudent.contains(verifyMess)){
out.writeUTF("已经成功登录了");
break; //如果已经登录过,就消灭因重新登录而创建的当前线程}
else{
loginStudent.add(verifyMess);
out.writeUTF("成功登录:"+verifyMess);
//保留首次登录时的线程,当用户突然离线时,该线程将触发IOException
}
}
else if(s.startsWith("列出文件:")){
verifyMess=s.substring(stIndexOf(":")+1);
System.out.println(verifyMess);
isLogin=loginStudent.contains(verifyMess);
if(isLogin){
String fileName[]=currentDir.list(new FilenameFilter(){
public boolean accept(File dir,String name){
return name.endsWith(".txt");
}
});
for(int i=0;i<fileName.length;i++)
out.writeUTF("列出文件:"+fileName[i]);
out.writeUTF("已经全部列出:");
}
else{ out.writeUTF("请登录");
}
return;
}
else if(s.startsWith("显示试卷")){
verifyMess=s.substring(stIndexOf(":")+1,stIndexOf("#"));
System.out.println(verifyMess);
isLogin=loginStudent.contains(verifyMess);
String fileName=s.substring(stIndexOf("#")+1);
File file=new File(fileName);
if(isLogin){
String contentTest=readTest.getTestContent(file);
out.writeUTF("试卷内容:"+contentTest);
}
else{ out.writeUTF("请登录");
}
return;
}
else if(s.startsWith("提交的答案:")){
verifyMess=s.substring(stIndexOf(":")+1,stIndexOf("#"));
System.out.println(verifyMess);
isLogin=loginStudent.contains(verifyMess);
if(isLogin){
String clientAnswer=s.substring(s.indexOf("#")+1);
String fileName=verifyMess.substring(0,verifyMess.indexOf("/"));
File file=new File(dirStudent,fileName+".txt");
RandomAccessFile outAnswer=new RandomAccessFile(file,"rw");
outAnswer.seek(outAnswer.length());
byte [] bb="给出的答案:".getBytes();
outAnswer.write(bb);
bb=clientAnswer.getBytes();
outAnswer.write(bb);
outAnswer.close();
}
else{ out.writeUTF("请登录");
}
return;
}
else if(s.startsWith("查看得分:")){
int score=0;
verifyMess="";
verifyMess=s.substring(s.indexOf(":")+1,s.indexOf("#"));
System.out.println(verifyMess);
isLogin=loginStudent.contains(verifyMess);
if(isLogin){
String clientAnswer=s.substring(s.indexOf("#")+1,s.indexOf("*"));
String fileName=s.substring(s.indexOf("*")+1);
File file=new File(fileName);
String str=readTest.getCorrectAnswer(file);
for(int k=0;k<str.length();k++){
if(str.charAt(k)==clientAnswer.charAt(k))
score++;
}
if(str.length()>0){
out.writeUTF("分数:"+score);
fileName=verifyMess.substring(0,verifyMess.indexOf("/"));
file=new File(dirStudent,fileName+".txt");
RandomAccessFile outAnswer=new RandomAccessFile(file,"rw");
outAnswer.seek(outAnswer.length());
byte [] bb=("得分:"+score).getBytes();
outAnswer.write(bb);
}
else
out.writeUTF("分数:"+"没有答案");
}
else{ out.writeUTF("请登录");
}
return;
}
}
catch(IOException ee){
try{ socket.close();
}
catch(Exception eee){}
loginStudent.remove(verifyMess);
System.out.println("客户离开了");
break;
}
}
}
}
4.2.3 ReadTestquestion类
1、效果图
ReadTestquestion类驻留在服务器端,没有可显示的效果图
2、主要成员变量和方法
1)成员变量
该类没有成员变量。

2)方法
a、getTestContent(File)方法负责读取参数指定的试卷文件中的考试内容,即读取试卷文件中从第2行以后的全部文本。

b、getCorrectAnswert(File)方法负责读取参数指定的试卷文件中的答案,即读取试卷文件中从第1行文本。

3、主要程序代码
import java.io.*;
public class ReadTestquestion{
public String getTestContent(File f){
String testContent="";
try{ FileReader in=new FileReader(f);
BufferedReader reader=new BufferedReader(in);
String correctAnswer=(reader.readLine()).trim();
String lineContent=null;
StringBuffer temp=new StringBuffer();
while((lineContent=reader.readLine())!=null){
temp.append(lineContent+"\n") ;
}
in.close();
reader.close();
testContent=new String(temp);
}
catch(IOException e){
testContent="没有选择试题文件";
}
return testContent;
}
public String getCorrectAnswer(File f){
String correctAnswer="";
try{ FileReader in=new FileReader(f);
BufferedReader reader=new BufferedReader(in);
correctAnswer=(reader.readLine()).trim();
in.close();
reader.close();
}
catch(IOException e){}
return correctAnswer;
}
}
5 代码调试
1.服务器端
将Server、ServerThread、ReadTestquestion类的三个源文件以及要求的试卷文件保存到某一台计算机的同一目录中(如D:\Server)。

分别编译这三个Java源文件,或运行“javac * .java”命令,编译全部的源文件,然后运行主类,即运行Server 类。

2.客户端
将ClientWindow、ClientLogin、GetTestFile、ClientTestArea类的四个源文件以及要求的图像文件保存到某一台计算机的同一目录中,比如D:\ Client中。

分别编译这四个Java源文件,或运行“javac * .java”命令,编译全部的源文件,然后运行主类,即运行ClientWindow类。

Java语言与面向对象技术课程设计
6 软件发布
1、服务器端
服务器端程序在命令行窗口运行,不需要打包。

2、客户端
可以使用jar.exe命令制作JAR文件来发布编写的客户端文件。

(1)首先用文本编辑器,比如Windows下的记事本,编写一个清单文件:mymoon.mf
Manifest-Version: 1.0
Main-Class: ClientWindow
Created-By: 1.6(Sun Microsystems Inc.)
将mymoon.mf保存到D:\ch11中,即和应用程序所用的字节码文件保存在相同的目录中。

注意:清单文件中的“Manifest-Version:”和 1.0之间、“Main-Class:”和主类ClientWindow之间以及“Created-By:”和1.6之间必须有且只有一个空格。

(2)生成JAR文件。

D:\ch4\jar cfm Client.jar mymoon.mf * .class
其中参数c表示要生成一个新的JAR文件,f表示要生成的JAR文件的名字,m表示清单文件的名字。

现在就可以将Client.jar复制到任何一个安装了Java运行环境(版本号需高于1.6的计算机上)的计算机上,用户双击该文件的图标就可以运行客户端软件。

标准化考试系统
7 小结
这次Java课程设计我做的是“标准化考试系统”,通过这次课程设计,不仅巩固了本学期所学的课本上的理论知识,而且锻炼了我的动手实践能力和团队合作能力。

当课程设计任务分配下来的时候,我们组的所有成员在一起认真讨论,每人分配一个模块的设计,遇到困难了,大家一起研究讨论。

通过一个星期的努力,终于完成了整个系统的设计与制作。

大家看着我们自己的成果,心中的喜悦油然而生。

本次课程设计过程中,我们也遇到了一些困难,从小到背景颜色的更改,大到系统版面的设计以及代码的编写,都遇到困难,我们也意识到我们所学知识的不足,但是在大家的一起努力下,所有的困难都迎刃而解了。

我们希望,在今后的日子里,要将理论知识与动手实践相结合,这样才能更好地学好一门课。

尤其是对于学计算机的我们,上机实践真的是一个非常重要的环节。

我相信,Java这门课以后一定会越学越好!
Java语言与面向对象技术课程设计
参考文献
[1]耿祥义,张跃平.Java面向对象程序设计 [M].北京:清华大学出版社,2009.11.
[2]耿祥义,张跃平.Java课程设计(第二版) [M].北京:清华大学出版社,2008.7. ........忽略此处.......。

相关文档
最新文档