java课程设计(日记本)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1 需求分析
日记本是很平常的东西,很多人都有记日记的习惯,有人记账,有人记事、有人记下心情。
随着计算机技术的发展,很多家庭都买了电脑,开始上网,开始使用电脑来办公、打字等。
所写现在也有很多的人在使用电脑写小说,写博客等,受此启发我就萌生了编写一个日记本,用电脑来写日记的想法。
很多事我们不想忘记,于是写进日记本里,多年后翻出来再看看,很是惬意。
大多数人都使用的是纸质的日记本,这中日记很难保存,容易丢失,也容易遭到水浸等物理破坏,这样我们的日记就丢了。
同纸质的日记本相比较,用软件日记本不仅环保,而且安全方便,不怕被别人偷看。
软件日记本可以很方便的携带只要存在电脑硬盘或者U盘中就可以了。
1.1用户分析
这个软件面向的用户是拥有个人电脑,而其具有写日记的习惯的人。
用户使用的软件必须简单容易使用,在此基础上尽可能多的提供人性化功能,丰富软件的内涵。
同时软件必须尽量保证不会因用户的不当操作而使用户受到严重的经济、财产、精神损失。
软件必须具有很强的可靠性,不会无故终止运行、死机、退出等。
1.1.1用户要求具备以下基本功能:
a 编辑日记:包括改变字体大小、改变字体颜色等。
b 管理日记:包括保存及删除日记、按日期分组日记等。
1.1.2除以上功能外,可另曾特色功能:
a 音乐播放的功能。
b 编辑背景变换的功能。
c 身份验证的功能。
d 日记文件加密存储的功能。
1.2软件界面与接口需求
1.2.1界面需求
界面的原则要求:方便、简洁、美观、一致等。
整个界面要保持友好、简易的风格。
a输入设备:键盘、鼠标。
b输出设备:显示器。
c显示风格:应用程序窗口界面。
1.2.2接口需求
软件功能比较简单,暂时不需要接口方面的需求。
1.3目标软件其他需求
a.运行环境需求:要求安装Java Development Kit(JDK) v1.5或以上版本环境。
b.进度要求:2009年6月底必须完成开发,并通过测试。
2 概要设计
本课程设计是一个实用的日记本程序,主要实现日记撰写、按月份、日期分类日记、字体设置、身份认证、音乐播放、背景随机变化等。
一个普通的日记本无需使用数据库,如果要使用数据库则没有适合的数据库可以使用,桌面数据库太小不能满足需求,而其他大型数据库则又昂贵而不合算,所写我要开发的日记将以文本文件(windows下的.txt文件格式)来存储,这样做的好处是显而易见的。
2.1登陆验证
日记是个人的隐私,通常日记的拥有者不希望他人看到自己所写的日记,为了实现基本的保密,程序进行了用户身份认证,来确认是否有权使用。
认证流程如下:
登陆窗口
登陆者身份验证
登陆失败:重新登陆/取消登陆登陆成功:进入日记本
编辑日记
图2-1 身份验证功能流程
2.2 日记本各部分功能
日记本的基本功能就是撰写日记,对写好的日记要能够进行保存、修改、删除等操作。
这些都是一个日记本所具有的最基本的功能,除此之外本日记本还增加了其他功能。
具体模块功能有:
a 编辑日记:包括改变字体大小 、改变字体颜色等。
b 管理日记:包括保存及删除日记、按日期分组日记等。
c 音乐播放的功能。
d 编辑背景变换的功能。
e 身份验证的功能。
f 日记文件加密存储的功能。
具体功能层出图如下所示:
图 2-2 日记本层次功能
3 详细设计
下面是程序的全部代码与详细注释。
/*************************************** * 程序文件名称:Diary.java * 功能: 日历本
***************************************/
package diary;
import javax.swing.*;
日记本
日记编写 字体大小 字体颜色 音乐播放 背景变化
保存
删除
编辑
大字
普通字
红色字
蓝色字
播放音乐
上一曲
下一曲
随机变换
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.io.*;
import sun.audio.*;
import java.util.*;
// 日记本类
class Remember extends JFrame implements TreeSelectionListener,ActionListener
{
JTree tree=null;
int i=0,r=255,g=255,b=255;
JTextArea text=new JTextArea(" ",20,30);
DefaultMutableTreeNode root;
DefaultMutableTreeNode month[]=new DefaultMutableTreeNode[13]; //对象数组
JButton b_save=new JButton("保存"), b_del=new JButton("删除"),
b_fontCommen=new JButton("普通"),
b_fontBig=new JButton("大字"), b_fontRed=new JButton("红色"),
b_fontBlue=new JButton("蓝色"),
b_music_on= new JButton("音乐ON/OFF"),
b_music_n = new JButton("上首"),
b_music_p = new JButton("下首"), b_bg=new JButton("背景");
String DiaryRoot="diaries\\";
int music_on = 0, m_now=0;;
String[] musics={ "Alone.wav",
"Dreaming.wav",
"dying in the sun.wav",
"End Credits.wav",
"lolita.wav",
"Numb.wav",
"The Pary.wav",
"小茉莉.wav"};
InputStream is=null;
//构造方法,完成界面及树结点初始化 ,音乐文件列表初始化
Remember()
{
Container con=getContentPane();
DefaultMutableTreeNode root=new DefaultMutableTreeNode("日记本");
//设置以月份为节点的树,不考虑闰年的影响。
for(i=1;i<=12;i++)
{
month[i]=new DefaultMutableTreeNode(""+i+"月");
root.add(month[i]);
}
//设置不同月份的节点
for(i=1;i<=12;i++)
{
//处理有31天的月份
if(i==1||i==3||i==5||i==7||i==8||i==10||i==12) {
for(int j=1;j<=31;j++){
String s1=month[i].toString();
String s2=j+"日.txt";
File file=new File(DiaryRoot+s1+s2);
//如果这一天写了日记则相应节点后面添加一个“*”来标志
if(file.exists()==true)
month[i].add(new DefaultMutableTreeNode(j+"日*"));
else
month[i].add(new DefaultMutableTreeNode(j+"日"));
}
}
//处理有30天的月份
else if(i==4||i==6||i==9||i==11)
{
for(int j=1;j<=30;j++){
String s1=month[i].toString();
String s2=j+"日.txt";
File file=new File(DiaryRoot+s1+s2);
//如果这一天写了日记则相应节点后面添加一个“*”来标志
if(file.exists()==true)
month[i].add(new DefaultMutableTreeNode(j+"日*"));
else
month[i].add(new DefaultMutableTreeNode(j+"日"));
}
}
//处理有28天的月份
else
{
for(int j=1;j<=28;j++) {
String s1=month[i].toString();
String s2=j+"日.txt";
File file=new File(DiaryRoot+s1+s2);
//如果这一天写了日记则相应节点后面添加一个“*”来标志
if(file.exists()==true)
month[i].add(new DefaultMutableTreeNode(j+"日*"));
else
month[i].add(new DefaultMutableTreeNode(j+"日"));
}
}
}
//设置监听
b_save.addActionListener(this);
b_del.addActionListener(this);
b_music_on.addActionListener(this);
b_music_n.addActionListener(this);
b_music_p.addActionListener(this);
b_fontRed.addActionListener(this);
b_fontCommen.addActionListener(this);
b_fontBig.addActionListener(this);
b_fontBlue.addActionListener(this);
b_bg.addActionListener(this);
//创建树及其面板
tree =new JTree(root);
JPanel p=new JPanel();
//设置边界布局
p.setLayout(new BorderLayout());
JScrollPane scrollpane_1=new JScrollPane(text);
//带滚动条的面板放置到中间,可以占据最大空间位置
p.add(scrollpane_1,BorderLayout.CENTER);
//设置面板,放置"保存"和"删除"按钮等按钮,面板放在上部 JPanel p_1=new JPanel();
p_1.add(b_save);
p_1.add(b_del);
p_1.add(b_fontCommen);
p_1.add(b_fontBig);
p_1.add(b_fontRed);
p_1.add(b_fontBlue);
p_1.add(b_music_on);
p_1.add(b_music_n);
p_1.add(b_music_p);
p_1.add(b_bg);
//设置布局
p.add(p_1,BorderLayout.NORTH);
JScrollPane scrollpane_2=new JScrollPane(tree); JSplitPane splitpane=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,scrol lpane_2,p);
tree.addTreeSelectionListener(this);
con.add(splitpane);
//设置窗体适配器,关闭功能
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);} });
setVisible(true);
setBounds(100,150,500,600);
}
//处理树节点事件
public void valueChanged(TreeSelectionEvent e) {
//清空文本区中的内容
text.setText(" ");
if(e.getSource()==tree)
{
//定义被选中的节点
DefaultMutableTreeNode node=
(DefaultMutableTreeNode)tree.getLastSelectedPathC omponent();
//如果是叶节点,则可以对文件进行操作
if(node.isLeaf())
{
//日记以“-月-日.txt”的形式存储,所以要消除“*”号的影响
String str=node.toString();
str=str.substring(0,str.length()-1);
for(int i=0;i<=12;i++)
{
if(node.getParent()==month[i])
{
try {
String temp=null;
//打开以节点(“*”号影响已经消除)所定义的文本为文件名的文件
File f=new File(DiaryRoot+node.getParent().toString()+str+". txt");
//建立文本文件输入流,读取文件
FileReader file=new FileReader(f);
BufferedReader in=new BufferedReader(file);
//将读到的文件内容添加到文本区中,按行读入
while((temp=in.readLine())!=null)
text.append(temp+'\n');
file.close();
in.close();
}
catch(FileNotFoundException e1){ }
catch(IOException e1){ }
}
}
}
}
}
//处理按钮事件
public void actionPerformed(ActionEvent e)
{
//处理"保存"按钮的事件
if(e.getSource()==b_save)
{
DefaultMutableTreeNode node= (DefaultMutableTreeNode)tree.getLastSelectedPathC
omponent();
String str=node.toString();
//保存文件时去除“*”号
str=str.replace("*","");
//如果是叶节点,则可以对文件进行操作
if(node.isLeaf())
{
//保存文件
try{
//建立以节点所定义的文本为文件名的文件
File f=new File(DiaryRoot+node.getParent().toString()+str+". txt");
//建立文本文件输出流
FileWriter tofile=new FileWriter(f); BufferedWriter out=new BufferedWriter(tofile);
//将文本区中的内容写到文件缓冲区
out.write(text.getText(),0,(text.getText()).lengt h());
//将缓冲区中的内容写到文件
out.flush();
tofile.close();
out.close();
}
catch(FileNotFoundException e1){ }
catch(IOException e1){ }
}
}
//处理点出"删除"按钮的事件
else if(e.getSource()==b_del)
{
DefaultMutableTreeNode node=
(DefaultMutableTreeNode)tree.getLastSelectedPathC omponent();
String str=node.toString();
//删除文件时消除“*”好影响
str=str.replace("*","");
if(node.isLeaf())
{
try{
// 把删除命令写到一个批处理文件中
File f=new File(DiaryRoot+node.getParent().toString()+str+". txt");
FileWriter tofile=new FileWriter("del.bat");
BufferedWriter out=new BufferedWriter(tofile);
String temp1="del "+f.getAbsoluteFile().toString();
out.write(temp1,0,temp1.length());
out.newLine();
out.flush();
tofile.close();
out.close();
}
catch(IOException e1){}
}
//调用执行删除文件的方法,del()执行上面创建的批处理文件del.bat
del();
}
// 处理"大字"按钮事件
else if(e.getSource()==b_fontBig)
{
text.setFont(new Font("Serif",1, 18)); }
// 处理"普通"按钮事件
else if(e.getSource()==b_fontCommen)
{
text.setFont(new Font("Serif",0,12));
text.setForeground(Color.black);
}
// 处理"红色"按钮事件
else if(e.getSource()==b_fontRed)
{
text.setForeground(Color.red);
}
// 处理"蓝色"按钮事件
else if(e.getSource()==b_fontBlue)
{
text.setForeground(Color.blue);
}
//处理"音乐ON"按钮事件
else if(e.getSource()==b_music_on)
{
//判断音乐开关变量music_on
if(music_on==0) music_on=1;
else if(music_on==1) music_on=0;
try
{
// 如果正在播放时被按下,就停止当前正在播放的音乐 AudioPlayer.player.stop(is);
//用输入流创建一个AudioStream对象,并打开给对象
is=getClass().getResource("sounds\\"+musics[m_now ]).openStream();
if(music_on==1)
{
//播放音乐,播放完毕后关闭
AudioPlayer.player.start(is);
while(is==null)
AudioPlayer.player.stop(is);
}
}
catch(IOException e1){ }
}
// 处理"上首"、"下首"按钮事件
if(e.getSource()==b_music_n)
{
//实现循环,当到达最后时可以返回到第一个音乐
m_now=(m_now+1)%6;
try
{
//关闭正在播放的音乐,重新创建并播放新的音乐
AudioPlayer.player.stop(is);
is=getClass().getResource("sounds\\"+musics[m_now ]).openStream();
if(music_on==1)
{
AudioPlayer.player.start(is);
while(is==null)
AudioPlayer.player.stop(is);
}
}
catch(IOException e1){ }
}
if(e.getSource()==b_music_p)
{
m_now=(m_now-1)%6;
try
{
//关闭正在播放的音乐,重新创建并播放新的音乐
AudioPlayer.player.stop(is);
is=getClass().getResource("sounds\\"+musics[m_now ]).openStream();
if(music_on==1)
{
AudioPlayer.player.start(is);
while(is==null)
AudioPlayer.player.stop(is);
}
}
catch(IOException e1){ }
}
// 处理"背景"按钮事件
else if(e.getSource()==b_bg)
{
// 随机变化背景颜色
// 随机+ - 操作,当op>0.5时做减法负责做加法,
double op = Math.random();
double c = Math.random()*10;
if(op>0.5)
{
// 使r,g,b三个标志RGB的变量减小一个随机的大小小在0-50之间的数
if(c<4) r-=Math.random()*50;
if(c>4 && c<7) g-=Math.random()*50;
if(c>7) b-=Math.random()*50;
}
if(op<=0.5)
{
// 使r,g,b三个标志RGB的变量增加一个随机的大小小在0-50之间的数
if(c<4) r-=Math.random()*50;
if(c>4 && c<7) g-=Math.random()*50;
if(c>7) b-=Math.random()*50;
}
text.setBackground(new Color(r,g,b));
}
}
//删除文件
void del()
{
// 调用外部命令执行批处理程序
try{
Runtime ce=Runtime.getRuntime();
ce.exec("gxy.bat");
} catch(IOException e1){ }
}
}
//登陆窗口类
class LoginWindow extends JDialog implements ActionListener
{
JPanel p1=new JPanel(); //定义并建立面板
JPanel p2=new JPanel();
JPanel p3=new JPanel();
JPanel p4=new JPanel();
JPanel p5=new JPanel();
JTextField txtUserName=new JTextField(15); //用户名文本框
JPasswordField txtPwd=new JPasswordField(15);//密码框
JButton ok=new JButton("确定");
JButton cancel=new JButton("取消");
public LoginWindow()
{
setModal(true); //设置模态
setBackground(Color.LIGHT_GRAY);//设置背景色
Container
contentPane=this.getContentPane();//取出内容面板
contentPane.setLayout(new GridLayout(5,1)); //设置布局为5行1列
p2.add(new JLabel("用户名:"));p2.add(txtUserName); //将组件添加到中间容器p3.add(new JLabel("密码:"));p3.add(txtPwd);
p4.add(ok);p4.add(cancel);
ok.addActionListener(this);
cancel.addActionListener(this);
txtUserName.addActionListener(this);
txtPwd.addActionListener(this);
contentPane.add(p1); //将面板添加到内容面板
contentPane.add(p2);
contentPane.add(p3);
contentPane.add(p4);
contentPane.add(p5);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) ;//设置自动关闭窗口
setSize(300,220);
// Dimension 类封装单个对象中组件的宽度和高度
Dimension
screen=Toolkit.getDefaultToolkit().getScreenSize( );
setLocation((screen.width-300)/2,(screen.height-2 20)/2);
setTitle("登录窗口");
setResizable(false); //设置窗口大小固定
setVisible(true);
}
//添加事件监听器
public void actionPerformed(ActionEvent e)
{
//处理”确定”按钮事件
if(e.getSource()==ok||e.getSource()==txtPwd) {
if(txtUserName.getText().trim().equals("shenbaise ") && txtPwd.getText().trim().equals("123456")) //如果用户名为shenbaise密码为123456 则正确
{
dispose(); //关闭登录窗口
}
else
{
JOptionPane.showMessageDialog(null,"用户名或密
码错误!");
txtUserName.requestFocus(); //设置焦点
txtUserName.setSelectionStart(0); //设置选中
文本开始位置
txtUserName.setSelectionEnd(txtUserName.getText()
.length());
}
}
//处理”取消”按钮事件
else if(e.getSource()==cancel)
{
dispose();
System.exit(0); //退出程序
}
else if(e.getSource()==txtUserName) //在用户名文本框按回车移动焦点到密码框
{
txtPwd.requestFocus();
}
}
}
// 程序主类
public class Diary
{
public static void main(String args[]) throws Exception
{
new LoginWindow();
Remember win=new Remember();
win.pack();
}
}
以上是整个程序的全部代码与详细注释,呈现主要包含了两个大类,一个是日记本类,它来实现日记本编辑、保存、删除、修改、日记分组等的管理与一些其他的附加功能比如音乐播放、背景变化等;另一个类是一个用来实现身份验证的登录窗口类,由它来实现最简单的身份认证与保密的功能。
4 总结
这个日记本程序是一个非常简单的java应用程序,但是由于经验和能力有限,在完成这个程序时遇到了不少困难。
目前本程序除了可以基本满足写日记的功能要求外,还增加了一些有特色的功能比如音乐播放、背景变换等,这些功能为日记本增加了不少特色。
其中音乐播放以前没有在在JA V A Application中实现起来不太容易,经过努力终于完成了音乐的循环播放。
有无日记的节点标记也是一个难点,最后通过在节点后面加星号的形似得到了基本实现,最后省份验证的内容比较难,本来想同过数据库并做加密存储来实现但是因为工作两太大,最终还是没能完成,而仅是将密码存储在程序中了。
然而这和最初的设想还有不小的差距。
首先,由于时间有限未能对日记做很好的加密,而是直接以windows下记事本的形式存储了,这样一来保密性就不好了;另外,为窗体设置背景图片的设想也没能完成;身份认证也没有十分完美地实现。
这些都有待今后进一步完善。