ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

图书管理系统用SWT做的JAVA图形化界面:从环境搭建到打包发布

图书管理系统用SWT做的JAVA图形化界面:从环境搭建到打包发布 简介这份资源是一套基于SWT构建的Java图书管理系统图形化界面项目面向具备Java基础、希望学习桌面端GUI开发与数据库整合的开发者尤其适合课程设计或实训参考。压缩包共259个文件约10.07MB包含45个java源码、107个class编译文件、80个ico图标、12张jpg图片、7个jar依赖库以及sql建库脚本、doc说明文档和可执行exe覆盖从源码到运行环境的完整结构。项目围绕图书信息管理、借阅归还、用户管理与统计报表等模块展开涉及SWT组件、事件驱动、布局管理、Table表格展示、对话框及JDBC数据库操作等知识点并体现面向对象与模块化编程思路。目前已有483人学习下载读者可借此理解SWT原生界面开发流程、数据库交互方式与项目打包部署方法也可作为二次开发或功能扩展的起点。1. 图书管理系统用SWT做的JAVA图形化界面为什么桌面端选型绕不开它很多同学做 Java 课程设计第一反应是拿 Swing 拖一个图书管理系统结果跑起来界面发虚、表格卡顿、在 Windows 高分屏上字体糊成一团。换成 SWT 之后同样的增删改查逻辑窗口响应速度和原生控件观感完全是两个档次。SWT 是 Standard Widget Toolkit 的缩写它不像 Swing 那样自己画一套控件而是直接调用操作系统的原生组件所以做出来的 JAVA 图形化界面跟系统自带程序长得几乎一样。这篇笔记就围绕「图书管理系统用SWT做的JAVA图形化界面」这个方向把环境搭建、界面骨架、数据层对接、打包发布整条链路讲清楚。适合正在做课程设计、想找一个能写进简历的桌面项目、或者单纯想搞明白 SWT 和 Swing 到底差在哪的 Java 学习者。下面所有步骤都是我在本地反复跑通过的参数和坑点会一并给出。2. SWT 环境搭建与第一个可运行窗口从依赖到显示2.1 为什么图书管理系统更适合用 SWT 而不是 Swing先把这个选型问题说透不然后面写代码心里没底。Swing 是纯 Java 实现的轻量级组件跨平台一致性好但代价是每个按钮、每个表格都是 JVM 自己绘制的在 Windows 上看起来总有点「不像本地程序」。SWT 走的是另一条路它通过 JNI 调用操作系统的原生控件Windows 上就是 Win32 控件Linux 上就是 GTK所以界面观感、字体渲染、输入法支持都跟系统原生程序一致。对于图书管理系统这种典型的信息管理类桌面应用界面元素无非是菜单栏、工具栏、表格、表单、对话框。这些用 SWT 的 Table、Text、Button、Combo 实现起来非常直接而且表格渲染几万条借阅记录时性能明显优于 Swing 的 JTable。另一个现实原因是很多 Java 课程设计案例源码里SWT 版本的项目结构更清晰事件监听和布局管理分离得更好适合作为学习面向对象编程 Java 的练手项目。当然 SWT 也有代价它依赖本地库不同操作系统要换对应的 jar 包打包时比纯 Java 的 Swing 麻烦一点。但这点麻烦换来的是界面质感和运行效率对课程设计答辩来说观感分是实打实的。2.2 用 Maven 引入 SWT 依赖并跑通最小窗口我一般用 Maven 管理依赖比手动下载 jar 包再配 Build Path 靠谱得多。SWT 的坐标需要指定操作系统和架构的分类器Windows 64 位用win32-x86_64。下面是最小可运行窗口的完整代码。!-- pom.xml 片段引入 SWT 依赖 -- dependencies dependency groupIdorg.eclipse.platform/groupId artifactIdorg.eclipse.swt.win32.win32.x86_64/artifactId version3.124.0/version /dependency /dependenciesimport org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class FirstWindow { public static void main(String[] args) { // Display 代表与操作系统图形系统的连接一个应用一个即可 Display display new Display(); // Shell 就是顶层窗口相当于 Swing 的 JFrame Shell shell new Shell(display); shell.setText(图书管理系统 - SWT); shell.setSize(800, 600); shell.open(); // 显示窗口 // 事件循环SWT 必须手动跑这个循环窗口才会响应 while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); // 释放系统资源 } }逻辑说明SWT 程序的核心是 Display 和 Shell 两个对象。Display 管理事件循环和系统资源Shell 是窗口容器。readAndDispatch()负责取出并分发事件没有事件时sleep()让出 CPU。这个循环是 SWT 的固定骨架后面所有界面都套这个结构。参数说明SWT.NONE是窗口样式常量如果需要带关闭按钮、可调整大小可以用SWT.SHELL_TRIM。setSize的单位是像素。依赖版本号以你本地仓库能拉到的为准不同版本 API 基本兼容。提示如果运行时报UnsatisfiedLinkError九成是依赖分类器和你的操作系统不匹配。Windows 64 位必须是win32-x86_64Linux 用gtk.linux.x86_64Mac 用cocoa.macosx.x86_64。2.3 布局管理器选哪个FillLayout、GridLayout 还是 FormLayoutSWT 的布局比 Swing 严格控件不设布局就是零尺寸什么都看不见。图书管理系统里我推荐 GridLayout 打底复杂表单用 FormLayout 微调。GridLayout 的核心是numColumns它决定一行放几个控件。每个控件通过 GridData 控制自己的跨列、填充、对齐。下面这段代码搭一个「查询条件 表格」的经典结构。import org.eclipse.swt.layout.*; import org.eclipse.swt.widgets.*; public class LayoutDemo { public static void main(String[] args) { Display display new Display(); Shell shell new Shell(display); shell.setText(布局演示); // 两列网格布局列之间留 10 像素间距 GridLayout gridLayout new GridLayout(2, false); gridLayout.marginWidth 10; gridLayout.marginHeight 10; gridLayout.horizontalSpacing 10; gridLayout.verticalSpacing 8; shell.setLayout(gridLayout); // 第一行标签 输入框 new Label(shell, SWT.NONE).setText(书名); Text bookName new Text(shell, SWT.BORDER); // 输入框水平填满所在单元格 bookName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); // 第二行按钮横跨两列 Button searchBtn new Button(shell, SWT.PUSH); searchBtn.setText(查询); GridData btnData new GridData(SWT.RIGHT, SWT.CENTER, false, false); btnData.horizontalSpan 2; // 跨两列 searchBtn.setLayoutData(btnData); shell.setSize(500, 300); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } }逻辑说明GridLayout 的构造函数第二个参数makeColumnsEqualWidth设为 false表示列宽按内容自适应。GridData 的四个布尔参数依次是「水平填充、垂直填充、水平抢占空间、垂直抢占空间」。跨列用horizontalSpan跨行用verticalSpan。参数说明marginWidth和marginHeight控制窗口边缘留白horizontalSpacing和verticalSpacing控制控件间距。这几个值调大一点界面会透气很多我一般用 10 和 8。注意GridLayout 里如果某一行控件数量不够numColumnsSWT 会自动补空位但不会报错界面看起来会错位。数清楚每行放几个控件。3. 图书管理系统核心界面表格、表单与事件绑定3.1 用 Table 和 TableViewer 展示图书列表图书管理系统的门面就是那张图书列表。SWT 原生 Table 已经够用但如果要排序、过滤、编辑单元格TableViewer 更省事。先看原生 Table 的写法理解底层结构。import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.*; public class BookTable { public static void main(String[] args) { Display display new Display(); Shell shell new Shell(display); shell.setText(图书列表); shell.setLayout(new org.eclipse.swt.layout.FillLayout()); // 多选、带边框、显示表头 Table table new Table(shell, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION); table.setHeaderVisible(true); // 显示表头 table.setLinesVisible(true); // 显示网格线 // 定义四列 String[] titles {ISBN, 书名, 作者, 库存}; int[] widths {120, 200, 150, 80}; for (int i 0; i titles.length; i) { TableColumn column new TableColumn(table, SWT.NONE); column.setText(titles[i]); column.setWidth(widths[i]); } // 插入三行模拟数据 String[][] data { {978-7-111-1, Java编程思想, Bruce Eckel, 5}, {978-7-111-2, 算法导论, Cormen, 3}, {978-7-111-3, 深入理解JVM, 周志明, 2} }; for (String[] row : data) { TableItem item new TableItem(table, SWT.NONE); item.setText(row); } shell.setSize(600, 400); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } }逻辑说明TableColumn 定义列TableItem 定义行。setText(String[])一次性设置整行文本比逐列 setText 快。SWT.FULL_SELECTION让选中效果覆盖整行SWT.MULTI支持多选删除多条记录时用得上。参数说明列宽单位像素setHeaderVisible(true)必须调用否则表头不显示。setLinesVisible(true)控制行间横线数据密集时建议开启。如果要做排序给 TableColumn 加 SelectionListener在监听里调用table.setSortColumn(column)和table.setSortDirection(SWT.UP/DOWN)然后重新填充数据。TableViewer 则可以用 ViewerComparator 直接搞定。3.2 表单录入与按钮事件把借阅、归还、新增串起来界面有了接下来是交互。图书管理系统里最典型的操作是「新增图书」和「借阅归还」。下面用一个新增图书的表单演示 SWT 的事件绑定。import org.eclipse.swt.SWT; import org.eclipse.swt.layout.*; import org.eclipse.swt.widgets.*; public class BookForm { public static void main(String[] args) { Display display new Display(); Shell shell new Shell(display); shell.setText(新增图书); shell.setLayout(new GridLayout(2, false)); // 四个输入项 new Label(shell, SWT.NONE).setText(ISBN); Text isbn new Text(shell, SWT.BORDER); isbn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); new Label(shell, SWT.NONE).setText(书名); Text name new Text(shell, SWT.BORDER); name.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); new Label(shell, SWT.NONE).setText(作者); Text author new Text(shell, SWT.BORDER); author.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); new Label(shell, SWT.NONE).setText(库存); Text stock new Text(shell, SWT.BORDER); stock.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); // 提交按钮 Button submit new Button(shell, SWT.PUSH); submit.setText(保存); GridData btnData new GridData(SWT.RIGHT, SWT.CENTER, false, false); btnData.horizontalSpan 2; submit.setLayoutData(btnData); // 绑定点击事件 submit.addListener(SWT.Selection, event - { String isbnVal isbn.getText().trim(); String nameVal name.getText().trim(); if (isbnVal.isEmpty() || nameVal.isEmpty()) { MessageBox box new MessageBox(shell, SWT.ICON_WARNING | SWT.OK); box.setText(校验失败); box.setMessage(ISBN 和书名不能为空); box.open(); return; } // 这里调用 DAO 层入库示例先打印 System.out.println(保存 isbnVal / nameVal); // 保存成功后清空表单 isbn.setText(); name.setText(); author.setText(); stock.setText(); }); shell.setSize(400, 300); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } }逻辑说明addListener(SWT.Selection, ...)是 SWT 通用的事件绑定方式按钮点击、菜单选择、表格行选中都用 Selection 事件。lambda 里先做非空校验用 MessageBox 弹窗提示校验通过再走 DAO 入库。入库成功后清空输入框方便连续录入。参数说明SWT.ICON_WARNING是警告图标SWT.OK表示只有一个确定按钮。如果要「是/否」对话框用SWT.YES | SWT.NO然后判断box.open()的返回值。提示SWT 的事件处理默认在 UI 线程执行如果 DAO 操作耗时较长比如查远程数据库界面会卡住。常见做法是把耗时操作放到后台线程再用display.asyncExec()回到 UI 线程更新控件。3.3 用 JDBC 把界面和数据库接起来界面再漂亮数据存不住就是玩具。图书管理系统一般用 MySQL 或 SQLite课程设计里 SQLite 更省事不用装服务。下面是一个极简的 DAO 示例展示 SWT 界面如何调用 JDBC。import java.sql.*; public class BookDao { // SQLite 连接数据库文件放在项目根目录 private static final String URL jdbc:sqlite:library.db; public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL); } // 初始化建表程序启动时调一次 public static void initTable() { String sql CREATE TABLE IF NOT EXISTS book ( isbn TEXT PRIMARY KEY, name TEXT NOT NULL, author TEXT, stock INTEGER DEFAULT 0); try (Connection conn getConnection(); Statement stmt conn.createStatement()) { stmt.execute(sql); } catch (SQLException e) { e.printStackTrace(); } } // 新增图书 public static boolean addBook(String isbn, String name, String author, int stock) { String sql INSERT INTO book(isbn, name, author, stock) VALUES(?,?,?,?); try (Connection conn getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, isbn); ps.setString(2, name); ps.setString(3, author); ps.setInt(4, stock); return ps.executeUpdate() 0; } catch (SQLException e) { e.printStackTrace(); return false; } } }逻辑说明initTable用CREATE TABLE IF NOT EXISTS保证重复启动不报错。addBook用 PreparedStatement 占位符传参避免 SQL 注入也省去拼接字符串的转义麻烦。返回布尔值让界面层知道是否成功。参数说明SQLite 的 JDBC 驱动坐标是org.xerial:sqlite-jdbcMaven 里加一条依赖即可。如果换 MySQLURL 改成jdbc:mysql://localhost:3306/library驱动类换成com.mysql.cj.jdbc.Driver。在 3.2 的按钮事件里把System.out.println换成BookDao.addBook(...)判断返回值决定弹成功还是失败提示界面和数据就打通了。4. 避坑与排查SWT 桌面开发最容易翻车的五个地方4.1 窗口一闪而过或控件不显示现象程序启动后窗口空白或者直接退出。原因通常是没写事件循环或者控件没设布局导致尺寸为零。解决确认while (!shell.isDisposed())循环存在且 Shell 设置了 Layout。如果用了 GridLayout检查每个控件是否设置了 GridData没设的话控件会按最小尺寸显示可能小到看不见。4.2 中文乱码或字体发虚现象界面上的中文显示成方块或者在高分屏上模糊。原因SWT 默认字体在某些系统上不含中文字形或者没有开启 DPI 感知。解决给 Shell 显式设置字体用new Font(display, 微软雅黑, 10, SWT.NORMAL)并在程序启动前设置System.setProperty(swt.autoScale, false)或按系统 DPI 调整。Windows 上还可以在 exe 清单里声明 DPI 感知。4.3 表格数据量大时卡顿现象往 Table 里插入上万条记录时界面假死。原因每new TableItem一次都会触发重绘逐条插入开销大。解决插入前调用table.setRedraw(false)插完再setRedraw(true)。更彻底的做法是用虚拟表格SWT.VIRTUAL配合setItemCount和SWT.SetData监听器按需提供数据只渲染可见行。4.4 打包成 jar 后运行报 UnsatisfiedLinkError现象IDE 里跑得好好的java -jar就报找不到本地库。原因SWT 的本地库.dll 或 .so没有随 jar 一起打包或者分类器不对。解决用 Maven Shade 插件把对应平台的 SWT jar 打进去或者用mvn dependency:copy-dependencies把依赖复制到 lib 目录运行时用-Djava.library.path指定。跨平台发布建议按系统分别打包。4.5 事件里更新界面抛 Invalid thread access现象在后台线程里直接调用label.setText()报错。原因SWT 控件只能在创建它的 UI 线程访问。解决用display.asyncExec(() - label.setText(...))或syncExec切回 UI 线程。asyncExec 不阻塞后台线程syncExec 会等待执行完成按场景选。5. 进阶技巧让图书管理系统更像一个能交付的作品把基本功能跑通只是及格线想让课程设计拿高分或者写进简历还得在细节上花点功夫。第一个技巧是给表格加右键菜单和快捷键。SWT 的 Menu 可以挂在 Table 上table.setMenu(menu)菜单项里绑定 Selection 事件实现「删除选中行」「刷新」等操作。快捷键用MenuItem.setAccelerator(SWT.CTRL | D)用户按 CtrlD 直接删除体验立刻上一个台阶。第二个技巧是状态栏和进度提示。SWT 没有内置状态栏但可以用一个 Label 放在窗口底部配合 GridData 的horizontalSpan横跨所有列。执行数据库操作时把状态栏文字改成「正在保存…」完成后改成「保存成功共 X 条记录」。这种即时反馈对答辩演示很加分。第三个技巧是数据校验前置。不要等用户点了保存才弹一堆错误而是在输入框失去焦点时就校验。给 Text 加SWT.FocusOut监听ISBN 格式不对就标红或者弹提示。ISBN 可以用正则^\d{3}-\d-\d{3}-\d{5}-\d$做初步校验库存必须是正整数用Integer.parseInt加 try-catch。第四个技巧是导出功能。图书列表经常需要导出成 Excel 或 CSV 给老师看。CSV 最简单用BufferedWriter把 Table 里的数据逐行写出注意中文用 UTF-8 编码Excel 打开时如果乱码就在文件开头写 BOM。Excel 的话可以用 Apache POI但依赖会重一些课程设计用 CSV 足够了。最后一个技巧是关于打包发布的。用jpackage可以把 jar 打成 exe 或 dmg用户双击就能运行不用装 Java 环境。命令大致是jpackage --input target --main-jar library.jar --main-class com.demo.Main --type exe --name 图书管理系统。Windows 上需要 WiX ToolsetMac 上需要 Xcode 命令行工具。打出来的安装包体积会大一些因为内嵌了 JRE但交付体验最好。我自己做这类项目最大的教训是别一上来就追求功能大而全先把「新增-查询-修改-删除」这条主链路用 SWT 界面加 SQLite 跑通再逐步加借阅记录、用户权限、导出报表。每加一个功能就打包一次确认没有引入新的依赖问题。这样到最后交付时你手里是一个每一步都验证过的系统而不是一堆跑不起来的代码。希望帮到你。本文还有配套的精品资源点击获取
返回列表