当用户在 JTable 中编辑单元格后直接点击 Save 按钮,最后一项修改常未被保存——这是因为编辑器仍处于激活状态,setValueAt() 尚未触发;通过设置 terminateEditOnFocusLost 客户端属性可强制失焦时提交编辑。
当用户在 jtable 中编辑单元格后直接点击 save 按钮,最后一项修改常未被保存——这是因为编辑器仍处于激活状态,`setvalueat()` 尚未触发;通过设置 `terminateeditonfocuslost` 客户端属性可强制失焦时提交编辑。
在 Swing 的 JTable 中,单元格编辑采用“延迟提交”机制:用户完成输入后,若焦点未离开该单元格(例如直接点击外部按钮),编辑器(如 DefaultCellEditor)不会自动调用 stopCellEditing(),因此 setValueAt() 不会被执行,模型中的数据也就不会更新。这正是你遇到的问题——点击 Save 时,Name 字段的最新值仍滞留在编辑器中,未写入 StudentModel.userProperty。
✅ 根本解决方法:启用编辑自动终止
只需在创建 JTable 后、将其加入界面前,添加以下关键配置:
jtable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);该客户端属性是 Swing 自 JDK 6u10 起引入的官方修复方案(对应 JDK-6349059),它会强制表格在失去焦点(包括按钮点击、窗口切换等场景)时立即终止当前编辑并提交变更。
⚠️ 注意:此属性必须在 JTable 实例化后、且在任何编辑操作发生前设置,否则可能无效。
? 推荐的完整初始化优化(含布局修正)
你原代码中将 JTable 放入 JPanel 再添加到 JFrame,但未指定布局约束,易导致显示异常。更健壮的做法是直接使用 BorderLayout 管理主容器:
void initializeComponent() {
studentModel = new StudentModel(getDummyData());
jtable = new JTable(studentModel);
// ✅ 关键:启用编辑自动终止
jtable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
// ✅ 使用 BorderLayout 规范布局
add(new JScrollPane(jtable), BorderLayout.CENTER); // 表格占满中央区域
JPanel buttonPanel = new JPanel(); // 按钮单独成面板
addBtn = new JButton("Save");
addBtn.addActionListener(this);
resetBtn = new JButton("Close");
resetBtn.addActionListener(this);
buttonPanel.add(addBtn);
buttonPanel.add(resetBtn);
add(buttonPanel, BorderLayout.SOUTH); // 按钮置于底部
}? 额外建议与验证技巧
-
调试验证:在 actionPerformed 中 Save 前,可主动触发编辑终止以双重保险(非必需,但增强鲁棒性):
if (e.getSource() == addBtn) { // 强制结束当前编辑(即使未失焦) if (jtable.isEditing()) { jtable.getCellEditor().stopCellEditing(); } System.out.println("Final data: " + studentModel.getAttributeMap()); } 模型一致性:StudentModel 中 keys 数组基于 userProperty.keySet() 动态生成,但 keySet() 无序。如需固定顺序(如 Age 在 Name 前),建议改用 LinkedHashMap 并按预期顺序插入键值对。
-
UI 可访问性:为提升体验,可为 Save 按钮添加快捷键(如 Ctrl+S):
addBtn.setMnemonic(KeyEvent.VK_S); getRootPane().setDefaultButton(addBtn); // 回车键也可触发
遵循以上方案,即可彻底解决“点击 Save 时最后编辑内容丢失”的问题,确保用户所有输入均实时、可靠地同步至数据模型。

















