/** * TableDemo is just like SimpleTableDemo, except that it * uses a custom TableModel. */ public class TableDemo extends JPanel { private JButton looper; JTable table; MyTableModel mdl; private static JFrame frame; public TableDemo() { super(new GridLayout(2,0)); looper = new JButton(); looper.setText("Hit Me to loop thru table and flip vegetarian preference"); looper.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(java.awt.event.ActionEvent evt) { HitButtonActionPerformed(evt); } }); mdl = new MyTableModel(); table = new JTable(mdl); table.setPreferredScrollableViewportSize(new Dimension(500, 70)); table.setFillsViewportHeight(true); //Create the scroll pane and add the table to it. JScrollPane scrollPane = new JScrollPane(table); //Add the scroll pane to this panel. add(scrollPane); //add button add(looper); } public void HitButtonActionPerformed(ActionEvent e) { for (int row=0; row<table.getRowCount();row++) { try { Thread.currentThread().sleep(1000);//sleep for 1000 ms System.out.println("one more flip"); Object p = table.getValueAt(row, 4); table.setValueAt( !((Boolean)p), row, 4); /* no hope ( (AbstractTableModel)table.getModel()).fireTableCellUpdated(row, 4); mdl.fireTableCellUpdated(row, 4); mdl.fireTableDataChanged(); table.validate(); frame.repaint(); */ } catch (InterruptedException ex) { Logger.getLogger(TableDemo.class.getName()).log(Level.SEVERE, null, ex); } } } class MyTableModel extends AbstractTableModel { private String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"}; private Object[][] data = { {"Kathy", "Smith","Snowboarding", new Integer(5), false}, {"John", "Doe","Rowing", new Integer(3), true}, {"Sue", "Black", "Knitting", new Integer(2), false}, {"Jane", "White", "Speed reading", new Integer(20), true}, {"Joe", "Brown","Pool", new Integer(10), false} }; @Override public int getColumnCount() { return columnNames.length; } @Override public int getRowCount() { return data.length; } @Override public String getColumnName(int col) { return columnNames[col]; } @Override 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. */ @Override public Class getColumnClass(int c) { return getValueAt(0, c).getClass(); } /* * Don't need to implement this method unless your table's * editable. */ @Override 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; } } /* * Don't need to implement this method unless your table's * data can change. */ @Override public void setValueAt(Object value, int row, int col) { data[row][col] = value; fireTableCellUpdated(row, col); } } /** * 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. frame = new JFrame("TableDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create and set up the content pane. TableDemo newContentPane = new TableDemo(); 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(); } }); } }