Java Swing实现简单的练习系统(总结)

第一个全部自己实现的程序,做一下总结。

1.准备阶段

跟着别人写了个小小的swing项目,现在看来那个项目中,我收益最大的就是学到了多层结构的开发模式。即服务层——监听器层——数据库。当我越写到后面,类越多的时候,我就越能感觉到这模式的好处。
看图
在这里插入图片描述

2.需求分析

操作:这一步我其实是有点难去分析的,我没在网上找到一个系统去参考,找到了的也是ssm框架之类的实现,我不懂,还有两个确实有swing实现但是要钱…所以我折中了一下,看看他们的功能描述有哪些,还有看看他们的swing界面是怎么样的,根据这些来初步得知练习系统大概有什么功能。

反思:这一步对写程序我觉得挺重要的。这个系统我花了2/3的事件去写代码,然后花了1/3的时间去改代码。不是代码错了要改,而是最先开始的需求分析不明确,导致一些功能实现的云里雾里的。不只是功能,表的设计也会受到很大影响,到后面表一改,好多代码都要对应的改,不是难,而是会很麻烦很容易漏掉一些边角处没改。

3.表结构设计

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4.界面原型

界面设计的话,由于已经有需求分析得出的结果了,就从登录界面一个个推出来,不难,但很麻烦。

第一步的设计我是在网上找了一些练习系统的例子,一般他们都会演示程序完成结果,就会有界面出来,根据他们的界面来设计自己的界面,这样会容易点。

画界面的话我分两种,简单一点的就自己写,技术达不到的就自己写一点,其他的用WindowBuilder一个个拖上去。WindowBuilder画swing界面挺好用的,可以百度教程。

画完原型后接下来就是功能模块的实现了,第一阶段的原型肯定是不完整的,其他的就留到实现功能的时候再慢慢补,看有什么缺漏或者需要删除的。

swing图我一开始最怕的就是表格JTable了,完全不懂它的运行格式,只是照搬别人的格式,写到最后的时候,才突然发现JTable是怎么运作的。

5.功能实现、实体类和DAO

功能实现就要回到开头的那个图了。
在这里插入图片描述来捋一捋:

界面→事件监听器→服务层→DAO层→数据库,

来实例:

1.首先我们通过界面原型那步画了一个题目管理界面出来

在这里插入图片描述在这里插入图片描述
2.现在我们来分析这个界面有什么功能需要实现。
(1)增加题目功能
(2)修改题目功能
(3)查看题目详情功能
(4)查找功能(查找功能又可以细分)
(4)根据题目编号查找题目功能
(5)根据知识点查找题目功能
(6)根据题目分数查找题目功能
(7)查找所有题目的功能
注意:规定教师只能对本学科的题目进行操作,所以查找功能隐含限制要加上“根据学科查找”,增加题目功能也是只能增加本学科的题目
仔细分析一下
前三个功能怎么样实现,增加、修改、查看可以在这个界面完成吗?我的做法是为这三个操作每个操作再新建一个界面。也即点击增加、修改、查找按钮会跳出对应的界面,在那个界面去进行操作。而查找功能的显示只需要在这个界面就可以完成。

3.开发思路:界面层→Service层
Service层是什么?看到第二步我们分析出来的功能了吗,界面需要的所有功能(一般情况下)我们都需要在Service层实现。Service层就是封装了界面功能的实现
创建一个service类,里面有很多个方法。

public class questionManageService {
	
	//增加按钮,跳转到跳转到增加题目界面
	public void add(){
		//里面是具体的功能实现	
	}
			
	//修改按钮,跳转到修改题目界面
	public void update(Question question){
		
	}
			
	//详细按钮,跳转到题目详情界面
	public void details(Question question){
				
	}
			
	//根据题目编号查找(其实还要加上学科限制)
	public List<Question> getById(int id, String subject){
				
	}
			
	//根据知识点查找(加上学科限制)
	public List<Question> getByPoint(String point, String subject){
				
	}
			
	//根据分数查找(加上学科限制)
	public List<Question> getByScore(int score, String subject){
				
	}
			
	//查找全部,这里的查找全部即为按照学科查找
	public List<Question> getBySubject(String subject){
				
	}

}

注意查找功能隐含限制要加上“根据学科查找”

4.开发思路:Service层→DAO层
我们从上一步功能分析知道有个查找功能。那去哪里查找呢?易拉罐里有饮料,为了喝到里面的饮料,我们需要一根吸管。DAO层就是那根吸管,就像是连接java代码和数据库的一条通道
这个通道里有增、删、改、查四个小通道,Service层需要用到什么,就走(调用)什么通道。

5.开发思路:DAO层→数据库,实体
在这里插入图片描述感觉有点自顶向下那味儿了

6.第五步后service层就算实现了。接下来是Listener层。这层是监听器层,封装了界面上所有按钮的监听器。来看下题目管理界面有什么按钮
在这里插入图片描述增加按钮、修改按钮、详情按钮、查找按钮。在点击这些按钮之后系统需要作出对应的反应,怎么才能作出反应呢,就需要为这些按钮添加监听器,监听这些按钮是不是被点击了,点击之后我们要干什么。当然,我们可以在界面类那里直接就写监听器,但那样需要每个按钮实现一个监听器,会弄得代码很繁杂,不利于问题定位或者修改代码。所以我们专门分出一个类来作为该界面监听器。该界面所有的按钮只要加这一个监听器就行。

public class questionManageListener implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent e) {
		
		//取得面板实例和事件源和老师学科
		questionManageFrm f = questionManageFrm.instance;
		Object b =e.getSource();
		Teacher teacher = (Teacher)LoginFrm.instance.user;
		
		//点击增加按钮
		if(b == f.bAdd) new questionManageService().add();
		
		//点击修改按钮
		if(b == f.bUpdate) {
			Question question = f.getSelectedQuestion();
			new questionManageService().update(question);
		}
		
		//点击详细
		if(b == f.bDetails){
			Question question = f.getSelectedQuestion();
			new questionManageService().details(question);
		}
		
		
		
		//点击查找按钮
		if(b == f.bSearch){
			String choice = (String)f.comboBox.getSelectedItem();
			String s = f.textField.getText().trim();
			
			//让“所有”查找放在空判断前面,因为“所有”查找时文本框就是空的
			if("所有" == choice){
				List<Question> questions = new questionManageService().getBySubject(teacher.subject);
				f.updateData(questions);
				return;
			}
			
			if(0 == s.length()){
				JOptionPane.showMessageDialog(f, "输入不能为空");
				return;
			}
			if("题目编号" == choice){
				if(!GUIUtil.checkNumber("题目编号", f.textField))
					return;
				List<Question> questions = new questionManageService().getById(Integer.parseInt(s), teacher.subject);
				f.updateData(questions);
			}
			if("知识点" == choice){
				List<Question> questions = new questionManageService().getByPoint(s, teacher.subject);
				f.updateData(questions);
			}
			if("分数" == choice){
				if(!GUIUtil.checkNumber("分数", f.textField))
					return;
				List<Question> questions = new questionManageService().getByScore(Integer.parseInt(s), teacher.subject);
				f.updateData(questions);
			}
			
			f.textField.setText("");
		}
		
		//点击复选框,当选择“所有”时,文本框清空且不可用
		if(b == f.comboBox){
			String choice = (String)f.comboBox.getSelectedItem();
			if("所有" == choice) {
				f.textField.setText("");
				f.textField.setEnabled(false);
			}
			else f.textField.setEnabled(true);
		}
		
	}
}

7.许多人会分不清Service层、DAO层、Listener层

DAO层:直接跟数据库打交道,封装一条条基本的增删改查操作

Service层:封装界面所需的所有功能,跟DAO层打交道,把一条条增删改查操作组合,组合成为界面的一个个功能

Listene层:跟Service层打交道,跟界面打交道。监听界面的事件,并根据事件类型作出不同反应,这些反应就是调用Service层实现的。

6.遇到的问题

1.遇到最多的问题就是空指针问题,大多是由于程序设计的不周全所致,这是当时的一个记录

2.对于试卷题目表中题目太多,在写代码时不想全部写的问题。问题记录,这里用了反射

3.在考试时我使用了一个倒计时线程,线程结束时会自动提交。但是当我提前交卷时关掉界面时,线程并没有停止。所以我发现我当时忘了加个线程停止的步骤。网上查了方法,然后采用了标志位的去停止线程。这是网上查的方法

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值