JTable: Detect cell data change

前端 未结 3 734
庸人自扰
庸人自扰 2020-12-15 18:21

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

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

pack         


        
相关标签:
3条回答
  • 2020-12-15 18:39

    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();
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-15 18:39

    mKorbel is on to something. What if you create your own cell editor that extends DefaultCellEditor:

      customerTable.setDefaultEditor(String.class, new DefaultCellEditor(new JTextField()){
         @Override
         public Component getTableCellEditorComponent(JTable table,
                  Object value, boolean isSelected, int row, int column) {
            // code on line below is redundant but would be needed if need to see
            // other property of the value object than toString()
            String valueStr = (value == null) ? "null" : value.toString();
            System.out.printf("[%d, %d]: %s%n", row, column, valueStr);
            return super.getTableCellEditorComponent(table, value, isSelected, row, column);
         }
    
         @Override
         public Object getCellEditorValue() {
            System.out.printf("cell editor value: %s%n", super.getCellEditorValue());
            return super.getCellEditorValue();
         }
      });
    
    0 讨论(0)
  • 2020-12-15 18:54

    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".

    0 讨论(0)
提交回复
热议问题