1

I have a JTable in my GUI, which I wish to update dynamically. Associated to the Jtable is of course a TableModel, where I've extended the AbstractTableModel and overridden appropiate methods.

I have four methods for my JTable:

  • AddRow
  • CopySelectedRow
  • DeleteSelectedRow
  • DeleteAll

When I run either AddRow or CopySelectedRow the table is 'one update behind':

If I press newRow once, nothing happens visually.

If I press newRow twice, the first one is shown while the second isn't.

However, using deleteSelected or deleteAll updates the table when I click (i.e. not behind).

Extract of my TableModel class:

public class TableModel extends AbstractTableModel {

private List<String[]> data;

public TableModel() {
    data = new ArrayList<String[]>();
}

...

public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    data.get(rowIndex)[columnIndex] = aValue.toString();
    fireTableCellUpdated(rowIndex, columnIndex);
}

public void addRow(String[] aValue) {
    data.add(aValue);
    fireTableRowsInserted(data.size()-1, data.size()-1);
}

public void copyRow(int rowIndex) {
    addRow(data.get(rowIndex));
}

public void removeRow(int rowIndex) {
    data.remove(rowIndex);
    fireTableRowsDeleted(rowIndex, rowIndex);
}

And how I call them:

JButton newRow = new JButton("New row");
    newRow.addActionListener(new ActionListener() {
        // Handling newRow event
        public void actionPerformed(ActionEvent e) {
            tableModel.addRow(new String[]{"", "", "", "", "", "", "", "", "", "", ""});
        }
    });

    JButton copyRow = new JButton("Copy selected row");
    copyRow.addActionListener(new ActionListener() {
        // Handling copyRow event
        public void actionPerformed(ActionEvent e) {
            if (table.getSelectedRow() != -1) {
                tableModel.copyRow(table.getSelectedRow());
            }
        }
    });

    JButton deleteRow = new JButton("Delete selected row");
    deleteRow.addActionListener(new ActionListener() {
        // Handling deleteRow event
        public void actionPerformed(ActionEvent e) {
            if (table.getSelectedRow() != -1) {
                tableModel.removeRow(table.getSelectedRow());
            }
        }
    });

    JButton deleteAllRows = new JButton("Delete all rows");
    deleteAllRows.addActionListener(new ActionListener() {
        // Handling deleteAllRows event
        public void actionPerformed(ActionEvent e) {
            for (int i = tableModel.getRowCount() - 1; i >= 0; i--) {
                tableModel.removeRow(i);
            }
        }
    });

EDIT:

I chose to use an AbstractTableModel because I had the same problem with the DefaultTableModel (whenever I added a row, it wasn't added until the next was 'added'), and with an AbstractTableModel I would be able to fire change events myself. However, it didn't fix a thing. Can anyone please shed some light on my issue here? I'd be happy to elaborate more on the case, should anyone need some more information.

Harpunius
  • 120
  • 7

1 Answers1

0

A method

FireTableDataChanged(); 

detects any kind of alteration in table data object and update the GUI respectively, you can try that instead of

fireTableRowsInserted();
Haris Mehmood
  • 854
  • 4
  • 15
  • 26
  • wrong suggestion, fireTableDataChanged recreating model, you can lost all custom settings for renderer and editor – mKorbel Jul 07 '14 at 08:40
  • @mKorbel Since his code shows changes in rows only(i.e. Delete / copy / insert) and no in-column data editing, i think this will work just fine since the structure of the table (as in the order of the columns) is assumed to be the same in this method. http://docs.oracle.com/javase/7/docs/api/javax/swing/table/AbstractTableModel.html#fireTableDataChanged%28%29 If I am wrong and missing something please correct me. Thank you. – Haris Mehmood Jul 07 '14 at 08:49
  • Hi @haris, thanks for your answer. Whether or not it changes the structure, firing a tableDataChanged() instead of insert didn't work. – Harpunius Jul 07 '14 at 08:51
  • 2
    1. you are wrong, 2. btw fireTableRowsInserted(); is proper notifier for addRow for a new row is inserted to JTable, 3. nothing cleaver from OPs question, otherwise will be answered (SSCCE/MCVE, short, runnable, compilable, with harcoded valuse for XxxTableModel in local variable), because everything in this question aren't completed, just about guessing, ... – mKorbel Jul 07 '14 at 08:55
  • I don't fully understand your third point mKorbel, can you please elaborate? – Harpunius Jul 08 '14 at 15:50