Guided edit row selection in JTable

I have a JTable displaying rows from an SQL database. The table is relatively small (only 4 columns and up to 1000 rows).

I would like to give the user the ability to edit any cells in the table, but you should not limit it so much that they use the edit dialog box (this simplifies error checking and checking, but is less intuitive)

I tried several different ways of managing choices using the valueChanged method of my JTable, but didn't have much luck.

I want each row to be edited and written to the database when editing is complete. I would like that after a cell has been pressed to start editing this row, no other rows can be selected until the user has finished editing the row (other rows will be grayed out). After editing each cell and pressing enter, the selection of editing should go to the next column in the same row.

Can someone give pointers on how I can achieve this?

// 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); } }; 

Edit - custom cell editor with table pointer seems empty

 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; } 

}

+3
source share
2 answers

The default rendering and editor is usually suitable for most data types, but you can define custom renderers and editors as needed.

Addendum: I am not familiar with the approach indicated in your snippet. Instead, register a TableModelListener with your model, as shown below, and update the database with any level of detail. See Also How to use tables: listening for data changes .

Application: @kleopatra correctly refers to your TableCellEditor . One convenient way to notify listeners is to call a super implementation, as shown here. Note that delegate calls 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(); } }); } } 
+4
source

The behavior you are talking about can be achieved by forcing the resumption of editing your table.

First, make sure you now have your own table and column, and you add your own tablecelleditor, which extends from AbstractCellEditor, then add this to the stopCellEditing method:

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

All Articles