一只刚学java的菜鸡一次练手练习——简易的快递信息管理系统
由于是新手第一次写练手项目并且是自学,例如存储查询数据的方式并没有选择最合适的集合,GUI也写的比较丑,见谅哈哈哈
以下是正文:
首先是快递订单信息对象的创建(滞纳金偷懒就没弄。。。所以全部注释掉了)
package Information;
import java.io.*;
//快递信息类
public class ExpressInformation implements Serializable//Serializable接口用于数据序列化
{
//以下数据暂考虑为直接初始化
private int Kind;//快递类别(分为加急和正常,加急为1,正常为2)
private String ID;//快递的ID;
private String Addressee;//收件人
private String Sender;//寄件人
//private double Fine_of_Day;//每日滞纳费
//以下的为快递到达运输点再进行初始化(利用方法
private String ReceiveDate;//签收日期
private String SendDate;//到站日期(送到快递站的日期
//private double Fine;//用户需缴纳滞纳费(按照快递签收日期-快递收到日期得到天数乘以每日滞纳费用得到
public ExpressInformation()
{
}
//创建一个订单必须传入快递类别,订单号,收件人名称,寄件人名称
public ExpressInformation(int Kind,String ID,String Addressee,String Sender)
{
this.Kind = Kind;
this.ID = ID;
this.Addressee = Addressee;
this.Sender = Sender;
//this.Fine_of_Day = 0.5;
this.ReceiveDate = null;
this.SendDate = null;
//this.Fine = 0;
}
public int getKind()//查询该订单的类别
{
return this.Kind;
}
public String getID()//查询该订单的ID
{
return this.ID;
}
public String getAddressee()//查询该订单的收件人
{
return this.Addressee;
}
public String getSender()//查询该订单的寄件人
{
return this.Sender;
}
public void setReceiveDate(String date)//设置签收日期
{
this.ReceiveDate = date;
}
public String getReceiveDate()//查询签收日期
{
return this.ReceiveDate;
}
public void setSendDate(String date)//设置送到快递站的日期
{
this.SendDate = date;
}
public String getSendDate()//查询送到快递站的日期
{
return this.SendDate;
}
}
接来下就是整个系统的主体部分:
(ps:很多人说java的swing和awt在国内用的很少,并不是很有必要去深入学习,能大概用点简单的就够了,如果这里说的不对望指正)
1.主菜单界面
这里用了很多JPanel,主要是为了感官上稍微好看点,也不是很必要
package System;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
/*
* 主菜单界面,可以选择读取订单,修改订单,创建新订单等
*/
@SuppressWarnings("serial")
public class MainMenu extends JFrame implements ActionListener
{
JButton creat,query,modify,exit;//创建,查询,修改,退出
JLabel title;//用于写标题的标签
JPanel jp1,jp2,jp3,jp4,jp5 = null;
public MainMenu()
{
//容器初始化
this.jp1 = new JPanel();
this.jp2 = new JPanel();
this.jp3 = new JPanel();
this.jp4 = new JPanel();
this.jp5 = new JPanel();
//按钮初始化
this.creat = new JButton("创建新订单");
this.query = new JButton("查询订单");
this.modify = new JButton("修改订单");
this.exit = new JButton("退出");
//为按钮添加监听事件
this.creat.addActionListener(this);
this.query.addActionListener(this);
this.modify.addActionListener(this);
this.exit.addActionListener(this);
//标签初始化
this.title = new JLabel("大学生快递管理系统");
//将组件装入容器
this.jp1.add(title);
this.jp2.add(creat);
this.jp3.add(query);
this.jp4.add(modify);
this.jp5.add(exit);
//将所有容器装入面板
this.add(jp1);
this.add(jp2);
this.add(jp3);
this.add(jp4);
this.add(jp5);
//面板属性设置
this.setLayout(new GridLayout(5,1));//这里是用了网格布局,5行1列
this.setTitle("大学生快递管理系统");
this.setSize(350,250);
this.setLocation(700, 200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);//窗体可视
}
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand() == "创建新订单")//通过按钮的监听事件返回点击按钮的名称(但如果是两个String必须用
//equals()比较哦,不然只是比较的地址)
{
this.dispose();
CreatNewOrder creat_UI = new CreatNewOrder();//打开创建订单对象
}
else if(e.getActionCommand() == "查询订单")
{
this.dispose();
QueryDate query_UI = new QueryDate();
}
else if(e.getActionCommand() == "修改订单")
{
this.dispose();
ModifyOrder modify_UI = new ModifyOrder();
}
else if(e.getActionCommand() == "退出")
{
this.dispose();
}
}
public static void main(String[] args)
{
MainMenu test = new MainMenu();
// TODO Auto-generated method stub
}
}
2.订单创建界面
这个是创建订单成功后的消息提示框:JOptionPane.showMessageDialog(null, “创建成功”);
package System;
import Information.ExpressInformation;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.*;
/*
* 创建新订单界面的GUI和创建新订单的方法
*/
public class CreatNewOrder extends JFrame implements ActionListener
{
JPanel jp1,jp2,jp3,jp4,jp5;//四个面板,用来放置标签等元素
JLabel id_l, sender_l, addressee_l;//标签
JTextField id_t, sender_t, addressee_t;//输入快递ID,寄送人,收件人信息的文本框
JRadioButton urgent, ordinary;//加急和普通件选项按钮
JButton clear, confirm, back;//清空文本框,确认,返回上一个页面选项
ButtonGroup bg; //按钮群组,放置快递类别按钮
public CreatNewOrder()
{
//面板初始化
this.jp1 = new JPanel();
this.jp2 = new JPanel();
this.jp3 = new JPanel();
this.jp4 = new JPanel();
this.jp5 = new JPanel();
//标签创建
this.id_l = new JLabel("快递ID:");
this.sender_l = new JLabel("寄件人姓名:");
this.addressee_l = new JLabel("收件人姓名:");
//创建文本输入框
this.id_t = new JTextField(20);
this.sender_t = new JTextField(20);
this.addressee_t = new JTextField(20);
//快件分类选择按钮创建
this.urgent = new JRadioButton("加急");
this.ordinary = new JRadioButton("普通");
//初始化按钮群组对象,将按钮放入
this.bg = new ButtonGroup();
this.bg.add(urgent);
this.bg.add(ordinary);
this.ordinary.setSelected(true);//设置默认选择普通类别
//创建操作按钮
this.clear = new JButton("清空输入内容");
this.confirm = new JButton("确认创建订单");
this.back = new JButton("返回");
//将各类组件加入面板
this.jp1.add(id_l);
this.jp1.add(id_t);
this.jp2.add(sender_l);
this.jp2.add(sender_t);
this.jp3.add(addressee_l);
this.jp3.add(addressee_t);
this.jp4.add(urgent);
this.jp4.add(ordinary);
this.jp5.add(clear);
this.jp5.add(confirm);
this.jp5.add(back);
this.add(jp1);
this.add(jp2);
this.add(jp3);
this.add(jp4);
this.add(jp5);
//添加监听事件
this.clear.addActionListener(this);
this.back.addActionListener(this);
this.confirm.addActionListener(this);
this.setLayout(new GridLayout(5,1));//选择GridLayout布局管理器
this.setTitle("新订单创建");
this.setSize(700,250);
this.setLocation(600, 200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置当关闭窗口时,保证JVM也退出
this.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand() == "清空输入内容")
{
clear_text();
}
else if(e.getActionCommand() == "确认创建订单")
{
creat();
JOptionPane.showMessageDialog(null, "创建成功");
this.dispose();
MainMenu main_ui = new MainMenu();
}
else if(e.getActionCommand() == "返回")
{
this.dispose();
MainMenu main_ui = new MainMenu();
}
}
public void clear_text()//清空所以JTextField中的数据
{
this.id_t.setText("");
this.sender_t.setText("");
this.addressee_t.setText("");
}
public void creat()
{
ExpressInformation n;//将要创建的新订单
ArrayList<ExpressInformation> data;//引用读取的数据
if(this.urgent.isSelected())
{
//JTextField.getText()方法可以返回当前输入范围内的字符串内容
n = new ExpressInformation(1,id_t.getText(),addressee_t.getText(),sender_t.getText());
}
else
{
n = new ExpressInformation(2,id_t.getText(),addressee_t.getText(),sender_t.getText());
}
//创建后直接存入文件
LoadInformation l = new LoadInformation();//创建读入数据对象
SaveInformation s = new SaveInformation();//创建保存数据对象
if(l.Load())//如果存在数据
{
data = l.getData();
data.add(n);
s.Save(data);
}
else
{
data = new ArrayList<ExpressInformation>();//创建个新动态数组放入文件
data.add(n);
s.Save(data);
}
}
/*public static void main(String[] args)
{
CreatNewOrder CreatUI = new CreatNewOrder();
}*/
}
3.查询订单信息界面
package System;
import javax.swing.*;
import javax.swing.table.TableColumn;
import Information.ExpressInformation;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
public class QueryDate extends JFrame implements ActionListener
{
JButton exit;//返回按钮暂
JTable table;//放置数据的表格组件
JScrollPane panel;//放置表格的视图组件
JPanel jp1,jp2;//放置组件的容器
Box buttonBox;//放置按钮的盒容器组件
private LoadInformation load;//获取文件数据的对象
private ArrayList<ExpressInformation> data;//存储获取的数据的对象(动态数组)
public QueryDate()
{
//初始化用于查询数据的类
this.load = new LoadInformation();
//初始化容器
this.jp1 = new JPanel();
this.jp2 = new JPanel();
//初始化按钮并添加监听事件
this.exit = new JButton("返回");
this.exit.addActionListener(this);
//创建出表单GUI
InitTable();
Box buttonBox = new Box(BoxLayout.Y_AXIS);
buttonBox.add(exit);
this.add(BorderLayout.EAST,buttonBox);
this.add(BorderLayout.NORTH, new JLabel("订单列表"));
this.setLocation(600, 200);
this.setSize(800,800);
this.setTitle("订单列表");
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
}
//初始化表单用函数
public void InitTable()
{
this.load.Load();
this.data = this.load.getData();
ExpressInformation p;//暂存数据用
int index = 0;//循环用
String[] colnames = {"快递类别","单号","寄件人","收件人","到站日期","签收日期"};
int rows = this.data.size();
Object[][] obj = new Object[rows][6];
for(Iterator<ExpressInformation> it = this.data.iterator();
it.hasNext() && rows != 0;)
{
p = it.next();
if(p.getKind() == 1)
{
obj[index][0] = "加急";
}
else
{
obj[index][0] = "普通";
}
obj[index][1] = p.getID();
obj[index][2] = p.getSender();
obj[index][3] = p.getAddressee();
obj[index][4] = p.getSendDate();
obj[index][5] = p.getReceiveDate();
index++;
}
JTable table=new JTable(obj, colnames);
TableColumn column=null; //TableColumn用于表示JTable的属性
int colunms = table.getColumnCount();
for(int i=0;i<colunms;i++)
{
column = table.getColumnModel().getColumn(i);
column.setPreferredWidth(100);
}
//table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JScrollPane scroll = new JScrollPane(table);
scroll.setSize(300,300);
this.add(BorderLayout.CENTER,scroll);//这里这个布局用的没啥用,主要是下一个模块要用
//this.add(scroll);
}
public void actionPerformed(ActionEvent e)
{
this.dispose();
MainMenu main_UI = new MainMenu();
}
/*public static void main(String[] args)
{
QueryDate test = new QueryDate();
}*/
}
4.修改订单界面
其实完全可以和查询合并成一个,但为了方便看清楚于是分成两个写了
package System;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.*;
import javax.swing.table.TableColumn;
import Information.*;
/*
* 修改订单信息(需要调用QueryDate)
*/
public class ModifyOrder extends JFrame implements ActionListener
{
JPanel jp1,jp2,jp3,jp4,jp5,jp6,jp7;//摆放标签,文本框,按钮的容器
JTextField ID_t;//输入想要修改签收或者到站日期的订单号的文本框
JLabel ID_l;//标签
JButton have_send, have_rec, clear, delete ,back;//设置到站日期,设置签收日期,清空输入框,删除该订单,返回主菜单
Box right_box;//位于框架右侧的组件组
private LoadInformation load;//读入数据操作对象
private SaveInformation save;//存储数据操作对象
private ArrayList<ExpressInformation> data;//放置数据对象
public ModifyOrder()
{
//初始化容器
this.jp1 = new JPanel();
this.jp2 = new JPanel();
this.jp3 = new JPanel();
this.jp4 = new JPanel();
this.jp5 = new JPanel();
this.jp6 = new JPanel();
this.jp7 = new JPanel();
this.ID_l = new JLabel("订单号:");
this.ID_t = new JTextField(15);
this.jp1.add(this.ID_l);
this.jp2.add(this.ID_t);
//初始化按钮
this.have_send = new JButton("快递到站");
this.have_rec = new JButton("快递签收");
this.delete = new JButton("删除该订单");
this.clear = new JButton("清空输入");
this.back = new JButton("返回主菜单");
//将所有按钮组件放入容器再最后放入jp_main中(这样做只是因为好看点
this.jp3.add(this.have_send);
this.jp4.add(this.have_rec);
this.jp5.add(this.delete);
this.jp6.add(this.clear);
this.jp7.add(this.back);
//初始化存储读入数据需要的对象和存储类的对象
this.load = new LoadInformation();
this.save = new SaveInformation();
this.load.Load();
this.data = this.load.getData();
//调用创建表单的方法
InitTable();
//按钮添加监听事件
this.have_send.addActionListener(this);
this.have_rec.addActionListener(this);
this.delete.addActionListener(this);
this.clear.addActionListener(this);
this.back.addActionListener(this);
//将放按钮组件的Box容器初始化
this.right_box = new Box(BoxLayout.Y_AXIS);//竖置摆放
this.right_box.add(this.jp1);
this.right_box.add(this.jp2);
this.right_box.add(this.jp3);
this.right_box.add(this.jp4);
this.right_box.add(this.jp5);
this.right_box.add(this.jp6);
this.right_box.add(this.jp7);
//JFrame初始化
this.add(BorderLayout.EAST,this.right_box);
this.setTitle("订单修改");
this.setLocation(600, 200);
this.setSize(700,800);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
}
public void actionPerformed(ActionEvent e)
{
ExpressInformation temp = new ExpressInformation();//暂存修改订单的对象(如果不在这进行初始化,始终会报错
int index;//修改订单的下标位置
index = if_id_exist();
if(e.getActionCommand() == "快递到站")//订单被签收,修改其签收日期
{
if(index == -1)
{
JOptionPane.showMessageDialog(null, "订单不存在");
return;
}
else if(index != -1)
{
temp = this.data.get(index);//从数组获得想要修改的对象
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");//设置日期格式
temp.setSendDate(df.format(new Date()));//Date()获得系统时间,df.fomat(new Date())返回代表时间的字符串
this.save.Save(this.data);
JOptionPane.showMessageDialog(null, "修改成功");
this.dispose();
ModifyOrder modify_UI = new ModifyOrder();
}
}
else if(e.getActionCommand() == "快递签收")
{
if(index == -1)
{
JOptionPane.showMessageDialog(null, "订单不存在");
return;
}
else if(index != -1)
{
temp = this.data.get(index);//从数组获得想要修改的对象
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");//设置日期格式
temp.setReceiveDate(df.format(new Date()));
this.save.Save(this.data);
JOptionPane.showMessageDialog(null, "修改成功");
this.dispose();
ModifyOrder modify_UI = new ModifyOrder();
}
}
else if(e.getActionCommand() == "删除该订单")
{
if(index == -1)
{
JOptionPane.showMessageDialog(null, "订单不存在");
return;
}
else
{
this.data.remove(index);//通过下标从动态数组中删除该订单对象
this.save.Save(this.data);
JOptionPane.showMessageDialog(null, "删除成功");
this.dispose();
ModifyOrder modify_UI = new ModifyOrder();
}
}
else if(e.getActionCommand() == "清空输入")//清空输入框
{
clear_text();
}
else if(e.getActionCommand() == "返回主菜单")//返回主菜单
{
this.dispose();//销毁当前窗口
MainMenu m = new MainMenu();//创建主菜单窗体对象
}
}
//判断订单是否存在的方法
public int if_id_exist()
{
String id;//想要修改的订单号的ID
ExpressInformation p;//暂存数据用
int index = 0;//方便使用ArrayList的下标检索方法get修改订单
id = this.ID_t.getText();
//PS:其实这是里用映射更方便找数据,但我tm写了半天才想起来
for(Iterator<ExpressInformation> it = this.data.iterator();
it.hasNext();)
{
p = it.next();
if(id.equals(p.getID()))//id存在返回其在数组的下标(用equal方法
{
return index;
}
index++;
}
return -1;//不存在该id返回-1
}
public void InitTable()//QueryDate也用了该函数
{
ExpressInformation p;//暂存数据用
int index = 0;//循环用
String[] colnames = {"快递类别","单号","寄件人","收件人","到站日期","签收日期"};
int rows = this.data.size();
Object[][] obj = new Object[rows][6];
for(Iterator<ExpressInformation> it = this.data.iterator();
it.hasNext() && rows != 0;)
{
p = it.next();
if(p.getKind() == 1)
{
obj[index][0] = "加急";
}
else
{
obj[index][0] = "普通";
}
obj[index][1] = p.getID();
obj[index][2] = p.getSender();
obj[index][3] = p.getAddressee();
obj[index][4] = p.getSendDate();
obj[index][5] = p.getReceiveDate();
index++;
}
JTable table=new JTable(obj, colnames);
TableColumn column=null; //TableColumn用于表示JTable的属性
int colunms = table.getColumnCount();
for(int i=0;i<colunms;i++)
{
column = table.getColumnModel().getColumn(i);
column.setPreferredWidth(100);
}
//table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JScrollPane scroll = new JScrollPane(table);
scroll.setSize(300,300);
this.add(BorderLayout.CENTER,scroll);
}
public void clear_text()//虽然只有一句,但也是为了方便以后加功能
{
this.ID_t.setText("");
}
/*public static void main(String[] args)
{
ModifyOrder test = new ModifyOrder();
}*/
}
5.保存数据到文件中的对象
package System;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import Information.ExpressInformation;
/*
* 用于将数据保存到文件中
* Save()将数据从动态数组保存到文件
*/
public class SaveInformation implements Serializable
{
private File filename;
public SaveInformation()
{
this.filename = new File("data.text");
}
public void Save(ArrayList<ExpressInformation> data)
{
ExpressInformation d;
try
{
FileOutputStream date_out = new FileOutputStream(this.filename);
ObjectOutputStream obj_date_out = new ObjectOutputStream(date_out);
for(Iterator<ExpressInformation> it = data.iterator(); it.hasNext();)//利用迭代器遍历ArrayList
{
d = it.next();
obj_date_out.writeObject(d);
}
date_out.close();
obj_date_out.close();
}
catch(IOException e)
{
System.out.println(e);
}
}
/*public static void main(String[] args)
{
}*/
}
6.从文件中读取数据的对象
这里对象反序列化读取的时候需要注意到一个问题:EOFException异常
这个异常是无法避免的,但只需要用一个try/catch块就可以解决
package System;
import Information.ExpressInformation;
import java.io.*;
import java.util.ArrayList;
/*
* 从保存数据的文件读取数据
* getDate()获得存储着数据的数组
* Load()从文件获取数据并且保存到ArrayList动态数组中
*/
public class LoadInformation implements Serializable
{
private File filename;//存储数据的文件名
private ArrayList<ExpressInformation> data;//用于保存数据的动态数组
public LoadInformation()
{
this.filename = new File("data.text");
this.data = new ArrayList<ExpressInformation>();
}
public ArrayList<ExpressInformation> getData()//获得存储数据的数组
{
return this.data;
}
public boolean Load()//打开存储数据的文件,并且载入数据(false表示无数据,true表示文件中有数据
{
ExpressInformation d;
try
{
FileInputStream data_in = new FileInputStream(this.filename);//打开一个文件读入流
ObjectInputStream obj_data_in = new ObjectInputStream(data_in);//打开一个类数据读入流
try//ObjectInputSteam反序列化流必定会产生一个EOFException的异常(无法避免)
{
while((d = (ExpressInformation)obj_data_in.readObject()) != null)
{
this.data.add(d);
}
}
catch(EOFException e)//空catch只是捕获一下异常
{
}
obj_data_in.close();
data_in.close();
}
catch(FileNotFoundException e)//保存数据的文件如果未建立
{
return false;
}
catch(IOException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
if(data.size() == 0)//数据文件建立,但其中并无数据
{
return false;
}
return true;
}
/*public static void main(String[] args)
{
}*/
}
总结:
其实这个东西写起来很简单,并没有什么难度,但我所有的东西和问题都是我通过浏览网上的各种博客和查看文档独立解决的,也许这些基础的东西并不能让你学到什么,可是如果你是一个初学的新人,你能独立自主地完成这样简易的小练习,是可以很大地锻炼你独立学习的能力的,毕竟学习路上不可能永远有人指导。