javase综合练习 考试系统(无数据库)(swing界面)实战
Exam:1.包结构entity: 实体类domain pojoservice: 服务test: 测试ui: 界面 - Swingutil: 工具2.MVC思想M: Model 对象, 业务逻辑[服务器端]V: View 视图, UIC: Controller 控制器数据存储在数据库[模拟数据库->读取文件]3.读取文件来充当数据库 EntityContext1.定义集合存储用户2.定义集合
Exam:
1.包结构
entity: 实体类 domain pojo
service: 服务
test: 测试
ui: 界面 - Swing
util: 工具
2.MVC思想
M: Model 对象, 业务逻辑[服务器端]
V: View 视图, UI
C: Controller 控制器
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210709194825172.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3h1amlhcWlxaXFp,size_16,color_FFFFFF,t_70
数据存储在数据库[模拟数据库->读取文件]
3.读取文件来充当数据库 EntityContext
1.定义集合存储用户
2.定义集合存储试题
3.定义方法来读取用户文件
4.定义方法来读取试题文件
注意: 在3.4中发现读取文件,需要传递文件名,文件名是可能发生改变的
所以将文件名写入到配置文件中, 需要通过Config类来读取配置文件
注意: Config是工具类, 在EntityContext中需要使用config对象
Config是IO流, 所以不能无限创建, 应该是程序启动时创建
EntityContext因为是模拟数据库, 所以也应该是程序启动时初始化好
主方法: new Config()
new EntityContext(): 读取文件
-
登陆界面
-
菜单界面
-
考试界面
-
交卷
-
退出
列举几个重要的类:
- 控制器类
package com.zzxx.exam.ui;
import com.zzxx.exam.entity.ExamInfo;
import com.zzxx.exam.entity.QuestionInfo;
import com.zzxx.exam.entity.User;
import com.zzxx.exam.service.ExamServiceImpl;
import com.zzxx.exam.service.IdOrPwdException;
import javax.swing.*;
import java.awt.*;
import java.sql.Time;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import static javax.swing.WindowConstants.EXIT_ON_CLOSE;
/**
* 前端控制器
*/
public class ClientContext {
private WelcomeWindow welcomeWindow;
private LoginFrame loginFrame;
private ExamFrame examFrame;
private MenuFrame menuFrame;
private ExamServiceImpl examService;
private MsgFrame msgFrame;
private ExamInfo examInfo;
/**
* 1.显示欢迎界面 -2000毫秒
* 2。计时 -> 到时间,欢迎界面消失
* 显示登陆界面
*/
public void show(){
welcomeWindow.setVisible(true);
//跳转页面时间延迟
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
welcomeWindow.setVisible(false);
loginFrame.setVisible(true);
}
},1000
);
}
public void setExamFrame(ExamFrame examFrame) {
this.examFrame = examFrame;
}
public void setMenuFrame(MenuFrame menuFrame) {
this.menuFrame = menuFrame;
}
public void setExamService(ExamServiceImpl examService) {
this.examService = examService;
}
public void login(){
//1.收集数据:loginFrame界面获得
/**
* 想要获得loginFrame中id和password
* loginFrame提供一个对外的方法
*/
int id = loginFrame.getId();
String pwd = loginFrame.getPwd();
//2。调用业务模型
try {
User u = examService.login(id, pwd);
loginFrame.setVisible(false);
menuFrame.showName(u);
menuFrame.setVisible(true);
} catch (IdOrPwdException e) {
loginFrame.showMes(e.getMessage());
}
}
/**
* 开始考试
* @param
*/
private ExamInfo info;
private QuestionInfo currentQuestion;
public void start(){
// 1.调用service 的 start方法
info = examService.start();
// 2.调用service 的 getQuestion方法
QuestionInfo questionInfo = examService.getQuestion(0);
currentQuestion = questionInfo;
// 3.更新界面信息
examFrame.updateInfo(info);
examFrame.updateQuestion(questionInfo);
// 4.显示界面/隐藏界面
menuFrame.setVisible(false);
examFrame.setVisible(true);
timer();
}
/**
* 下一题
* @return
*/
public void next(){
List<Integer> userAnswer = examFrame.getUserAnswer();
// 1.保存当前题目的用户答案
examService.saveUserAnswers(currentQuestion.getQuestionIndex(),userAnswer);
// 知道当前是哪一题
// index ++
if(currentQuestion.getQuestionIndex()<=18){
QuestionInfo question = examService.getQuestion(currentQuestion.getQuestionIndex() + 1);
// 2.获得下一题对应的题目信息QuestionInfo
currentQuestion=question;
// 3.更新界面
examFrame.updateQuestion(question);
//更新选项的状态
examFrame.updateOption(currentQuestion.getUserAnswers());
}else {
JOptionPane.showMessageDialog(examFrame,"已经是最后一题了");
System.out.println("已经是最后一题了");
}
}
public WelcomeWindow getWelcomeWindow() {
return welcomeWindow;
}
public void setWelcomeWindow(WelcomeWindow welcomeWindow) {
this.welcomeWindow = welcomeWindow;
}
public LoginFrame getLoginFrame() {
return loginFrame;
}
public void setLoginFrame(LoginFrame loginFrame) {
this.loginFrame = loginFrame;
}
public void showName() {
menuFrame.getName();
}
public void prev() {
List<Integer> userAnswer = examFrame.getUserAnswer();
// 1.保存当前题目的用户答案
examService.saveUserAnswers(currentQuestion.getQuestionIndex(),userAnswer);
// 知道当前是哪一题
// index ++
if (currentQuestion.getQuestionIndex()>0){
QuestionInfo question = examService.getQuestion(currentQuestion.getQuestionIndex() - 1);
// 2.获得下一题对应的题目信息QuestionInfo
currentQuestion=question;
// 3.更新界面
examFrame.updateQuestion(question);
//更新选项的状态
examFrame.updateOption(currentQuestion.getUserAnswers());
}else {
JOptionPane.showMessageDialog(examFrame,"已经是第一题了");
System.out.println("已经是第一题了");
}
}
public void over() {
// 1.记录当前这道题的用户答案
List<Integer> userAnswer = examFrame.getUserAnswer();
examService.saveUserAnswers(currentQuestion.getQuestionIndex(),userAnswer);
// 2.计算分数
int score = examService.examOver();
// 3.弹窗显示分数
JOptionPane.showConfirmDialog(this.examFrame,"你确定要交卷吗?","请确认",JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
JOptionPane.showMessageDialog(examFrame,"你的分数是"+score);
System.out.println(score);
timer.cancel();
}
public void setMsgFrame(MsgFrame msgFrame) {
this.msgFrame = msgFrame;
}
public void msg() {
msgFrame.showMsg(examService.getMsg());
}
private Timer timer = new Timer();
public void timer(){
long end = System.currentTimeMillis()+info.getTimeLimit()*60*1000;
//剩余时间的概念:计时结束的时间-当前时间
timer.schedule(new TimerTask() {
@Override
public void run() {
long now = System.currentTimeMillis();
long left = end - now; // 显示格式 01:10:34
long hour = left / 1000 / 60 / 60;
long minute = left / 1000 / 60 - hour * 60;
long second = left / 1000 - hour * 60 * 60 - minute * 60;
examFrame.updateTime(hour, minute, second);
if (left <= 0) { // 到时间了
over(); // 强制交卷了
}
}
}, 1, 1000);
//考试时间
}
public void exit(JFrame source ) {
int i = JOptionPane.showConfirmDialog(source, "确定要离开吗?");
// 判断点击的是 确定还是取消
if (i == JOptionPane.OK_OPTION) {
System.exit(0);
}
}
}
- 数据库类(通过集合自己写的数据库)
package com.zzxx.exam.entity;
import com.zzxx.exam.util.Config;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 实体数据管理, 用来读取数据文件放到内存集合当中
* 模拟数据库
*/
public class EntityContext {
private Config config; // null, 要通过set方法注入[程序开启后]
// 存储所有用户的集合 用户的id对应的用户对象
private Map<Integer, User> users = new HashMap<>();
// 存储所有试题的集合 一个难度级别下面对应这个难度级别所有的题目
private Map<Integer, List<Question>> questions = new HashMap<>();
private List<String> messages = new ArrayList<>();
public EntityContext(Config config) {
this.config = config;
String userFile = config.getString("UserFile");
String questionFile = config.getString("QuestionFile");
String msgFile = config.getString("rule.txt");
loadUsers(userFile);
loadQuestions(questionFile);
//loadMsg(msgFile);
}
/**
* 读取user.txt文件
* 并且解析成user对象, 添加到users集合中
*/
private void loadUsers(String userFile) {
System.out.println("loadUsers");
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(userFile)));
String str;
while((str = br.readLine()) != null) {
// 跳过 空格 和 #行
str = str.trim();
if (str.startsWith("#") || str.equals("")){
continue;
}
User one = parseUser(str);
users.put(one.getId(), one);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//System.out.println(users.size());
}
// private void loadMsg(String msgFile){
// System.out.println("msmFile");
// BufferedReader br = null;
// try {
// br = new BufferedReader(new InputStreamReader(new FileInputStream(msgFile)));
// String str;
// while ((str=br.readLine())!=null){
// str = str.trim();
// if (str.startsWith("#") || str.equals("")){
// continue;
// }
// messages.add(str);
// }
// } catch (IOException e) {
// e.printStackTrace();
// }finally {
// if (br != null) {
// try {
// br.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// }
// }
/**
* 解析字符串
* 1001:陈贺贺:1234:13810381038:chenhh@zzxx.com.cn
* @param str
* @return
*/
private User parseUser(String str) {
String[] data = str.split(":");
User user = new User();
user.setId(Integer.valueOf(data[0]));
user.setName(data[1]);
user.setPassword(data[2]);
user.setPhone(data[3]);
user.setEmail(data[4]);
return user;
}
/**
* 读取corejava.txt文件
* 并且解析成Question对象, 添加到questions集合中
*/
private void loadQuestions(String questionFile) {
System.out.println("loadQuestions");
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(questionFile)));
String str;
while((str = br.readLine()) != null) {
Question question = parseQuestion(str, br);
addQuestion(question);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//System.out.println(questions.size());
}
/**
* 将question对象添加到questions集合中
* 相同的难度级别, 放在同一个List中
* @param question
*/
private void addQuestion(Question question) {
List<Question> list = this.questions.get(question.getLevel());
// 第一次出现这个难度级别的题目
if (list == null) {
list = new ArrayList<>();
questions.put(question.getLevel(), list);
}
list.add(question);
}
/**
* 解析Question对象
* @param str @answer=2/3,score=5,level=5 @answer= ,score= ,level=
* @param br
* @return
*/
private Question parseQuestion(String str, BufferedReader br) {
Question question = new Question();
try { // 2/3 5 5
String[] data = str.split("[@,][a-z]+=");
// {"", "2/3", "5", "5"}
question.setAnswers(parseAnswer(data[1]));
question.setScore(Integer.parseInt(data[2]));
question.setLevel(Integer.parseInt(data[3]));
question.setTitle(br.readLine()); // 读一行是题干
List<String> option = new ArrayList<>();
// 连续读4行是选项
option.add(br.readLine());
option.add(br.readLine());
option.add(br.readLine());
option.add(br.readLine());
question.setOptions(option);
question.setType(question.getAnswers().size()==1 ? Question.SINGLE_SELECTION:Question.MULTI_SELECTION);
} catch (IOException e) {
e.printStackTrace();
}
return question;
}
/**
* 解析 2/3 正确答案
* @param str
* @return
*/
private List<Integer> parseAnswer(String str){
String[] data = str.split("/");
List<Integer> answers = new ArrayList<>();
for (String s : data) {
answers.add(Integer.valueOf(s));
}
return answers;
}
public void setConfig(Config config) {
this.config = config;
}
/**
* 根据用户ID查找用户实例
* @param id
* @return
*/
public User getUserById(int id) {
return users.get(id);
}
public Map<Integer, List<Question>> getQuestions() {
return questions;
}
public void setQuestions(Map<Integer, List<Question>> questions) {
this.questions = questions;
}
public int getTime() {
return config.getInt("TimeLimit");
}
public String getTitle() {
return config.getString("PaperTitle");
}
// public ExamInfo getExamInfo() {
//
// return null;
// }
}
- 业务层
package com.zzxx.exam.service;
import com.zzxx.exam.entity.*;
import java.util.*;
public class ExamServiceImpl implements ExamService{
private EntityContext entityContext;
private User user;
public void setEntityContext(EntityContext entityContext) {
this.entityContext = entityContext;
}
@Override
public User login(int id, String pwd) throws IdOrPwdException {
user = entityContext.getUserById(id);
if (user==null){
throw new IdOrPwdException("用户不存在");
}
if (!user.getPassword().equals(pwd)){
throw new IdOrPwdException("密码错误");
}
return user;
}
// 定义一个集合 List<QuestionInfo> paper, 用来存储试卷题目
private List<QuestionInfo>paper = new ArrayList<>();
@Override
public ExamInfo start() {
int num =0;
Random random = new Random();
// 1.生成试卷[每一个难度级别随机生成2道题目]
for (int i = 1; i < 11; i++) {
List<Question> questions = entityContext.getQuestions().get(i);
Question q1 = questions.remove(random.nextInt(questions.size()));
Question q2 = questions.remove(random.nextInt(questions.size()));
paper.add(new QuestionInfo(num++,q1));
paper.add(new QuestionInfo(num++,q2));
}
// 调用EntityContext来获得题目
// 2.封装一个考试信息返回 ExamInfo
ExamInfo examInfo = new ExamInfo();
examInfo.setQuestionCount(paper.size());
examInfo.setTimeLimit(entityContext.getTime());
examInfo.setTitle(entityContext.getTitle());
examInfo.setUser(user);
// ExamInfo : title-自定 user->登陆过的(login赋值过了)
// timeLimit: 配置文件 questionCount: 生成试卷时记录的
return examInfo;
}
@Override
public QuestionInfo getQuestion(int index) {
return paper.get(index);
}
@Override
public void saveUserAnswers(int index, List<Integer> userAnswers) {
getQuestion(index).setUserAnswers(userAnswers);
}
@Override
public int examOver() {
int sum=0;
for (int i = 0; i < 20; i++) {
List<Integer> userAnswers = getQuestion(i).getUserAnswers();
List<Integer> answers = getQuestion(i).getQuestion().getAnswers();
if (userAnswers.equals(answers)){
sum+=getQuestion(i).getQuestion().getScore();
}
}
// paper 用户答案和正确答案对比
return sum;
}
@Override
public String getMsg() {
return null;
}
}
更多推荐
所有评论(0)