Java课程设计——使用对象流模拟对象数据库(详细含报告和源代码)

欢迎来到Stephen的博客。我是小达,一名普通的在校大学生。希望大家多多关照,我们一起成长一起进步,也希望大家多多支持我鸭,喜欢我就给我一个关注吧!

1.实验目的:图形界面、对象流、文件的综合运用。
2.题意:将用户信息设计成一个类,使用对象流模拟对象数据库,将用户信息保存到数据文件夹中。
3.实验要求:能录入用户的相关信息,添加、删除信息,对记录定位,保存文件。界面如图所示:
题意

1.系统简介

1.1 设计背景

用户的信息管理在日常生活中是非常频繁的工作,如果通过人工的用纸笔记录用户的信息和管理用户信息,一方面效率会很低,同时对资源的浪费也很严重。所以,类似的简易用户信息管理工具就显得十分必要和实用。

1.2 开发环境

开发平台:Windows 10
开发工具:IntelliJ IDEA 2020.2.3 x64 + corretto-1.8.0

2.系统分析与设计

2.1 设计目的

首先是界面设计,最重要的就是简洁美观而且要符合普通用户的使用习惯。各个组件的功能也要设计得让用户有一种“望文生义”的效果。
其次,便是结构设计。为了增强各个模块的独立性,将各个功能都分开写成独立的方法,通过一个主类将各个模块功能的实现方法作为类的成员方法连接起来。这样既增加了程序的可读性和模块的独立性,也让自己调试程序的时候方便很多。
将用户信息设计成一个类,使用对象流模拟对象数据库,将用户信息保存到数据文件夹中。能录入用户的相关信息,添加、删除信息,对记录定位,保存文件。

2.2 功能需求

用户信息包括:用户编号、用户姓名、性别、省份、城市。
(1).点击添加按钮,即添加相应的用户信息在左边的列表框中显示;
(2).点击第一页即将列表框中第一条记录选中;
(3).前一页、下一页、最后一页按钮点击分别选中当前记录的前一条、下一条和最后一条;
(4).点击删除即将列表框中当前选中的记录项删除;
(5).点击打开按钮即弹出文件选择器,选择确定即将文件中的内容导入到列表框中显示;
(6).点击保存即将列表框中的记录作为文件导出到硬盘上保存,用户可以选择路径。如下图所示为功能模块图:
在这里插入图片描述

2.3 系统流程框图

系统流程框图

2.4 代码设计

定义一个主类(Julia)继承windowAdapter类,重写其windowClosing的方法来实现窗口关闭按钮的响应事件,同时实现ActionListener,ItemListener两个接口重写其中的actionPerform()和itemStateChange()方法分别监听按钮和下拉框的响应事件来完成功能。将界面上所有的组件都定义成该类的成员变量,以供在方法中调用。定义display成员方法来显示程序的界面,在该方法中实例化一个frame对象,利用合适的布局管理器将类中声明的所有组件变量都添加到frame的合适位置。在actionPerformed方法中实现button按钮点击的响应事件,由于有8个按钮组件可以通过e.getSource方法获取点击事件的事件源来区别响应事件。
第一页、前一页、后一页、最后一页响应事件实现:直接通过调用列表框的已经定义的list.select(list.getSelectIndex())方法设置列表框中记录的选中。
添加:将在编号、姓名、性别、省份、城市组件上获得的文本,组合成一个字符串,形成一条记录直接当成一个list的item添加到左边的列表框中显示。
删除:将当前选中的列表项直接调用库函数删除,如果当前没有任何列表项处于选中状态则弹出提示框提示用户没有选中。
打开:在打开记录文件之前,先把列表框中的所有内容全部清空以防止混淆。然后弹出一个文件对话框,用户选择待打开的文件的路径以及选中文件再点击确定;程序捕获文件的绝对路径后定义一个指向该路径的文件对象获取文件流,再通过缓冲读入流将文件内容一行一行读入并添加到列表框中显示,完成以后关闭输入输出流。
保存:弹出文件选择器,选择将列表框中的记录保存到的文件的路径;如果文件选择为空则程序新建一个自定义名字的文件,如果存在则直接保存到相应文件;保存的功能是交给save(file)方法来完成;打开一个缓冲输出流将刚指定的文件包装到其中,定义一个string数组来存放列表框中的所有记录,通过循环将数组中的每一个元素即列表框中的一条记录转化为字节数组再通过输出流将数据输出到指定文件中;最后关闭输出流。

3.系统调试

3.1 编写源程序界面

运行界面,如图所示。
运行界面

3.2 测试用例

在这里插入图片描述
导入

3.3 运行结果

在这里插入图片描述

4.设计总结

在我看来,课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程。随着科学技术发展的日新月异,当今计算机的应用在生活中可以说得是无处不在。
在实践中我遇到许多的问题,通过网上的交流,和同学的帮助,最终我成功的完成了这次课程设计。从中我充分理解了Java面对对象的特性,并体会到Java与C语言的不同之处。只有多动手,经常编写程序,才能发现我们学习上的漏洞和自己的不足,并在实践中解决这些问题,不断提高自己转化知识的能力。通过这次课程设计使我懂得了理论与实际相结合是很重要的,单纯理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。这次编写的程序大部分是通过调用各包中的方法来实现的,这也让我充分理解了包和类之间的关系。
编写整个程序的过程中,思路一开始并不是很清晰,而是用边写边想边调试的方式,导致费时很多,比如各个线程一起跑怎么实现同步来避免程序执行结果很杂乱,还有如何设计模块以及各模块之间的连接方式等等,都是比较容易出错的地方,而且写的时候忽略了一些可能出现的情况使得程序一度不能正确运行,最后还是仔细分析了整个扫描过程之后将程序调试好。所以,不论程序的规模大小,写之前必须理清思路,那将会是事半功倍的。

5.源代码

//AWT核心包,包括组件类、事件类
import java.awt.*;
//AWT核心包,包括组件类、事件类
import java.awt.event.*;
//输入输出流的文件包
import java.io.*;
import java.nio.file.Files;
import java.util.Objects;

/**
 * @author Jiangda
 * @since 2023/2/2 15:05
 */

public class Julia extends WindowAdapter implements ActionListener,ItemListener
{
    /**
     *  frame//声明对象
     */
    private Frame f;

    /**
     *  文本域
     */
    private TextField tf1;
    private TextField tf2;
    private TextField tf3;

    /**
     *  复选框
     */
    private Checkbox cb1;
    private Checkbox cb2;

    /**
     *  选择框
     */
    private Choice c1;
    private Choice c2;

    /**
     * 数据结构
     */
    private List dataList;

    /**
     *  按钮
     */
    private Button b1;
    private Button b2;
    private Button b3;
    private Button b4;
    private Button b5;
    private Button b6;
    private Button b7;
    private Button b8;

    /**
     * 保存文件
     */
    File file=null;

    public static void main(String[] args)
    {
        (new Julia()).display();
    }

    public void display()
    {
        Panel p1;
        Panel p2;
        Panel p3;
        CheckboxGroup cg;
        //实例化对象
        f=new Frame("Input student");
        f.setSize(480,350);
        f.setLocation(200,140);
        f.setBackground(Color.lightGray);
        f.setLayout(new GridLayout(1,2));
        dataList=new List();
        f.add(dataList);
        p1=new Panel();
        p1.setLayout(new GridLayout(7,1));
        p3=new Panel();
        p3.setLayout(new GridLayout(2,4));
        f.add(p1);
        tf1=new TextField("1");
        tf2=new TextField("Name");
        tf3=new TextField("FileName:null");
        cg=new CheckboxGroup();
        cb1=new Checkbox("男",cg,true);
        cb2=new Checkbox("女",cg,false);
        c1=new Choice();
        c1.addItem("江苏省");
        c1.addItem("浙江省");
        c1.addItem("湖南省");
        c1.addItemListener(this);
        c2=new Choice();
        c2.addItem("南京");

        b1=new Button("第一页");
        b1.addActionListener(this);
        b2=new Button("前一页");
        b2.addActionListener(this);
        b3=new Button("下一页");
        b3.addActionListener(this);
        b4=new Button("最后一页");
        b4.addActionListener(this);
        b5=new Button("添加");
        b5.addActionListener(this);
        b6=new Button("删除");
        b6.addActionListener(this);
        b7=new Button("打开");
        b7.addActionListener(this);
        b8=new Button("保存");
        b8.addActionListener(this);
        p1.add(tf1);
        p1.add(tf2);
        p1.add(tf3);
        p2=new Panel();
        //设置为左对齐的按行布局
        p2.setLayout(new FlowLayout(FlowLayout.LEFT));
        p2.add(cb1);
        p2.add(cb2);
        p1.add(p2);
        p1.add(c1);
        p1.add(c2);
        p1.add(p3);
        p3.add(b1);
        p3.add(b2);
        p3.add(b3);
        p3.add(b4);
        p3.add(b5);
        p3.add(b6);
        p3.add(b7);
        p3.add(b8);
        f.addWindowListener(this);
        f.setVisible(true);
    }

    /**
     * 重写父类的方法,记得加上@Override注解
     *
     * @param e 窗口事件
     */
    @Override
    public void windowClosing(WindowEvent e)
    {
        //结束程序运行,关闭窗口
        System.exit(0);
    }

    /**
     * 保存文件
     *
     * @param file 文件
     */
    public void save(File file)
    {
        try(BufferedOutputStream out=new BufferedOutputStream(
           Files.newOutputStream(file.toPath()))){
            //左边列表框中的记录保存到字符串数组
            String[] in=dataList.getItems();
            for(String s : in){
                //把字符转换为字节
                byte[] b=s.getBytes();
                //0~length b字节里的所有记录写入输出流
                out.write(b,0,b.length);
                //回车
                out.write(13);
                //换行
                out.write(10);
            }
        }
        catch(IOException ioe)
        {
            System.out.println(ioe);
        }
    }

    @Override
    //实现Actionlistener接口中的方法,单击按钮时产生该事件
    public void actionPerformed(ActionEvent e) {
        //First,获得产生该事件的对象
        handlerFirst(e);

        //Prior 一个方法的代码行数不要超过80行,可以重构方法
        handlerPrior(e);

        //Next
        handlerNext(e);

        //Last
        handlerLast(e);

        //Add
        handlerAdd(e);

        //Delete
        handlerDelete(e);

        //Open
        handlerOpen(e);

        //Save
        handlerSave(e);
    }

    /**
     *  处理First
     *
     * @param e 监听事件
     */
    private void handlerFirst(ActionEvent e) {
        if(e.getSource()==b1)
        {
            //选中第一条
            dataList.select(0);
        }
    }

    /**
     *  处理prior
     *
     * @param e 监听事件
     */
    private void handlerPrior(ActionEvent e) {
        if (e.getSource() == b2){
            if (dataList.isIndexSelected(0)) {
                dataList.select(dataList.getItemCount() - 1);
            }else{
                dataList.select(dataList.getSelectedIndex() - 1);
            }
        }
    }

    /**
     *  处理Next
     *
     * @param e 监听事件
     */
    private void handlerNext(ActionEvent e) {
        if(e.getSource()==b3) {
            if(dataList.isIndexSelected(dataList.getItemCount()-1)){
                dataList.select(0);
            }else {
                dataList.select(dataList.getSelectedIndex() + 1);
            }
        }
    }

    /**
     *  处理Last
     *
     * @param e 监听事件
     */
    private void handlerLast(ActionEvent e) {
        if (e.getSource()==b4)
        {
            dataList.select(dataList.getItemCount()-1);
        }
    }

    /**
     *  处理Add
     *
     * @param e 监听事件
     */
    private void handlerAdd(ActionEvent e) {
        if(e.getSource()==b5)
        {
            String str;
            str=tf1.getText()+" "+tf2.getText();
            if(cb1.getState())
                //单击按钮选中时,添加标签
                str=str+" "+cb1.getLabel();
            if(cb2.getState())
                str=str+" "+cb2.getLabel();
            //获取选择框中的选项
            str=str+" "+c1.getSelectedItem();
            str=str+" "+c2.getSelectedItem();
            //添加列表选项
            dataList.add(str);
            //编号自动加1
            tf1.setText(""+(Integer.parseInt(tf1.getText())+1));
        }
    }

    /**
     *  处理Delete
     *
     * @param e 监听事件
     */
    private void handlerDelete(ActionEvent e) {
        if (e.getSource()==b6)
        {
            dataList.remove(dataList.getSelectedItem());
        }
    }

    /**
     *  处理Open
     *
     * @param e 监听事件
     */
    private void handlerOpen(ActionEvent e) {
        if (e.getSource()==b7)
        {   dataList.removeAll();//在打开的同时自动删除以前记录
            FileDialog fdOpen=new FileDialog(f,"Open",FileDialog.LOAD);
//		fd_open.show();//显示对话框
            fdOpen.setVisible(true);
            if((fdOpen.getDirectory()!=null)&&(fdOpen.getFile()!=null))
            {   tf3.setText(fdOpen.getDirectory()+fdOpen.getFile());
                try
                { File file=new File(fdOpen.getDirectory()+fdOpen.getFile());
                    FileReader fr=new FileReader(file);
                    //把fr内容读入br中
                    BufferedReader br=new BufferedReader(fr);
                    String line;//字符串类的一个对象
                    while((line=br.readLine())!=null)
                        dataList.add(line+"\r\n");
                    fr.close();
                    //关闭输入流
                    br.close();
                }
                catch(IOException ioe)
                {System.out.println(ioe);}
            }
        }
    }

    /**
     *  处理Save
     *
     * @param e 监听事件
     */
    private void handlerSave(ActionEvent e) {
        if (e.getSource()==b8 && Objects.isNull(file))
        {
            FileDialog fdClose=new FileDialog(f,"Save",FileDialog.SAVE);
            fdClose.setFile("LC.txt");

            fdClose.setVisible(true);
            if((fdClose.getDirectory()!=null)&&(fdClose.getFile()!=null))
            {
                tf3.setText(fdClose.getDirectory()+fdClose.getFile());
                file=new File(fdClose.getDirectory(),fdClose.getFile());
                save(file);
            }
            else {
                save(file);
            }
        }
    }

    @Override
    public void itemStateChanged(ItemEvent e)
    {
        //对选择框C1操作时触发
        if(c1.getSelectedIndex()==0)
        {
            //清除选择框C2全部内容
            c2.removeAll();
            //选择框C2添加内容
            c2.addItem("南京");
            c2.addItem("苏州");
            c2.addItem("无锡");
        }
        if(c1.getSelectedIndex()==1)
        {
            c2.removeAll();
            c2.addItem("杭州");
            c2.addItem("宁波");
            c2.addItem("温州");
        }
        if(c1.getSelectedIndex()==2)
        {
            c2.removeAll();
            c2.addItem("长沙");
            c2.addItem("衡阳");
            c2.addItem("郴州" );
        }
    }
}

博主后记:
希望看到此篇博文的网友,如果发现有什么不对的地方,欢迎在下方留言指正!博主一定虚心接受并改正!大家一起共同进步。如果对你有所帮助,可以给博主一个赞👍。

想要获取详细源代码和课设设计报告,可以点赞、关注私信我!若没及时回,可直接添加我的Wechat,一定备注来意!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日 近 长 安 远

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值