Swing产品管理界面点击JButton后JFrame冻结问题求助
问题原因
- UI线程被耗时操作阻塞:Swing采用单线程模型,所有界面渲染、事件响应都在事件分发线程(EDT)中执行。你直接在按钮点击的事件回调里执行数据库查询、ResultSet遍历这类耗时IO操作,会直接占用EDT线程,导致界面无法响应其他操作,出现冻结。
- TableModel操作冗余错误:你在循环添加每行数据时,反复调用
table.setModel(m1),DefaultTableModel本身修改后会自动触发表格刷新,反复重设模型会导致表格每次加行都全量重绘,数据量稍大就会占满EDT资源。同时多次调用showData时没有清空旧数据,模型行不断累加,操作耗时会越来越高,加剧卡顿冻结。 - 数据库资源泄漏:代码中ResultSet、Statement执行完成后没有主动释放,多次操作后数据库连接资源被耗尽,后续数据库请求会阻塞等待可用连接,进一步导致界面无响应。
- 你贴出的代码片段存在语法缺失,缺少循环闭合、资源关闭的相关代码,也可能引发未捕获的异常导致线程挂起。
可行解决方案
- 用
SwingWorker把数据库操作放到后台线程执行,仅把最终的表格更新操作放回EDT执行,避免阻塞UI。 - 调整TableModel操作逻辑:执行查询前先清空模型原有数据,所有行添加完成后不需要反复重设模型。
- 用try-with-resources语法自动管理数据库相关资源,避免资源泄漏。
修正后的showData()参考代码:
// 放到Show按钮的事件监听器里调用 new SwingWorker<DefaultTableModel, Void>() { @Override protected DefaultTableModel doInBackground() throws Exception { // 后台线程执行数据库查询,不占用EDT DefaultTableModel m1 = (DefaultTableModel) table.getModel(); // 先清空旧数据,避免重复累加 m1.setRowCount(0); // try-with-resources自动关闭ResultSet、Statement,避免资源泄漏 try (Statement s = conn.createStatement(); ResultSet r = s.executeQuery("SELECT * FROM EmployeeTable")) { while (r.next()) { String name1 = r.getString("EmployeeName"); String userID = r.getString("UserID"); String username = r.getString("Username"); String password = r.getString("Password"); String[] data = {name1, userID, username, password}; m1.addRow(data); } } return m1; } @Override protected void done() { // 后台执行完成后在EDT处理异常,避免线程挂起 try { get(); } catch (Exception e) { e.printStackTrace(); // 可自行添加弹窗提示查询失败 } } }.execute();
- Insert按钮的数据库写入逻辑也按照同样的逻辑改造,用SwingWorker包裹写入操作,不要直接在EDT里执行数据库操作即可解决交叉点击冻结的问题。
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

