Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JTable: Detect cell data change

Tags:

In Netbeans, I used the GUI Builder to insert a JTable into my application.

I have just one class (CustomerDB) so far which is:

package CustomerDB;  import [...];  public class CustomerDB extends javax.swing.JFrame {      CellEditorListener ChangeNotification = new CellEditorListener() {         public void editingCanceled(ChangeEvent e) {             System.out.println("The user canceled editing.");         }          public void editingStopped(ChangeEvent e) {             System.out.println("The user stopped editing successfully.");         }     };      public CustomerDB() {         customerTable = new javax.swing.JTable();         customerTable.setModel(new javax.swing.table.DefaultTableModel(             new Object [][] {                 {null, null, null, null},                 {null, null, null, null},                 {null, null, null, null},                 {null, null, null, null},                 {null, null, null, null},                 {null, null, null, null},                 {null, null, null, null},                 {null, null, null, null},                 {null, null, null, null},                 {null, null, null, null}             },             new String [] {                 "ID", "Name", "Address", "Phone"             }         ) {             Class[] types = new Class [] {                 java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class             };              public Class getColumnClass(int columnIndex) {                 return types [columnIndex];             }         });         customerTable.getDefaultEditor(String.class).addCellEditorListener(ChangeNotification);     }       public static void main(String args[]) {         java.awt.EventQueue.invokeLater(new Runnable() {             public void run() {                 new CustomerDB().setVisible(true);             }         });     }      // Variables declaration - do not modify     [...]     private javax.swing.JTable customerTable;     [...]     // End of variables declaration  } 

Whenever a user changes data in the table, I want to get the old value (optional) and the new value of that cell.

In order to get this data, I tried to implement an event listener:

    CellEditorListener ChangeNotification = new CellEditorListener() {         public void editingCanceled(ChangeEvent e) {             System.out.println("The user canceled editing.");         }          public void editingStopped(ChangeEvent e) {             System.out.println("The user stopped editing successfully.");         }     }; 

Then I assign this CellEditorListener to the table (its cell editor):

    customerTable.getDefaultEditor(String.class).addCellEditorListener(ChangeNotification); 

This works so far. But it doesn't yet enable me to detect the old and the new value of this cell. What else do I have to do?

Thank you very much in advance!

like image 474
caw Avatar asked Jul 31 '11 13:07

caw


People also ask

How can you change the appearance of data in cells in JTable?

We can change the background and foreground color for each column of a JTable by customizing the DefaultTableCellRenderer class and it has only one method getTableCellRendererComponent() to implement it.

How delete all data from JTable?

You must remove the data from the TableModel used for the table. If using the DefaultTableModel , just set the row count to zero. This will delete the rows and fire the TableModelEvent to update the GUI. JTable table; …

How do I get the value of a JTable cell?

To get the value from a particular grid cell, you can use the wValue property of the JTable object. The property has the Row and Column parameters which specify the row and the column that contain the cell.


2 Answers

But it doesn't yet enable me to detect the old and the new value of this cell. What else do I have to do?

It is easier to use a TableModelListener to listen for changes but it still has the problem of not being able to access the old value.

Check out the Table Cell Listener for a solution that gives you access to the "old value" as well as the "new value".

like image 62
camickr Avatar answered Sep 21 '22 14:09

camickr


or TableModelLister with ListSelectionListener, fist returns if TableCell changed, second from selected call, then just compare Row & Column Index from TableModelLister with ListSelectionListener

import java.awt.*; import java.util.Random; import java.util.Vector; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer;  public class Forum implements ListSelectionListener {      private JFrame frame = new JFrame("Frame");     private JPanel fatherCenter = new JPanel();     private JScrollPane tableScroll = new JScrollPane();     private myTableModel tableModel;     private JTable dialogTable;     private ListSelectionModel lsDialog;      private void addComponentsToPane(Container pane) {         tableModel = new myTableModel();         dialogTable = new JTable(tableModel) {              private static final long serialVersionUID = 1L;              @Override             public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {                 Component comp = super.prepareRenderer(renderer, row, column);                 JComponent jc = (JComponent) comp;//for Custom JComponent                 if (!isRowSelected(row)) {                     int modelRow = convertRowIndexToModel(row);                     boolean type = (Boolean) getModel().getValueAt(modelRow, 2);                     boolean type1 = (Boolean) getModel().getValueAt(modelRow, 3);                     boolean type2 = (Boolean) getModel().isCellEditable(row, column);                     comp.setForeground(Color.black);                     if ((type) && (!type1)) {                         comp.setBackground(Color.yellow);                     } else if ((!type) && (type1)) {                         comp.setBackground(Color.orange);                     } else if ((!type) || (!type1)) {                         comp.setBackground(Color.red);                         //} else if ((!type2)) {                         //comp.setForeground(Color.red);                         //comp.setBackground(Color.magenta);                     } else {                         comp.setBackground(row % 2 == 0 ? getBackground() : getBackground().darker());                     }                     dialogTable.convertRowIndexToView(0);                 } else {                     comp.setForeground(Color.blue);                     comp.setBackground(Color.lightGray);                 }                 if (!isCellEditable(row, column)) {                     comp.setForeground(Color.red);                     comp.setBackground(Color.magenta);                 }                 return comp;             }         };         tableScroll = new JScrollPane(dialogTable, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,                 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);         tableScroll.setBorder(null);         dialogTable.getTableHeader().setReorderingAllowed(false);         dialogTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);         lsDialog = dialogTable.getSelectionModel();         dialogTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);         dialogTable.setRowHeight(20);         dialogTable.setRowMargin(2);         ListSelectionModel rowSelMod = dialogTable.getSelectionModel();         //ListSelectionModel colSelMod = dialogTable.getColumnModel().getSelectionModel();         rowSelMod.addListSelectionListener(this);         //colSelMod.addListSelectionListener(this);         fatherCenter = new JPanel();         fatherCenter.setLayout(new BorderLayout(10, 10));         fatherCenter.add(tableScroll, BorderLayout.CENTER);         pane.add(fatherCenter);     }      private void addData() {         Runnable doRun1 = new Runnable() {              @Override             public void run() {                 tableModel.resetTable();                 Vector<String> tbl = new Vector<String>();                 Vector<Object> tbl1 = new Vector<Object>();                 Random rnd = new Random();                 tbl.add("Integer");                 tbl.add("Double");                 tbl.add("Boolean");                 tbl.add("Boolean");                 tbl.add("String");                 tableModel.setColumnNames(tbl);                 for (int row = 0; row < 30; row++) {                     tbl1 = null;                     tbl1 = new Vector<Object>();                     tbl1.addElement(row + 1);                     tbl1.addElement(rnd.nextInt(25) + 3.14);                     tbl1.addElement((row % 3 == 0) ? false : true);                     tbl1.addElement((row % 5 == 0) ? false : true);                     if (row % 7 == 0) {                         tbl1.add(("Canc"));                     } else if (row % 6 == 0) {                         tbl1.add(("Del"));                     } else {                         tbl1.add(("New"));                     }                     tableModel.addRow(tbl1);                 }                 addTableListener();             }         };         SwingUtilities.invokeLater(doRun1);     }      private void addTableListener() {         tableModel.addTableModelListener(new TableModelListener() {              @Override             public void tableChanged(TableModelEvent tme) {                 if (tme.getType() == TableModelEvent.UPDATE) {                     System.out.println("");                     System.out.println("Cell " + tme.getFirstRow() + ", "                             + tme.getColumn() + " changed. The new value: "                             + tableModel.getValueAt(tme.getFirstRow(),                             tme.getColumn()));                 }             }         });     }      public void valueChanged(ListSelectionEvent le) {         int row = dialogTable.getSelectedRow();         int col = dialogTable.getSelectedColumn();         String str = "Selected Row(s): ";         int[] rows = dialogTable.getSelectedRows();         for (int i = 0; i < rows.length; i++) {             str += rows[i] + " ";         }         str += "Selected Column(s): ";         int[] cols = dialogTable.getSelectedColumns();         for (int i = 0; i < cols.length; i++) {             str += cols[i] + " ";         }         str += "Selected Cell: " + dialogTable.getSelectedRow() + ", " + dialogTable.getSelectedColumn();         System.out.println(str);         Object value = dialogTable.getValueAt(row, col);         System.out.println(String.valueOf(value));     }      private void createAndShowGUI() {         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         frame.setLayout(new BorderLayout(10, 10));         addComponentsToPane(frame.getContentPane());         addData();         frame.setLocation(150, 150);         frame.setPreferredSize(new Dimension(400, 647));         frame.pack();         frame.setVisible(true);     }      public static void main(String[] args) {         Forum osFrame = new Forum();     }      public Forum() {         javax.swing.SwingUtilities.invokeLater(new Runnable() {              @Override             public void run() {                 createAndShowGUI();             }         });     }      private class myTableModel extends AbstractTableModel {          private static final long serialVersionUID = 1L;         private Vector<Vector<Object>> data;         private Vector<String> colNames;         private boolean[] _columnsVisible = {true, true, true, true, true};          myTableModel() {             this.colNames = new Vector<String>();             this.data = new Vector<Vector<Object>>();         }          myTableModel(Vector<String> colnames) {             this.colNames = colnames;             this.data = new Vector<Vector<Object>>();         }          public void resetTable() {             this.colNames.removeAllElements();             this.data.removeAllElements();         }          public void setColumnNames(Vector<String> colNames) {             this.colNames = colNames;             this.fireTableStructureChanged();         }          public void addRow(Vector<Object> data) {             this.data.add(data);             this.fireTableDataChanged();             this.fireTableStructureChanged();         }          public void removeRowAt(int row) {             this.data.removeElementAt(row);             this.fireTableDataChanged();         }          @Override         public int getColumnCount() {             return this.colNames.size();         }          @Override         public Class<?> getColumnClass(int colNum) {             switch (colNum) {                 case 0:                     return Integer.class;                 case 1:                     return Double.class;                 case 2:                     return Boolean.class;                 case 3:                     return Boolean.class;                 default:                     return String.class;             }         }          @Override         public boolean isCellEditable(int row, int colNum) {             switch (colNum) {                 case 2:                     return false;                 default:                     return true;             }         }          @Override         public String getColumnName(int colNum) {             return this.colNames.get(colNum);         }          @Override         public int getRowCount() {             return this.data.size();         }          @Override         public Object getValueAt(int row, int col) {             Vector<Object> value = this.data.get(row);             return value.get(col);         }          @Override         public void setValueAt(Object newVal, int row, int col) {             Vector<Object> aRow = data.elementAt(row);             aRow.remove(col);             aRow.insertElementAt(newVal, col);             fireTableCellUpdated(row, col);         }          public void setColumnVisible(int index, boolean visible) {             this._columnsVisible[index] = visible;             this.fireTableStructureChanged();         }     } } 
like image 35
mKorbel Avatar answered Sep 20 '22 14:09

mKorbel