Search code examples
swingjtabletablemodel

I'm able to update the TableModel using setValueAt() but changes are not visible in the Table


I'm able to update the TableModel using setValueAt() but changes are not visible in the Table below is the code:

    import javax.swing.JFrame;
    import javax.swing.JDialog;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.AbstractTableModel;
    import java.awt.Dimension;
    import java.awt.GridLayout;

public class TableFTFEditDemo extends JPanel {
private boolean DEBUG = true;
JTable table;
MyTableModel tableModel=new MyTableModel();

public TableFTFEditDemo() {
    super(new GridLayout(1,0));

    table = new JTable(tableModel);
    table.setPreferredScrollableViewportSize(new Dimension(500, 70));
    table.setFillsViewportHeight(true);

    //Create the scroll pane and add the table to it.
    JScrollPane scrollPane = new JScrollPane(table);

    //Set up stricter input validation for the integer column.
    table.setDefaultEditor(Integer.class,
                           new IntegerEditor(0, 100));

//If we didn't want this editor to be used for other
//Integer columns, we'd do this:
//table.getColumnModel().getColumn(3).setCellEditor(
//  new IntegerEditor(0, 100));

    //Add the scroll pane to this panel.
    add(scrollPane);
}

class MyTableModel extends AbstractTableModel {
    private String[] columnNames ;
    private Object[][] data; 
    MyTableModel(){
    columnNames=new String[] {"First Name","Last Name","Sport","# of Seaters","Vegetarian","blank"};
    data=new Object[][] {
            {"Kathy", "Smith",
            "Snowboarding", new Integer(5), new Boolean(false),"sdf"},
            {"John", "Doe",
            "Rowing", new Integer(3), new Boolean(true),"reytry"},
            {"Sue", "Black",
            "Knitting", new Integer(2), new Boolean(false),"wwttu"},
            {"Jane", "White",
            "Speed reading", new Integer(20), new Boolean(true),"yuiyio"},
            {"Joe", "Brown",
            "Pool", new Integer(10), new Boolean(false),"ertey"}
    };
}
    public int getColumnCount() {
        return columnNames.length;
    }

    public int getRowCount() {
        return data.length;
    }

    public String getColumnName(int col) {
        return columnNames[col];
    }

    public Object getValueAt(int row, int col) {
        return data[row][col];
    }

    /*
     * JTable uses this method to determine the default renderer/
     * editor for each cell.  If we didn't implement this method,
     * then the last column would contain text ("true"/"false"),
     * rather than a check box.
     */
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

    public boolean isCellEditable(int row, int col) {
        //Note that the data/cell address is constant,
        //no matter where the cell appears onscreen.
        if (col < 2) {
            return false;
        } else {
            return true;
        }
    }

    public void setValueAt(Object value, int row, int col) {
        if (DEBUG) {
            System.out.println("Setting value at " + row + "," + col
                               + " to " + value
                               + " (an instance of "
                               + value.getClass() + ")");
        }

        data[row][col] = value;
        this.fireTableCellUpdated(row,col);

        if (DEBUG) {
            System.out.println("New value of data:");
            printDebugData();
        }
    }

    private void printDebugData() {
        int numRows = getRowCount();
        int numCols = getColumnCount();

        for (int i=0; i < numRows; i++) {
            System.out.print("    row " + i + ":");
            for (int j=0; j < numCols; j++) {
                System.out.print("  " + data[i][j]);
            }
            System.out.println();
        }
        System.out.println("--------------------------");
    }
}

/**
 * Create the GUI and show it.  For thread safety,
 * this method should be invoked from the
 * event-dispatching thread.
 */
private static void createAndShowGUI() {
    //Create and set up the window.
    JFrame frame = new JFrame("TableFTFEditDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //Create and set up the content pane.
    TableFTFEditDemo newContentPane = new TableFTFEditDemo();
    newContentPane.setOpaque(true); //content panes must be opaque
    frame.setContentPane(newContentPane);

    //Display the window.
    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
}
void runtable(){

    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
            tableModel.setValueAt(new Integer(5),2,5); 
     ((AbstractTableModel)table.getModel()).fireTableCellUpdated(2,5);
        }
    });
}
 /** using this to call setValueAt from other classes*/
public void setValueAt1(Object value, int row, int col) {
     table.setValueAt(new Integer(5),row,col); 
     ((AbstractTableModel)table.getModel()).fireTableCellUpdated(row,col);   
    }
 }

PS: the code is taken frm oracle' example..i just want to knw how to reflect the changes made in tablemodel in the table.


Solution

  • Your code works as expected, just you do not actually call setValueAt() on your model. Your runtable() method where you do is never invoked.

    To verify, change createAndShowGUI() to return the newContentPane and use the following main:

        static TableFTFEditDemo instance;
    
        public static void main(String[] args) throws Exception {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                instance = createAndShowGUI();
            }
        });
        Thread.sleep(5000);
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                instance.tableModel.setValueAt(5, 2, 5);
            }
        });
    }
    

    Screen shot

    After the programmed five second delay, the value in column 2 row five will change from "wwtu" into "5".