如何获取JTable选中行数据并设置到JTextArea中完成打印
现有代码存在的问题
- 循环逻辑冲突:外层遍历所有行,但是循环体内直接把循环变量
row覆盖为选中行索引,既存在死循环风险,也无法正确支持多选场景 - 缺少非空校验:如果用户没有选中任何行,
getSelectedRow()会返回-1,调用getValueAt会直接抛出数组越界异常 - 频繁调用
setText拼接内容性能差,建议用StringBuilder一次性拼接后再赋值 - 直接用JTable的
getValueAt要注意视图索引和模型索引不一致的问题(如果给表格做了列排序/隐藏,会拿错数据)
正确实现代码
单选场景(仅允许选中一行)
// 先判断是否选中行 int selectedRow = jTable_S_Class.getSelectedRow(); if (selectedRow == -1) { Print_Area.setText("请先选中需要打印的行"); return; } // 转换为模型索引,避免列排序/隐藏导致的数据错位 int modelRow = jTable_S_Class.convertRowIndexToModel(selectedRow); DefaultTableModel model = (DefaultTableModel) jTable_S_Class.getModel(); // 用StringBuilder拼接内容,性能更高 StringBuilder sb = new StringBuilder(); // 按列取对应的值 String S_Hobby = model.getValueAt(modelRow, 0).toString(); String S_Phone = model.getValueAt(modelRow, 1).toString(); String S_Area = model.getValueAt(modelRow, 2).toString(); String S_Class_Name = model.getValueAt(modelRow, 3).toString(); String S_Mony = model.getValueAt(modelRow, 4).toString(); String S_Year = model.getValueAt(modelRow, 5).toString(); String S_Student_Part = model.getValueAt(modelRow, 6).toString(); String S_Student_ID = model.getValueAt(modelRow, 7).toString(); String S_Statues = model.getValueAt(modelRow, 8).toString(); String S_Mother_Name = model.getValueAt(modelRow, 9).toString(); String S_Student_Name = model.getValueAt(modelRow, 10).toString(); // 拼接行数据 sb.append(S_Student_Name).append("\t\n") .append(S_Mother_Name).append("\t\n") .append(S_Statues).append(S_Student_ID).append("\t\n") .append(S_Hobby).append("\t\n") .append(S_Student_Part).append("\t\n") .append(S_Year).append("\t\n") .append(S_Mony).append("\t\n") .append(S_Class_Name).append("\t\n") .append(S_Area).append("\t\n") .append(S_Phone).append("\n"); // 拼接底部落款 sb.append("\n") .append("==============================================================\n") .append("\t\t إدارة المدرسة\n") .append("=============================================================\n"); // 一次性赋值给JTextArea Print_Area.setText(sb.toString());
多选场景(允许同时选中多行批量打印)
int[] selectedRows = jTable_S_Class.getSelectedRows(); if (selectedRows.length == 0) { Print_Area.setText("请先选中需要打印的行"); return; } DefaultTableModel model = (DefaultTableModel) jTable_S_Class.getModel(); StringBuilder sb = new StringBuilder(); for (int viewRow : selectedRows) { // 每次转换索引避免错位 int modelRow = jTable_S_Class.convertRowIndexToModel(viewRow); // 取列值逻辑和单选一致 String S_Hobby = model.getValueAt(modelRow, 0).toString(); String S_Phone = model.getValueAt(modelRow, 1).toString(); String S_Area = model.getValueAt(modelRow, 2).toString(); String S_Class_Name = model.getValueAt(modelRow, 3).toString(); String S_Mony = model.getValueAt(modelRow, 4).toString(); String S_Year = model.getValueAt(modelRow, 5).toString(); String S_Student_Part = model.getValueAt(modelRow, 6).toString(); String S_Student_ID = model.getValueAt(modelRow, 7).toString(); String S_Statues = model.getValueAt(modelRow, 8).toString(); String S_Mother_Name = model.getValueAt(modelRow, 9).toString(); String S_Student_Name = model.getValueAt(modelRow, 10).toString(); // 拼接当前行数据 sb.append(S_Student_Name).append("\t\n") .append(S_Mother_Name).append("\t\n") .append(S_Statues).append(S_Student_ID).append("\t\n") .append(S_Hobby).append("\t\n") .append(S_Student_Part).append("\t\n") .append(S_Year).append("\t\n") .append(S_Mony).append("\t\n") .append(S_Class_Name).append("\t\n") .append(S_Area).append("\t\n") .append(S_Phone).append("\n\n"); } // 拼接底部落款 sb.append("==============================================================\n") .append("\t\t إدارة المدرسة\n") .append("=============================================================\n"); Print_Area.setText(sb.toString());
额外优化建议
- 如果列顺序可能调整,建议不要写死列索引,可以通过
model.findColumn("列名")动态获取列索引,适配性更强 - 如果单元格可能为空,建议加非空判断再调用
toString(),避免空指针异常 convertRowIndexToModel是必要操作,只要给JTable开启了排序、列移动、列隐藏功能,不加这个就会出现拿到的数据和显示不一致的问题
内容的提问来源于stack exchange,提问作者Motivation -التحفيز
相关产品推荐
相关产品推荐

