JTable单元格无法获取最新更新值的问题求助
问题:Java Swing JTable编辑后直接点击Save无法获取最新值
我正在开发Java Swing UI,使用JTable允许用户更新Attribute值。更新Age时,内部会触发setValueAt方法完成更新,但更新第二个值Name后直接点击Save按钮,却无法获取Name的最新更新值。原因是只有在点击离开Name所在行时,才会内部触发setValueAt方法。请问有没有办法在点击按钮时触发该方法,以便获取最新值?
编辑补充
Model类
public class StudentModel extends AbstractTableModel { private static final long serialVersionUID = 1L; private final Map<String, String> userProperty = new HashMap<>(); private final String[] header = new String[]{"Attribute Name", "Attribute Value"}; private String[] keys; public StudentModel(Map<String, String> attributeMap) { this.userProperty.putAll(attributeMap); keys = this.userProperty.keySet().toArray(new String[this.userProperty.size()]); } @Override public int getRowCount() { return userProperty.size(); } @Override public int getColumnCount() { return header.length; } @Override public String getColumnName(int col) { if (col == 0) { return header[0]; } else { return header[1]; } } @Override public Object getValueAt(int rowIndex, int columnIndex) { if (columnIndex == 0) { return keys[rowIndex]; } else { return userProperty.get(keys[rowIndex]); } } public void removeAllRows() { this.userProperty.clear(); keys = this.userProperty.keySet().toArray(new String[this.userProperty.size()]); } public void addRow(Map<String, String> newRows) { this.userProperty.putAll(newRows); keys = this.userProperty.keySet().toArray(new String[this.userProperty.size()]); } public void updateTable() { fireTableDataChanged(); } @Override public boolean isCellEditable(int row, int column) { return column == 1; } @Override public void setValueAt(Object value, int row, int col) { userProperty.put(keys[row], String.valueOf(value)); fireTableCellUpdated(row, col); } public Map<String, String> getAttributeMap() { return userProperty; } }
UI类
public class JTableDemo2 extends JFrame implements ActionListener { private JButton addBtn; private JButton resetBtn; private JTable jtable; private StudentModel studentModel; private JTableDemo2() { setBounds(300, 200, 550, 400); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent we) { dispose(); } }); initializeComponent(); } void initializeComponent() { JPanel panel = new JPanel(); studentModel = new StudentModel(getDummyData()); addBtn = new JButton("Save"); addBtn.addActionListener(this); resetBtn = new JButton("Close"); resetBtn.addActionListener(this); jtable = new JTable(studentModel); panel.add(new JScrollPane(jtable)); panel.add(addBtn); panel.add(resetBtn); add(panel); } /** * @param args the command line arguments */ public static void main(String[] args) { JTableDemo2 object = new JTableDemo2(); object.setVisible(true); } private Map<String, String> getDummyData() { Map<String, String> rowData = new HashMap<>(); rowData.put("Age", ""); rowData.put("Name", ""); return rowData; } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == addBtn) { System.out.println("studentModel.getAttributeMap() :" + studentModel.getAttributeMap()); } } }
点击按钮后的输出
控制台输出:studentModel.getAttributeMap() :{Age=18, Name=},可见Name的最新输入值未被保存到Model中。
解决方案
修改UI类中的actionPerformed方法,在获取数据前强制结束当前单元格的编辑:
@Override public void actionPerformed(ActionEvent e) { if (e.getSource() == addBtn) { // 强制结束当前单元格编辑,确保修改提交到Model if (jtable.isEditing()) { jtable.getCellEditor().stopCellEditing(); } System.out.println("studentModel.getAttributeMap() :" + studentModel.getAttributeMap()); } else if (e.getSource() == resetBtn) { dispose(); } }
原理
JTable默认仅在单元格失去焦点(如点击其他行、组件)时,才会调用单元格编辑器的stopCellEditing()方法,将编辑内容提交到TableModel。直接点击Save按钮时,编辑的单元格仍处于激活状态,修改未提交,因此Model中还是旧值。主动调用stopCellEditing()可强制提交当前编辑内容,确保获取到最新值。
内容的提问来源于stack exchange,提问作者user21528347
相关产品推荐
相关产品推荐

