基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVA+SQL电子通讯录带系统托盘
一、系统概述
本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统托盘,实现后台运行。
二、系统架构设计
1. 技术选型
- 前端:Java Swing
- 后端:Java SE
- 数据库:SQLite 3.36+
- 数据访问:JDBC
- 开发工具:Eclipse
2. 系统架构
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── addressbook
│ │ │ ├── controller (控制器层)
│ │ │ ├── model (模型层)
│ │ │ ├── view (视图层)
│ │ │ ├── dao (数据访问层)
│ │ │ └── utils (工具类)
三、核心代码实现
1. 数据库连接工具类
// DBConnectionUtil.java
public class DBConnectionUtil {private static final String DB_URL = "jdbc:sqlite:addressbook.db";public static Connection getConnection() throws SQLException {return DriverManager.getConnection(DB_URL);}public static void close(Connection conn, Statement stmt, ResultSet rs) {try {if (rs != null) rs.close();if (stmt != null) stmt.close();if (conn != null) conn.close();} catch (SQLException e) {e.printStackTrace();}}// 初始化数据库public static void initDatabase() {try (Connection conn = getConnection();Statement stmt = conn.createStatement()) {// 创建联系人表String createTableSQL = "CREATE TABLE IF NOT EXISTS contacts (" +"id INTEGER PRIMARY KEY AUTOINCREMENT," +"name TEXT NOT NULL," +"phone TEXT," +"email TEXT," +"address TEXT," +"groupId INTEGER," +"photo BLOB," +"FOREIGN KEY (groupId) REFERENCES groups(id)" +")";stmt.execute(createTableSQL);// 创建分组表createTableSQL = "CREATE TABLE IF NOT EXISTS groups (" +"id INTEGER PRIMARY KEY AUTOINCREMENT," +"name TEXT NOT NULL UNIQUE" +")";stmt.execute(createTableSQL);// 插入默认分组String checkDefaultGroupSQL = "SELECT COUNT(*) FROM groups WHERE name = '默认分组'";ResultSet rs = stmt.executeQuery(checkDefaultGroupSQL);if (rs.next() && rs.getInt(1) == 0) {String insertDefaultGroupSQL = "INSERT INTO groups (name) VALUES ('默认分组')";stmt.execute(insertDefaultGroupSQL);}} catch (SQLException e) {e.printStackTrace();}}
}
2. 联系人实体类
// Contact.java
public class Contact {private int id;private String name;private String phone;private String email;private String address;private int groupId;private byte[] photo;// getters and setters
}
3. 联系人数据访问类
// ContactDAO.java
public class ContactDAO {public List<Contact> getAllContacts() {List<Contact> contacts = new ArrayList<>();String sql = "SELECT * FROM contacts ORDER BY name";try (Connection conn = DBConnectionUtil.getConnection();Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(sql)) {while (rs.next()) {Contact contact = new Contact();contact.setId(rs.getInt("id"));contact.setName(rs.getString("name"));contact.setPhone(rs.getString("phone"));contact.setEmail(rs.getString("email"));contact.setAddress(rs.getString("address"));contact.setGroupId(rs.getInt("groupId"));contact.setPhoto(rs.getBytes("photo"));contacts.add(contact);}} catch (SQLException e) {e.printStackTrace();}return contacts;}public boolean addContact(Contact contact) {String sql = "INSERT INTO contacts (name, phone, email, address, groupId, photo) " +"VALUES (?, ?, ?, ?, ?, ?)";try (Connection conn = DBConnectionUtil.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setString(1, contact.getName());pstmt.setString(2, contact.getPhone());pstmt.setString(3, contact.getEmail());pstmt.setString(4, contact.getAddress());pstmt.setInt(5, contact.getGroupId());pstmt.setBytes(6, contact.getPhoto());int rows = pstmt.executeUpdate();return rows > 0;} catch (SQLException e) {e.printStackTrace();return false;}}public boolean updateContact(Contact contact) {String sql = "UPDATE contacts SET name = ?, phone = ?, email = ?, " +"address = ?, groupId = ?, photo = ? WHERE id = ?";try (Connection conn = DBConnectionUtil.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setString(1, contact.getName());pstmt.setString(2, contact.getPhone());pstmt.setString(3, contact.getEmail());pstmt.setString(4, contact.getAddress());pstmt.setInt(5, contact.getGroupId());pstmt.setBytes(6, contact.getPhoto());pstmt.setInt(7, contact.getId());int rows = pstmt.executeUpdate();return rows > 0;} catch (SQLException e) {e.printStackTrace();return false;}}public boolean deleteContact(int id) {String sql = "DELETE FROM contacts WHERE id = ?";try (Connection conn = DBConnectionUtil.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setInt(1, id);int rows = pstmt.executeUpdate();return rows > 0;} catch (SQLException e) {e.printStackTrace();return false;}}
}
4. 系统托盘实现
// TrayManager.java
public class TrayManager {private static final String ICON_PATH = "resources/addressbook.png";private SystemTray tray;private TrayIcon trayIcon;private JFrame mainFrame;public TrayManager(JFrame mainFrame) {this.mainFrame = mainFrame;initTray();}private void initTray() {if (!SystemTray.isSupported()) {System.out.println("系统不支持托盘功能");return;}tray = SystemTray.getSystemTray();Image image = Toolkit.getDefaultToolkit().getImage(ICON_PATH);// 创建弹出菜单PopupMenu popupMenu = new PopupMenu();MenuItem openItem = new MenuItem("打开");openItem.addActionListener(e -> showFrame());MenuItem exitItem = new MenuItem("退出");exitItem.addActionListener(e -> {if (JOptionPane.showConfirmDialog(mainFrame, "确定要退出程序吗?", "确认退出", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {System.exit(0);}});popupMenu.add(openItem);popupMenu.addSeparator();popupMenu.add(exitItem);// 创建托盘图标trayIcon = new TrayIcon(image, "电子通讯录", popupMenu);trayIcon.setImageAutoSize(true);// 添加双击事件trayIcon.addActionListener(e -> showFrame());try {tray.add(trayIcon);} catch (AWTException e) {e.printStackTrace();}}public void hideFrame() {mainFrame.setVisible(false);trayIcon.displayMessage("电子通讯录", "程序已最小化到托盘", TrayIcon.MessageType.INFO);}public void showFrame() {mainFrame.setVisible(true);mainFrame.setExtendedState(JFrame.NORMAL);mainFrame.toFront();}public void showMessage(String message) {trayIcon.displayMessage("电子通讯录", message, TrayIcon.MessageType.INFO);}public void removeTrayIcon() {tray.remove(trayIcon);}
}
5. 主界面
// MainFrame.java
public class MainFrame extends JFrame {private JTable contactTable;private ContactTableModel tableModel;private ContactDAO contactDAO = new ContactDAO();private TrayManager trayManager;public MainFrame() {setTitle("电子通讯录");setSize(800, 600);setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);setLocationRelativeTo(null);// 初始化系统托盘trayManager = new TrayManager(this);// 添加窗口关闭事件addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {trayManager.hideFrame();}});initComponents();loadContacts();}private void initComponents() {// 工具栏JToolBar toolBar = new JToolBar();JButton addButton = new JButton("添加");JButton editButton = new JButton("编辑");JButton deleteButton = new JButton("删除");JButton refreshButton = new JButton("刷新");addButton.addActionListener(e -> openAddContactDialog());editButton.addActionListener(e -> openEditContactDialog());deleteButton.addActionListener(e -> deleteSelectedContact());refreshButton.addActionListener(e -> loadContacts());toolBar.add(addButton);toolBar.add(editButton);toolBar.add(deleteButton);toolBar.addSeparator();toolBar.add(refreshButton);// 表格tableModel = new ContactTableModel();contactTable = new JTable(tableModel);JScrollPane scrollPane = new JScrollPane(contactTable);// 布局setLayout(new BorderLayout());add(toolBar, BorderLayout.NORTH);add(scrollPane, BorderLayout.CENTER);}private void loadContacts() {List<Contact> contacts = contactDAO.getAllContacts();tableModel.setContacts(contacts);}// 其他方法省略...
}
四、系统界面设计
1. 联系人表格模型
// ContactTableModel.java
public class ContactTableModel extends AbstractTableModel {private List<Contact> contacts = new ArrayList<>();private String[] columnNames = {"ID", "姓名", "电话", "邮箱", "地址", "分组"};@Overridepublic int getRowCount() {return contacts.size();}@Overridepublic int getColumnCount() {return columnNames.length;}@Overridepublic Object getValueAt(int rowIndex, int columnIndex) {Contact contact = contacts.get(rowIndex);switch (columnIndex) {case 0: return contact.getId();case 1: return contact.getName();case 2: return contact.getPhone();case 3: return contact.getEmail();case 4: return contact.getAddress();case 5: return getGroupName(contact.getGroupId());default: return null;}}@Overridepublic String getColumnName(int column) {return columnNames[column];}// 其他方法省略...
}
五、系统部署与测试
1. 环境要求
- JDK 1.8+
- SQLite JDBC驱动:sqlite-jdbc-3.36.0.3.jar
2. 部署步骤
- 确保JDK和SQLite JDBC驱动已安装
- 编译项目生成可执行JAR文件
- 创建必要的资源文件夹和图标文件
- 运行程序:java -jar addressbook.jar
3. 测试用例
// ContactDAOTest.java
public class ContactDAOTest {private ContactDAO contactDAO = new ContactDAO();@Beforepublic void setUp() {DBConnectionUtil.initDatabase();}@Testpublic void testAddContact() {Contact contact = new Contact();contact.setName("张三");contact.setPhone("13800138000");contact.setEmail("zhangsan@example.com");contact.setAddress("北京市朝阳区");contact.setGroupId(1);boolean result = contactDAO.addContact(contact);assertTrue(result);}@Testpublic void testUpdateContact() {// 先添加一个联系人Contact contact = new Contact();contact.setName("李四");contact.setPhone("13900139000");contact.setEmail("lisi@example.com");contact.setAddress("上海市浦东新区");contact.setGroupId(1);contactDAO.addContact(contact);// 获取联系人并更新List<Contact> contacts = contactDAO.getAllContacts();Contact toUpdate = contacts.get(0);toUpdate.setPhone("13912345678");boolean result = contactDAO.updateContact(toUpdate);assertTrue(result);}@Testpublic void testDeleteContact() {// 先添加一个联系人Contact contact = new Contact();contact.setName("测试删除");contact.setPhone("12345678901");contact.setEmail("test@example.com");contact.setAddress("测试地址");contact.setGroupId(1);contactDAO.addContact(contact);// 获取联系人ID并删除List<Contact> contacts = contactDAO.getAllContacts();int id = contacts.get(0).getId();boolean result = contactDAO.deleteContact(id);assertTrue(result);}
}
六、毕业设计文档框架
1. 论文框架
- 引言
- 相关技术综述
- 系统需求分析
- 系统设计
- 系统实现
- 系统测试
- 总结与展望
七、总结
本电子通讯录系统实现了基本的联系人管理功能,并创新性地加入了系统托盘功能,提升了用户体验。系统采用Java+SQLite技术栈,具有良好的可移植性和扩展性,可作为个人或小型团队的通讯录管理工具使用。