在JTable中控制行选择的编辑

我有一个JTable显示SQL数据库中的行。 该表相对较小(仅4列,最多1000行)。

我想让用户有机会编辑表格中的任何单元格,但是要避免限制它,以便他们必须使用编辑对话框(这样可以更容易地进行错误检查和validation,但不太直观)

我尝试了几种使用JTable的valueChanged方法控制编辑选择的方法,但运气不好。

我想在编辑结束时编辑每一行并将其写入数据库。 我希望一旦单击一个单元格开始编辑该行,在用户完成编辑行之前不能选择其他行(其他行显示为灰色)。 编辑每个单元格并按Enter后,编辑选择应跳转到同一行中的下一列。

谁能指点我怎么能做到这一点?

// Create table with database data table = new JTable(new DefaultTableModel(data, columnNames)) { public Class getColumnClass(int column) { for (int row = 0; row < getRowCount(); row++) { Object o = getValueAt(row, column); if (o != null){ return o.getClass(); } } return Object.class; } @Override public boolean isCellEditable(int row, int col){ return true; } @Override public boolean editCellAt(int row, int column) { boolean ans = super.editCellAt(row, column); if (ans) { Component editor = table.getEditorComponent(); editor.requestFocusInWindow(); } return ans; } @Override public void valueChanged(ListSelectionEvent source) { super.valueChanged(source); if (table!=null) table.changeSelection(getSelectedRow(), getSelectedColumn()+1, false, false); } }; 

编辑 – 带有表指针的自定义单元格编辑器似乎是一个开始

 public class ExchangeTableCellEditor extends AbstractCellEditor implements TableCellEditor { private JTable table; JComponent component = new JTextField(); public ExchangeTableCellEditor(JTable table) { this.table = table; } public boolean stopCellEditing() { boolean ans = super.stopCellEditing(); //now we want to increment the cell count table.editCellAt(table.getSelectedRow(), table.getSelectedColumn()+1); return ans; } @Override public void cancelCellEditing() { //do nothing... must accept cell changes } @Override public Object getCellEditorValue() { return ((JTextField)component).getText(); } @Override public Component getTableCellEditorComponent(JTable arg0, Object value, boolean arg2, int arg3, int arg4) { ((JTextField)component).setText((String)value); return component; } 

}

默认渲染器和编辑器通常适用于大多数数据类型,但您可以根据需要定义自定义渲染器和编辑器 。

附录:我不熟悉你片段中显示的方法。 而是将TableModelListener注册到您的模型,如下所示,并使用保证的任何粒度更新数据库。 另请参见如何使用表:侦听数据更改

附录:@kleopatra对您的TableCellEditor是正确的。 通知侦听器的一种方便方法是调用超级实现,如此处所示。 请注意, delegate调用fireEditingStopped()

 /** @see https://stackoverflow.com/questions/9155596 */ public class NewJavaGUI extends JPanel { private final JTable table; public NewJavaGUI() { String[] colNames = {"C1", "C2", "C3"}; DefaultTableModel model = new DefaultTableModel(colNames, 0) { @Override public boolean isCellEditable(int row, int col) { // return your actual criteria return true; } @Override public Class getColumnClass(int col) { // return your actual type tokens return getValueAt(0, col).getClass(); } }; // Add data; note auto-boxing model.addRow(new Object[]{"A1", "A2", 42}); model.addRow(new Object[]{"B1", "B2", 42d}); model.addTableModelListener(new TableModelListener() { @Override public void tableChanged(TableModelEvent e) { // DML as indicated } }); table = new JTable(model); this.add(table); } private void display() { JFrame f = new JFrame("NewJavaGUI"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(this); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new NewJavaGUI().display(); } }); } } 

您提到的行为可以通过强制您的表再次开始编辑来实现。

首先确保你现在是yourRow和Column,然后你添加了自己的表格托管者,它从AbstractCellEditor中获取,然后将它添加到你的stopCellEditing方法:

 EventQueue.invokeLater(new Runnable() { public void run() { yourTable.editCellAt( yourRow, yourColumn+1); } });