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!
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.
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; …
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.
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".
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(); } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With