Java Swing通讯录管理系统文档

12344

贡献于2011-08-25

字数:32115 关键词: 设计文档 Swing Java开发 Java SQL

A 通讯录管理系统 随着社会的发展,人际关系变得越来越重要,为了保持良好的人际关系,必须经常与亲戚、朋友、同学、同事和其他一些人保持联系,因此,为了能够快速查找到联系人的信息,节省查找时间,可以创建一个通讯录管理系统,在该系统中为了防止信息被他人窃取,可以通过密码进行验证,只有通过密码验证才能进入系统。通讯录管理系统主窗体界面如图A.1所示。 图A.1 通讯录管理系统主窗体 A.1程序预览 下面我们首先来浏览一下整个系统的运行过程,由于整个系统分为家人、朋友、同学、同事和其他5类,并且这5类信息的操作过程是一样的,所以下面主要以家人信息进行介绍。 1.系统运行后,首先进入系统登录模块,效果如图A.2所示。 图A.2 系统登录窗体 2.在图A.2所示的系统登录模块中可以通过输入正确的用户“mr”和密码“mrsoft”,单击“登录”按钮进入通讯录管理系统的主窗体界面,通讯录管理系统的主窗体界面如图A.3所示,可以通过菜单和工具栏进入相应的模块。 图A.3 通讯录管理系统主窗体 3.在通讯录管理系统的主窗体中,单击“家人”/“添加信息”菜单项,可以打开添加家人信息模块,如图A.4所示,在该界面中可以输入家人的联系信息,然后单击“保存”按钮,保存此次输入的家人联系信息。 图A.4 添加家人信息模块 4.在通讯录管理系统的主窗体中,单击“家人”/“修改信息”菜单项,可以打开修改家人信息模块,如图A.5所示,在该界面中可以修改家人的联系信息,方法是首先在下面的表格中选择要修改的家人信息,然后在编辑组件中输入要修改的内容,单击“修改”按钮,保存此次信息的修改。 图A.5 修改家人信息模块 5.在通讯录管理系统的主窗体中,单击“家人”/“删除信息”菜单项,可以打开删除家人信息模块,如图A.6所示,从表格中选择要删除的家人信息,然后单击“删除”按钮,即可删除所选择的家人联系信息。 图A.6 删除家人信息模块 6.在通讯录管理系统的主窗体中,单击“家人”/“查询信息”菜单项,可以打开查询家人信息模块,如图A.7所示,在该界面中默认在表格中显示所有家人的联系信息,也可以从“查询条件:”标签右侧的组合框中选择查询字段,然后在右侧的文本框中输入对应的查询内容,单击“查询”按钮,即可查询出指定条件的家人联系信息。 图A.7 查询家人信息模块 A.2 需求分析 需求分析阶段的主要任务是确定目标系统的功能,设计应用程序的第一个步骤就是根据用户的需求规划系统的功能。作为应用程序的第一要求,也是最主要的要求就是满足用户的需求。如果连这一点都做不到,即使系统的功能再强大、界面再美观,也是一个失败的项目,因为它没有应用价值。因此实用性是衡量软件的第一标准。而系统功能的规划是软件实用性的核心。下面是通讯录管理系统的功能规划。 系统登录模块 包括登录系统和退出应用程序2个功能,其功能结构如图A.8所示。 图A.8 系统登录窗体功能结构图 家人信息模块 包括添加家人信息、修改家人信息、删除家人信息和查询家人信息4个功能,其功能结构如图A.9所示。 图A.9 家人信息管理模块功能结构图 朋友信息模块 包括添加朋友信息、修改朋友信息、删除朋友信息和查询朋友信息4个功能,其功能结构如图A.10所示。 图A.10 朋友信息管理模块功能结构图 同学信息模块 包括添加同学信息、修改同学信息、删除同学信息和查询同学信息4个功能,其功能结构如图A.11所示。 图A.11 同学信息管理模块功能结构图 同事信息模块 包括添加同事信息、修改同事信息、删除同事信息和查询同事信息4个功能,其功能结构如图A.12所示。 图A.12 同事信息管理模块功能结构图 其他信息模块 包括添加其他人信息、修改其他人信息、删除其他人信息和查询其他人信息4个功能,其功能结构如图A.13所示。 根据上述功能规划,可以对各功能模块设计功能结构图。 图A.13 其他信息管理模块功能结构图 A.3 设计数据库 在通讯录管理系统中,我们采用MySQL作为后台数据库,存储系统信息。对于用户信息和联系人信息我们要存储起来,这样可以方便以后的使用,因此我们需要创建一个数据库,这里我们创建了一个名为“db_addresslist”的数据库,创建完数据库,接下来就可以创建所需要的表了,本系统需要两个数据表,一个用于存储用户信息,另一个用户存储联系人信息,下面将分别介绍: (1)根据系统的需要,只有合法用户才能进入系统,为此我们设计了存放用户信息的表tb_user,tb_user表的结构如表A.1所示。 表A.1 tb_user表的结构 (2)根据系统的需要,还要能够快速操作联系人的信息,如添加联系人信息、修改联系人信息、删除联系人信息和查找联系人信息,为此我们设计了存放联系人信息的表tb_message,tb_message表的结构如表A.2所示。 表A.2 tb_message表的结构 A.4 开发应用程序 根据通讯录管理系统各模块的功能结构,本系统应按如下顺序进行开发: (1)由于通讯录管理系统主要是对联系人信息进行操作,而联系人信息是存储在数据库表中的,只有合法用户登录系统后才可以操作联系人信息,所有这些都需要对数据库进行操作, 因此首选择应该创建封装数据信息的实体公共类和操作数据库的数据访问对象公共类。下面分别介绍: ① 封装联系人信息的实体公共类Message,用于封装所有的联系人信息,包括家人、朋友、同事、同学和其他人等。 ② 操作数据库的数据访问对象公共类DAO,用于实现所有的数据库操作,包括加载数据库驱动、连接数据库,操作数据表等。 (2)为了使通讯录管理系统主窗体的界面美观,可以给主窗体加上背景图片,为此我们设计一个用户设计窗体背景的公共面板类BackgroundPanel。下面对该类进行介绍: 公共类BackgroundPanel是一个背景面板类,使用时通过构造方法为该类传递一个需要显示的图像对象,然后将该类的实例放到通讯录主窗体的上使其显示背景图片。 (3)由于通讯录管理系统按家人、朋友、同学、同事和其他进行分类,而这5个分类使用的是同一个数据库表存储信息,所以这5个分类模块的增、删、改、查界面基本相同,因此为了提高本系统的开发效率,这5个分类模块的增、删、改、查使用同一个用户界面,为了知道是哪个分类的信息,我们设计了公共类SaveTypeState。下面对该类进行介绍: 公共类SaveTypeState是一个保存分类信息的类,该类可以用于保存分类信息、保存主窗体的标题信息和保存主窗体上标签的标题信息 (4)为了防止信息被其他用户非法窃取,本系统设计了系统登录模块,只有合法用户输入正确的用户名和密码才可进入系统主窗体,否则不能进入系统。 (5)系统主窗体用于按分类打开实现增、删、改、查的功能模块,方便用户操作,该界面是本系统的灵魂所在,只有进入该界面才能进行系统的其他操作,比如添加联系人信息、查询联系人信息等。 (6)设计实现本系统的增、删、改、查功能的4个模块,用于实现本系统的增、删、改、查功能,即实现添加联系人信息、修改联系人信息、删除联系人信息和查询联系人信息等操作。 接下来我们就可以按本系统的开发顺序进行开发了。 A.4.1 创建项目 下面我们来介绍通讯管理系统的实现过程。 (1)打开Eclipse集成开发工具,单击“文件”/“新建”/“Java 项目”菜单项,打开“新建 Java 项目”对话框,如图A.14所示,在“项目名”右侧的文本框中输入项目的名称,本系统输入的项目名称是“通讯录管理系统”,其他选项采用默认设置,单击“完成”按钮,完成项目的创建。 图A.14 新建Java项目 (2)创建完项目后,在包资源管理器中看到如图A.15所示的文件夹结构。 图A.15 文件夹结构 A.4.2 公共实体类Message (1)在包资源管理器中的src文件夹上单击鼠标右键,在弹出的菜单中选择“新建”/“包”菜单项,打开“新建 Java 包”对话框,如图A.16所示,在“名称”右侧的文本框中输入包名“com.zzk.db”,该包用于存放实体类Message,单击“完成”按钮,完成包的创建。 图A.16 新建Java包对话框 (2)在包资源管理器中的包名“com.zzk.db”上单击鼠标右键,在弹出的菜单中选择“新建”/“类”菜单项,打开“新建 Java 类”对话框,在“名称”右侧的文本框中输入类名“Message”,单击“完成”按钮,完成实体类Message的创建。该类代码如下: package com.zzk.db; public class Message { // 该类的成员变量 private String id; // 编号 private String name; // 姓名 private String sex; // 性别 private String birthday; // 出生日期 private String nation; // 民族 private String zuoji; // 座机号码 private String shouji; // 手机号码 private String qq; // QQ号码 private String email; // 电子信箱 private String address; // 家庭住址 private String youbian; // 邮政编码 private String type; // 类型 private String memo; // 备注 public String getId(){ // id的get方法 return id; } public void setId(String id){ // id的set方法 this.id=id; } // 省略了其他的get和set方法 } A.4.3 公共数据访问对象类DAO (1)在包资源管理器中的通讯录管理系统文件夹中建立lib文件夹,把本系统需要的MySQL驱动类库“mysql-connector-java-3.0.16-ga-bin.jar”复制到该文件夹中。 (2)构建MySQL驱动的类库路径,在“通讯录管理系统”文件夹上单击鼠标右键,在弹出的菜单中选择“构建路径”/“配置构建路径”菜单项,打开“通讯录管理系统的属性”对话框,如图A.17所示,单击“添加Jar”按钮,将lib文件夹中的MySQL驱动类库“mysql-connector-java-3.0.16-ga-bin.jar”添加到Java构建路径中,单击“确定”按钮完成MySQL驱动类库的构建。 图A.17 构建MySQL驱动类库 (3)在包资源管理器中的src文件夹上单击鼠标右键,在弹出的菜单中选择“新建”/“包”菜单项,打开“新建 Java 包”对话框,在“名称”右侧的文本框中输入包名“com.zzk.dao”,该包用于存放操作数据库的数据访问对象类DAO,单击“完成”按钮,完成包的创建,在包名“com.zzk.dao”上单击鼠标右键,在弹出的菜单中选择“新建”/“类”菜单项,打开“新建 Java 类”对话框,在“名称”右侧的文本框中输入类名“DAO”,单击“完成”按钮,完成数据访问对象DAO类的创建,该类实现的所有的数据库操作。DAO类代码如下: package com.zzk.dao; import java.sql.*; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Vector; import javax.swing.JOptionPane; import com.zzk.db.Message; public class DAO { private static DAO dao=new DAO(); // 创建DAO对象 public DAO(){ try { Class.forName("com.mysql.jdbc.Driver"); // 加载数据库驱动类 } catch (ClassNotFoundException e) { JOptionPane.showMessageDialog(null, "数据库驱动加载失败。"); } } /** * 获得数据库连接的方法 * @return Connection */ public static Connection getConn(){ try { Connection conn=null; // 定义数据库连接 String url="jdbc:mysql://localhost:3306/db_addresslist"; // 声明数据库的URL String user="root"; // 数据库用户 String password="111"; // 数据库密码 conn=DriverManager.getConnection(url, user, password); // 建立数据库连接 return conn; // 返回连接 } catch (Exception e) { JOptionPane.showMessageDialog(null, "数据库连接失败。\n"+e.getMessage()); return null; } } /** * 判断用户名和密码的方法 * @param user 用户名 * @param pwd 密码 * @return true用户名和密码正确,false用户名和密码不正确 */ public static boolean okUser(String user,String pwd){ try{ Connection conn=getConn(); // 获得数据库连接 // 创建PreparedStatement对象,并传递SQL语句 PreparedStatement ps=conn.prepareStatement("select password from tb_user where username=?"); ps.setString(1, user); // 为参数赋值 ResultSet rs=ps.executeQuery(); // 执行SQL语句,获得查询结果集 if (rs.next() && rs.getRow()>0){ // 查询到用户信息 String password=rs.getString(1); // 获得密码 if (password.equals(pwd)){ return true; // 密码正确返回true }else{ JOptionPane.showMessageDialog(null, "密码不正确。"); return false; // 密码错误返回false } }else{ JOptionPane.showMessageDialog(null, "用户名不存在。"); return false; // 用户不存在返回false } }catch(Exception ex){ JOptionPane.showMessageDialog(null, "数据库异常!\n"+ex.getMessage()); return false; // 数据库异常返回false } } /** * 向数据库中添加联系人信息的方法 * @param m 实体类Message的对象 */ public static void insert(Message m){ try{ Connection conn=getConn(); // 获得数据连接 // 创建PreparedStatement对象,并传递SQL语句 PreparedStatement ps=conn.prepareStatement("insert into tb_message (name,sex,birthday,nation,phone,handset,qq,email,address,postalcode,sort,memo) values(?,?,?,?,?,?,?,?,?,?,?,?)"); ps.setString(1, m.getName()); // 通过实例类的实例为第1个参数赋值 ps.setString(2, m.getSex()); // 通过实例类的实例为第2个参数赋值 // 创建日期格式化对象,并指定格式 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); Date date = format.parse(m.getBirthday()); // 将实体类的出生日期转换为Date类型 ps.setTimestamp(3, new Timestamp(date.getTime())); // 通过实例类的实例为第3个参数赋值 ps.setString(4, m.getNation()); // 通过实例类的实例为第4个参数赋值 ps.setString(5, m.getZuoji()); // 通过实例类的实例为第5个参数赋值 ps.setString(6, m.getShouji()); // 通过实例类的实例为第6个参数赋值 ps.setString(7, m.getQq()); // 通过实例类的实例为第7个参数赋值 ps.setString(8, m.getEmail()); // 通过实例类的实例为第8个参数赋值 ps.setString(9, m.getAddress()); // 通过实例类的实例为第9个参数赋值 ps.setString(10, m.getYoubian()); // 通过实例类的实例为第10个参数赋值 ps.setString(11,m.getType()); // 通过实例类的实例为第11个参数赋值 ps.setString(12,m.getMemo()); // 通过实例类的实例为第12个参数赋值 int flag=ps.executeUpdate(); // 执行SQL语句,获得更新记录数 if (flag>0){ JOptionPane.showMessageDialog(null, "添加成功!"); }else{ JOptionPane.showMessageDialog(null, "添加失败!"); } ps.close(); conn.close(); // 关闭连接 }catch(Exception ex){ JOptionPane.showMessageDialog(null, "添加失败!\n"+ex.getMessage()); } } /** * 修改联系人信息的方法 * @param m 实体类Message的对象 */ public static void update(Message m){ try{ Connection conn=getConn(); // 获得连接 String sql="update tb_message set name=?,sex=?, birthday=?, nation=?, phone=?, handset=?, qq=?, email=?, address=?, postalcode=?, sort=?, memo=? where ID=?"; PreparedStatement ps=conn.prepareStatement(sql); // 创建PreparedStatement对象,并传递SQL语句 ps.setString(1, m.getName()); // 通过实例类的实例为第1个参数赋值 ps.setString(2, m.getSex()); // 通过实例类的实例为第2个参数赋值 // 创建日期格式化对象,并指定格式 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); Date date = format.parse(m.getBirthday()); // 将实体类的出生日期转换为Date类型 ps.setTimestamp(3, new Timestamp(date.getTime())); // 通过实例类的实例为第3个参数赋值 ps.setString(4, m.getNation()); // 通过实例类的实例为第4个参数赋值 ps.setString(5, m.getZuoji()); // 通过实例类的实例为第5个参数赋值 ps.setString(6, m.getShouji()); // 通过实例类的实例为第6个参数赋值 ps.setString(7, m.getQq()); // 通过实例类的实例为第7个参数赋值 ps.setString(8, m.getEmail()); // 通过实例类的实例为第8个参数赋值 ps.setString(9, m.getAddress()); // 通过实例类的实例为第9个参数赋值 ps.setString(10, m.getYoubian()); // 通过实例类的实例为第10个参数赋值 ps.setString(11,m.getType()); // 通过实例类的实例为第11个参数赋值 ps.setString(12,m.getMemo()); // 通过实例类的实例为第12个参数赋值 int id=Integer.parseInt(m.getId()); // 获得编号 ps.setInt(13, id); // 通过实例类的实例为第13个参数赋值 int flag=ps.executeUpdate(); // 执行SQL语句,获得更新记录数 if (flag>0){ JOptionPane.showMessageDialog(null, "修改成功!"); }else{ JOptionPane.showMessageDialog(null, "修改失败!"); } ps.close(); conn.close(); // 关闭连接 }catch(Exception ex){ JOptionPane.showMessageDialog(null, "修改失败!\n"+ex.getMessage()); ex.printStackTrace(); } } /** * 根据编号删除记录的方法 * @param id 编号 */ public static void delete(int id){ try{ Connection conn=getConn(); // 获得连接 // 创建PreparedStatement对象,并传递SQL语句 PreparedStatement ps=conn.prepareStatement("delete from tb_message where ID=?"); ps.setInt(1, id); // 为参数赋值 int flag=ps.executeUpdate(); // 执行SQL语句,获得更新记录数 if (flag>0){ JOptionPane.showMessageDialog(null, "删除成功!"); }else{ JOptionPane.showMessageDialog(null, "删除失败!"); } ps.close(); conn.close(); // 关闭连接 }catch(Exception ex){ JOptionPane.showMessageDialog(null, "删除失败!\n"+ex.getMessage()); } } /** * 查询满足条件的记录 * @param fieldName 字段名 * @param value 字段值 * @param mtype 分类 * @return 结果集的Vector对象 */ public static Vector query(String fieldName,String value,String mtype){ try{ Vector vector=new Vector(); // 创建存放数据的向量 Connection conn=getConn(); // 获得数据连接 // 创建PreparedStatement对象,并传递SQL语句 PreparedStatement ps=conn.prepareStatement("select * from tb_message where "+fieldName+" ='"+value+"' and sort='"+mtype+"'"); ResultSet rs=ps.executeQuery(); // 执行SQL语句,获得查询结果集 while (rs.next() && rs.getRow()>0){ // 遍历结果集 Vector row=new Vector(); // 创建存放记录的向量 // 为记录向量赋值 for (int col=1;col<=rs.getMetaData().getColumnCount();col++){ if (col==1){ row.add(String.valueOf(rs.getInt(col))); }else if (col==4){ String dateString=new Timestamp(new Date().getTime()).toString().substring(0,10); row.add(dateString); }else{ row.add(rs.getString(col)); } } vector.add(row); // 将记录向量添加到数据向量 } return vector; // 返回数据向量 }catch(Exception ex){ JOptionPane.showMessageDialog(null, "查询失败!\n"+ex.getMessage()); return null; } } /** * 按编号查询记录 * @param id 编号 * @return 结果集的Vector对象 */ public static Vector query(int id){ try{ Vector vector=new Vector(); // 创建存放数据的向量 Connection conn=getConn(); // 获得数据连接 // 创建PreparedStatement对象,并传递SQL语句 PreparedStatement ps=conn.prepareStatement("select * from tb_message where ID=?"); ps.setInt(1, id); // 为参数赋值 ResultSet rs=ps.executeQuery(); // 执行SQL语句,获得查询结果集 if (rs.next() && rs.getRow()>0){ // 遍历结果集 Vector row=new Vector(); // 创建存放记录的向量 // 为记录向量赋值 for (int col=1;col<=rs.getMetaData().getColumnCount();col++){ if (col==1){ row.add(String.valueOf(rs.getInt(col))); }else if (col==4){ String dateString=new Timestamp(new Date().getTime()).toString().substring(0,10); row.add(dateString); }else{ row.add(rs.getString(col)); } } vector.add(row); // 将记录向量添加到数据向量 } return vector; // 返回数据向量 }catch(Exception ex){ JOptionPane.showMessageDialog(null, "查询失败!\n"+ex.getMessage()); return null; } } /** * 按分类查询记录 * @param mtype 分类 * @return 结果集的Vector对象 */ public static Vector query(String mtype){ try{ Vector vector=new Vector(); // 创建存放数据的向量 Connection conn=getConn(); // 获得数据连接 // 创建PreparedStatement对象,并传递SQL语句 PreparedStatement ps=conn.prepareStatement("select * from tb_message where sort=?"); ps.setString(1, mtype); // 为参数赋值 ResultSet rs=ps.executeQuery(); // 执行SQL语句,获得查询结果集 while (rs.next() && rs.getRow()>0){ // 遍历结果集 Vector row=new Vector(); // 创建存放记录的向量 // 为记录向量赋值 for (int col=1;col<=rs.getMetaData().getColumnCount();col++){ if (col==1){ row.add(String.valueOf(rs.getInt(col))); }else if (col==4){ String dateString=new Timestamp(new Date().getTime()).toString().substring(0,10); row.add(dateString); }else{ row.add(rs.getString(col)); } } vector.add(row); // 将记录向量添加到数据向量 } rs.close(); ps.close(); conn.close(); // 关闭连接 return vector; // 返回数据向量 }catch(Exception ex){ JOptionPane.showMessageDialog(null, "查询失败!\n"+ex.getMessage()); return null; } } } A.4.4 公共背景面板类BackgroundPanel 在包资源管理器中的src文件夹上单击鼠标右键,在弹出的菜单中选择“新建”/“包”菜单项,打开“新建 Java 包”对话框,在“名称”右侧的文本框中输入包名“com.zzk.background”,该包用于存放背景面板类BackgroundPanel,单击“完成”按钮,完成包的创建,然后在包名“com.zzk.background”上单击鼠标右键,在弹出的菜单中选择“新建”/“类”菜单项,打开“新建 Java 类”对话框,在“名称”右侧的文本框中输入类名“BackgroundPanel”,在“超类”右侧的文本框中输入“javax.swing.JPanel”,单击“完成”按钮,完成背景面板类BackgroundPanel的创建。BackgroundPanel类的代码如下: package com.zzk.background; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import javax.swing.JPanel; public class BackgroundPanel extends JPanel { private Image image; // 定义图像对象 public BackgroundPanel(Image image) { super(); // 调用超类的构造方法 this.image=image; // 为图像对象赋值 } /* * 重写paintComponent方法 */ protected void paintComponent(Graphics g) { super.paintComponent(g); // 调用父类的方法 Graphics2D g2 = (Graphics2D) g; // 创建Graphics2D对象 if (image != null) { int width = getWidth(); // 获得面板的宽度 int height = getHeight(); // 获得面板的高度 // 绘制图像 g2.drawImage(image, 0, 0, width, height, this); } } } A.4.5 公共分类信息类SaveTypeState 在包资源管理器中的src文件夹上单击鼠标右键,在弹出的菜单中选择“新建”/“包”菜单项,打开“新建 Java 包”对话框,在“名称”右侧的文本框中输入包名“com.zzk.typestate”,该包用于存放分类信息的类SaveTypeState,单击“完成”按钮,完成包的创建,然后在包名“com.zzk.typestate”上单击鼠标右键,在弹出的菜单中选择“新建”/“类”菜单项,打开“新建 Java 类”对话框,在“名称”右侧的文本框中输入类名“SaveTypeState”,单击“完成”按钮,完成分类信息类SaveTypeState的创建。SaveTypeState类的代码如下: package com.zzk.typestate; public class SaveTypeState { private static String typeState; // 保存分类信息 private static String titleState; // 保存窗体标题信息 private static String lableState; // 保存窗体上标签的标题信息 public static String getTypeState() { // typeState的get方法 return typeState; } public static void setTypeState(String typeState) { // typeState的set方法 SaveTypeState.typeState = typeState; } public static String getTitleState() { // titleState的get方法 return titleState; } public static void setTitleState(String titleState) { // titleState的set方法 SaveTypeState.titleState = titleState; } public static String getLableState() { // lableState的get方法 return lableState; } public static void setLableState(String lableState) { // lableState的set方法 SaveTypeState.lableState = lableState; } } A.4.6 系统登录模块 (1)在包资源管理器中的src文件夹上单击鼠标右键,在弹出的菜单中选择“新建”/“包”菜单项,打开“新建 Java 包”对话框,在“名称”右侧的文本框中输入包名“com.zzk.frame”,该包用于存放所有的窗体类,单击“完成”按钮,完成包的创建。 (2)在包资源管理器中的src文件夹上单击鼠标右键,在弹出的菜单中选择“新建”/“文件来”菜单项,打开“新建文件夹”对话框,在“文件夹名”右侧的文本框中输入文件夹名“image”,该文件夹用于存放所有为窗体类设置的背景图片,单击“完成”按钮,完成文件夹的创建。 (3)将本系统所需要的login.jpg图片文件和main.jpg图片文件拷贝到image文件夹中,分别用于为系统登录窗体和主窗体设置背景。 (4)在包名“com.zzk.frame”上单击鼠标右键,在弹出的菜单中选择“新建”/“类”菜单项,打开“新建 Java 类”对话框,在“名称”右侧的文本框中输入类名“LoginFrame”,然后在“超类”右侧的文本框中输入“javax.swing.JFrame”,单击“完成”按钮,完成系统登录窗体类LoginFrame的创建。 (5)在LoginFrame类的构造方法中输入如下代码,为窗体指定背景。 super(); setTitle("系统登录"); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setBounds(260,140,350,230); URL url = LoginFrame.class.getResource("/image/login.jpg"); // 获得图片的URL Image image=new ImageIcon(url).getImage(); // 创建图像对象 BackgroundPanel gbPanel=new BackgroundPanel(image); // 创建背景面板 gbPanel.setLayout(null); // 设置背景面板为绝对布局 getContentPane().add(gbPanel); // 将背景面板添加到窗体容器中部 (6)进入系统登录窗体LoginFrame类的设计器窗口,在背景在板上添加标签、文本框、密码框和按钮组件,结果如图A.18所示。 图A.18 系统登录窗体设计结果 (7)双击“登录”按钮,为“登录”按钮的动作事件编写如下代码,实现判断用户名和密码是否正确的功能,如果用户名正确,就可进入系统主窗体,否则不能进入系统主窗体。 String user=tf_user.getText(); // 获得输入的用户名 String password=new String(pw_password.getPassword()); // 获得输入的密码 if (user.equals("") || password.equals("")){ // 如果用户名或密码为空 JOptionPane.showMessageDialog(null, "用户名和密码不能为空。"); }else{ boolean ok=DAO.okUser(user, password); // 调用DAO的方法判断用户名和密码 if (ok){ // 用户名和密码正确 new MainFrame().setVisible(true); // 创建并显示主窗体 LoginFrame.this.dispose(); // 销毁系统登录窗体 } } 说明:MainFrame类是通讯录管理系统的主窗体类,稍后将对该类进行介绍。 (8)LoginFrame类是通讯录管理系统的主类,在main()主方法中编写一行代码,用于启动系统登录窗体,主方法及其中的代码如下: public static void main(String[] args) { // 主方法 new LoginFrame().setVisible(true); // 创建系统登录窗体类的实例,并显示登录窗体 } (9)双击“退出”按钮,为“退出”按钮的动作事件编写如下代码,实现退出应用程序的操作。 System.exit(0); // 退出应用程序 A.4.7 主窗体模块 (1)在包名“com.zzk.frame”上单击鼠标右键,在弹出的菜单中选择“新建”/“类”菜单项,打开“新建 Java 类”对话框,在“名称”右侧的文本框中输入类名“MainFrame”,然后在“超类”右侧的文本框中输入“javax.swing.JFrame”,单击“完成”按钮,完成主窗体类MainFrame的创建。 (2)在MainFrame类的构造方法中输入如下代码,为窗体指定背景。 super(); setTitle("通讯录管理系统"); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setBounds(100,60,800,600); URL url = LoginFrame.class.getResource("/image/main.jpg"); // 获得图片的URL Image image=new ImageIcon(url).getImage(); // 创建图像对象 BackgroundPanel gbPanel=new BackgroundPanel(image); // 创建背景面板 getContentPane().add(gbPanel); // 将背景面板添加到窗体容器中部 (3)进入主窗体MainFrame类的设计器窗口,在窗体上添加菜单栏、菜单、菜单项、工具栏和工具按钮,结果如图A.19所示。 图A.19 通讯录管理系统主窗体设计结果 说明:菜单项遮挡住的工具按钮是“查询家人信息”按钮,再有就是这里只列出了家人菜单中的菜单项,朋友、同学、同事和其他菜单里的菜单项与家人菜单里的菜单项相同,这里就不一一显示了,并且每个菜单的“查询信息”菜单项都与工具栏上对应的工具按钮实现相同的功能。 (4)设置工具按钮的图标,选择要设置图标的工具按钮,通过属性窗体设置工具按钮的图标和回滚图标,如图A.20所示。 图A.20 设置工具按钮图标 (4)双击“家人”菜单中“添加信息”菜单项,为“添加信息”菜单项的动作事件编写如下代码,实现打开添加家人信息窗体模块的操作。 SaveTypeState.setTypeState("家人"); // 设置分类信息为“家人” SaveTypeState.setTitleState("添加家人信息模块"); // 主置添加信息窗体标题为“添加家人信息模块” SaveTypeState.setLableState("添加家人信息界面"); // 设置添加信息窗体上标签的标题信息为“添加家人信息界面” AddMessageFrame frame = new AddMessageFrame(); // 创建添加信息窗体对象 frame.setVisible(true); // 显示添加信息窗体 (5)双击“家人”菜单中“修改信息”菜单项,为“修改信息”菜单项的动作事件编写如下代码,实现打开修改家人信息窗体模块的操作。 SaveTypeState.setTypeState("家人"); // 设置分类信息为“家人” SaveTypeState.setTitleState("修改家人信息模块"); // 主置修改信息窗体标题为“修改家人信息模块” SaveTypeState.setLableState("修改家人信息界面"); // 设置修改信息窗体上标签的标题信息为“修改家人信息界面” UpdateMessageFrame dialog = new UpdateMessageFrame(); // 创建修改信息窗体对象 dialog.setVisible(true); // 显示修改信息窗体 (6)双击“家人”菜单中“删除信息”菜单项,为“删除信息”菜单项的动作事件编写如下代码,实现打开删除家人信息窗体模块的操作。 SaveTypeState.setTypeState("家人"); // 设置分类信息为“家人” SaveTypeState.setTitleState("删除家人信息模块"); // 主置删除信息窗体标题为“删除家人信息模块” SaveTypeState.setLableState("删除家人信息界面"); // 设置删除信息窗体上标签的标题信息为“删除家人信息界面” DeleteMessageFrame dialog = new DeleteMessageFrame(); // 创建删除信息窗体对象 dialog.setVisible(true); // 显示删除信息窗体 (7)双击“家人”菜单中“查询信息”菜单项,为“查询信息”菜单项的动作事件编写如下代码,实现打开查询家人信息窗体模块的操作。 SaveTypeState.setTypeState("家人"); // 设置分类信息为“家人” SaveTypeState.setTitleState("查询家人信息模块"); // 主置查询信息窗体标题为“查询家人信息模块” SaveTypeState.setLableState("查询家人信息界面"); // 设置查询信息窗体上标签的标题信息为“查询家人信息界面” QueryMessageFrame dialog = new QueryMessageFrame(); // 创建查询信息窗体对象 dialog.setVisible(true); // 显示查询信息窗体 说明:家人菜单中的4个菜单项事件编写完之后,由于朋友、同学、同事和其他菜单里的菜单项事件与家人菜单里的菜单项事件相同,只需要将第4~7步中的添加到对应的菜单项事件,并把代码中的“家人”分别改为对应的“朋友”、“同学”、“同事”和“其他”即可。 (8)双击工具栏上的“查询家人信息”按钮,为“查询家人信息”按钮的动作事件编写如下代码,实现打开查询家人信息窗体模块的操作。 SaveTypeState.setTypeState("家人"); // 设置分类信息为“家人” SaveTypeState.setTitleState("查询家人信息模块"); // 主置查询信息窗体标题为“查询家人信息模块” SaveTypeState.setLableState("查询家人信息界面"); // 设置查询信息窗体上标签的标题信息为“查询家人信息界面” QueryMessageFrame dialog = new QueryMessageFrame(); // 创建查询信息窗体对象 dialog.setVisible(true); // 显示查询信息窗体 说明:上面代码涉及到的AddMessageFrame、UpdateMessageFrame、DeleteMessageFrame和QueryMessageFrame这4个对话框窗体类分别用来添加联系人信息、修改联系人信息、删除联系人信息和查询联系人信息,稍后将对这4个类进行介绍。 A.4.8 添加信息模块 添加信息模块可以用于添加联系人信息,该模块根据用户所选择分类菜单中的“添加信息”菜单项,添加该分类的联系人信息,具体添加的是家人、朋友、同学、同事还是其他主要取决于用户选择了哪个分类菜单,就添加该分类的联系人信息。 (1)在包名“com.zzk.frame”上单击鼠标右键,在弹出的菜单中选择“新建”/“类”菜单项,打开“新建 Java 类”对话框,在“名称”右侧的文本框中输入类名“AddMessageFrame”,然后在“超类”右侧的文本框中输入“javax.swing.JDialog”,单击“完成”按钮,完成添加信息对话框窗体类AddMessageFrame的创建。 (2)进入添加信息窗体AddMessageFrame类的设计器窗口,在窗体上添加标签、文本框、单选按钮、文本域和按钮,结果如图A.21所示。 图A.21 添加信息窗体设计结果 说明:图A.21中处于选择状态的组件就是窗体最上方显示界面信息的标签。 (3)在AddMessageFrame类的构造方法中输入如下代码,设置对话框窗体、窗体最上方显示界面信息的标签和“分类”标签右侧文本框的属性。 super(); // 调用超类的构造方法 setTitle(SaveTypeState.getTitleState()); // 设置窗体的标题,从SaveTypeState类获得 getContentPane().setLayout(null); // 设置窗体容器为绝对布局 setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); // 设置窗体的默认关闭方式 setBounds(100, 100, 518, 450); // 设置窗体的显示位置和大小 this.setModal(true); // 设置对话框窗体为模式窗体 final JLabel lb_add_title = new JLabel(); // 创建标签 lb_add_title.setHorizontalAlignment(SwingConstants.CENTER); // 设置标签上的文字在标签上居中显示 lb_add_title.setForeground(new Color(0, 0, 255)); // 设置标签上显示的文字颜色 lb_add_title.setFont(new Font("", Font.BOLD, 42)); // 设置标签上显示文字的字体 lb_add_title.setText(SaveTypeState.getLableState()); // 设置标签上显示的文字,从SaveTypeState类获得 lb_add_title.setBounds(34, 10, 422, 66); // 设置标签的显示位置和大小 getContentPane().add(lb_add_title); // 将标签添加到窗体容器中 tf_type = new JTextField(); // 创建分类文本框 tf_type.setText(SaveTypeState.getTypeState()); // 设置分类文本框上显示的文字,从SaveTypeState类获得 tf_type.setBounds(345, 257, 131, 22); // 设置文本框的显示位置和大小 getContentPane().add(tf_type); // 将文本框添加到窗体容器中 (4)双击“保存”按钮,为“保存”按钮的动作事件编写如下代码,实现保存所输入的联系人信息的操作。 String name=tf_name.getText(); // 获得输入的姓名 String sex=null; // 定义存放性别的变量 if (rb_nan.isSelected()){ // 如果单选按钮男被选中 sex=rb_nan.getText(); // sex为男 }else{ // 否则如果单选按钮女被选中 sex=rb_nv.getText(); // sex为女 } String date=tf_date.getText(); // 获得输入的出生日期 String minzu=tf_minzu.getText(); // 获得输入的民族 String jiadian=tf_jiadian.getText(); // 获得输入的家庭电话 String shouji=tf_shouji.getText(); // 获得输入的手机号码 String qq=tf_qq.getText(); // 获得输入的QQ号吗 String email=tf_email.getText(); // 获得输入的Email String address=tf_address.getText(); // 获得输入的家庭住址 String youbian=tf_youbian.getText(); // 获得输入的邮编 String mtype=tf_type.getText(); // 获得输入的分类 String memo=ta_memo.getText(); // 获得输入的备注 Message ms=new Message(); // 创建Message的实体对象 // 将上面代码获得的输入信息为实体类的属性赋值 ms.setName(name); ms.setSex(sex); ms.setBirthday(date); ms.setNation(minzu); ms.setZuoji(jiadian); ms.setShouji(shouji); ms.setQq(qq); ms.setEmail(email); ms.setAddress(address); ms.setYoubian(youbian); ms.setType(mtype); ms.setMemo(memo); DAO.insert(ms); // 调用公共类DAO的方法保存实体类的属性值 A.4.9 修改信息模块 修改信息模块可以用于修改联系人信息,该模块根据用户从表格中所选择的数据行进行修改,当用户从表格中选择了数据行,就会在上方的文本框等编辑组件中输入要修改的数据,输入完要修改的数据后,单击“修改”按钮完成所选择数据行的修改,具体修改的是家人、朋友、同学、同事还是其他主要取决于用户选择了哪个分类菜单,就修改该分类的联系人信息。 (1)在包名“com.zzk.frame”上单击鼠标右键,在弹出的菜单中选择“新建”/“类”菜单项,打开“新建 Java 类”对话框,在“名称”右侧的文本框中输入类名“UpdateMessageFrame”,然后在“超类”右侧的文本框中输入“javax.swing.JDialog”,单击“完成”按钮,完成修改信息对话框窗体类UpdateMessageFrame的创建。 (2)进入修改信息窗体UpdateMessageFrame类的设计器窗口,在窗体上添加标签、文本框、单选按钮、文本域、按钮、滚动面板和表格,结果如图A.22所示。 图A.22 修改信息窗体设计结果 说明:图A.22中处于选择状态的组件就是窗体最上方显示界面信息的标签。 (3)在UpdateMessageFrame类中编写方法showDataToComponent()方法,用于根据选择表格中的行在组件中显示相应的内容,代码如下: public void showDataToComponent(int row){ // 获得表格指定行索引、列索引为0处单元格的值,并转换为整数 int id=Integer.valueOf(table.getValueAt(row, 0).toString()); Vector vector=DAO.query(id); // 获得数据向量 Vector dataV=(Vector)vector.get(0); // 获得行值向量 // 将行值向量中的数据赋值给窗体上相应的组件 tf_name.setText(dataV.get(1).toString()); // 根据选择行的性别设置选中哪个单选按钮 if (dataV.get(2).toString().equals("男")){ rb_nan.setSelected(true); // 选中男 }else{ rb_nv.setSelected(true); // 选中女 } // 将表格中选择行的内容赋值给相应的组件 tf_date.setText(dataV.get(3).toString()); tf_minzu.setText(dataV.get(4).toString()); tf_jiadian.setText(dataV.get(5).toString()); tf_shouji.setText(dataV.get(6).toString()); tf_qq.setText(dataV.get(7).toString()); tf_email.setText(dataV.get(8).toString()); tf_address.setText(dataV.get(9).toString()); tf_youbian.setText(dataV.get(10).toString()); tf_type.setText(dataV.get(11).toString()); ta_memo.setText(dataV.get(12).toString()); } (4)在UpdateMessageFrame类的构造方法中输入如下代码,设置对话框窗体、窗体最上方显示界面信息的标签和“分类”标签右侧文本框的属性。 super(); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); // 设置窗体关闭方式 setTitle(SaveTypeState.getTitleState()); // 设置对话框窗体的标题 setModal(true); // 设置对话框窗体为模式对话框 getContentPane().setLayout(null); // 设置对话框窗体容器为绝对布局 setBounds(100, 100, 687, 594); // 设置对话框窗体的显示位置和大小 final JLabel lb_update_title = new JLabel(); // 创建标签 lb_update_title.setHorizontalAlignment(SwingConstants.CENTER); // 设置标签上的文字在标签上居中显示 lb_update_title.setForeground(new Color(0, 0, 255)); // 设置标签上显示的文字颜色 lb_update_title.setFont(new Font("Dialog", Font.BOLD, 42)); // 设置标签上显示文字的字体 lb_update_title.setText(SaveTypeState.getLableState()); // 设置标签上显示的文字,从SaveTypeState类获得 lb_update_title.setBounds(118, 3, 422, 66); // 设置标签的显示位置和大小 getContentPane().add(lb_update_title); // 将标签添加到窗体容器中 tf_type = new JTextField(); // 创建分类文本框 tf_type.setText(SaveTypeState.getTypeState()); // 设置分类文本框上显示的文字,从SaveTypeState类获得 tf_type.setBounds(338, 243, 131, 22); // 设置文本框的显示位置和大小 getContentPane().add(tf_type); // 将文本框添加到窗体容器中 scrollPane_1.setBounds(24, 365, 627, 176); // 设置滚动面板的显示位置和大小 getContentPane().add(scrollPane_1); // 将滚动面板添加到窗体上 // 创建表格的列名向量 Vector vectorColumns=new Vector(); String[] columns={"编号","姓名","性别","出生日期","民族","家庭电话","手机号码","QQ号码","电子信箱","家庭住址","邮政编码","类型","备注"}; // 为表格的列名向量赋值 for (int i=0;i=0){ // 调用方法获得表格中选择行的值,并添加到相应的组件中 showDataToComponent(row); selectRow=row; // 将表格中所选择数据行的行索引赋值给成员变量 } } }); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); // 关闭表格的自动调整功能 scrollPane_1.setViewportView(table); (5)在窗体的打开时,为了能在窗体上的组件中显示内容,可以在窗体打开事件中编写如下代码: if (table.getRowCount()>0){ showDataToComponent(0); // 调用方法获得表格中第一行的值,并添加到相应的组件中 selectRow=0; // 为成员变量赋值 } (6)双击“修改”按钮,为“修改”按钮的动作事件编写如下代码,实现保存所输入的联系人修改信息的操作。 String name=tf_name.getText(); // 获得姓名文本框中的内容 String sex=null; // 定义性别变量 if (rb_nan.isSelected()){ // 如果选择了男 sex=rb_nan.getText(); // 设置性别为男 }else{ // 如果选择了女 sex=rb_nv.getText(); // 设置性别为女 } // 获得其他组件中的内容并赋值给变量 String date=tf_date.getText(); String minzu=tf_minzu.getText(); String jiadian=tf_jiadian.getText(); String shouji=tf_shouji.getText(); String qq=tf_qq.getText(); String email=tf_email.getText(); String address=tf_address.getText(); String youbian=tf_youbian.getText(); String mtype=tf_type.getText(); String memo=ta_memo.getText(); Message ms=new Message(); // 创建实体类Message的对象 // 为实体类的属性赋值 ms.setId(table.getValueAt(selectRow, 0).toString()); ms.setName(name); ms.setSex(sex); ms.setBirthday(date); ms.setNation(minzu); ms.setZuoji(jiadian); ms.setShouji(shouji); ms.setQq(qq); ms.setEmail(email); ms.setAddress(address); ms.setYoubian(youbian); ms.setType(mtype); ms.setMemo(memo); DAO.update(ms); // 调用公共类DAO的方法保存修改信息 // 创建表格的列名向量 Vector vectorColumns=new Vector(); String[] columns={"编号","姓名","性别","出生日期","民族","家庭电话","手机号码","QQ号码","电子信箱","家庭住址","邮政编码","类型","备注"}; // 为表格的列名向量赋值 for (int i=0;i vectorColumns=new Vector(); String[] columns={"编号","姓名","性别","出生日期","民族","家庭电话","手机号码","QQ号码","电子信箱","家庭住址","邮政编码","类型","备注"}; // 为表格的列名向量赋值 for (int i=0;i=0){ selectRow=row; // 将选择行的行号赋值给成员变量 } (5)双击“删除”按钮,为“删除”按钮的动作事件编写如下代码,实现删除表格中选择行的数据。 if (selectRow>=0){ // 如果从表格选择了数据行 // 获的选择行第1列单元格中的值,并转换为整数 int id=Integer.parseInt(table.getValueAt(selectRow, 0).toString()); DAO.delete(id); // 调用DAO类的方法删除数据 selectRow=-1; // 为成员变量赋值为-1 }else{ JOptionPane.showMessageDialog(null, "请从表中选择要删除的行。"); } // 创建表格的列名向量 Vector vectorColumns=new Vector(); String[] columns={"编号","姓名","性别","出生日期","民族","家庭电话","手机号码","QQ号码","电子信箱","家庭住址","邮政编码","类型","备注"}; // 为表格的列名向量赋值 for (int i=0;i vectorColumns=new Vector(); String[] columns={"编号","姓名","性别","出生日期","民族","家庭电话","手机号码","QQ号码","电子信箱","家庭住址","邮政编码","类型","备注"}; // 为表格的列名向量赋值 for (int i=0;i vectorColumns=new Vector(); String[] columns={"编号","姓名","性别","出生日期","民族","家庭电话","手机号码","QQ号码","电子信箱","家庭住址","邮政编码","类型","备注"}; // 为表格的列名向量赋值 for (int i=0;i vectorColumns=new Vector(); String[] columns={"编号","姓名","性别","出生日期","民族","家庭电话","手机号码","QQ号码","电子信箱","家庭住址","邮政编码","类型","备注"}; // 为表格的列名向量赋值 for (int i=0;i

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 20 金币 [ 分享文档获得金币 ]
10 人已下载

下载文档

相关文档