0

My project is simple implementation of app like MC, NC or Total Commander. I use 2 JTables with custom model that extends AbstractTableModel and my problem is updating these tables with new data and size.

Whenever I try to update it with my method, I run into ArrayIndexOutOfBoundsException, altough I make sure to recreate my data array with new size, based off given arguments. Also, if I wait long enough, my table will indeed refresh properly but it's stuttering a lot, it's view is going crazy and it's overall unusable although it works in some weird, twisted way.

Here's my method that is supposed to refresh my Table's model:

public class TableModel extends AbstractTableModel { 

private SimpleDateFormat df2 = new SimpleDateFormat("dd/MM/yyyy HH:mm");
private String[] fieldNames = {"Name", "Extension", "Size", "Time"};
private Object[][] data;

public void UpdateTable(String path)
{
    File[] list = (new File(path).listFiles());

    data = new Object[list.length][fieldNames.length];

    for(int i=0; i<list.length;i++)
    {   
        data[i][0] = list[i].getName();
        if (FilenameUtils.getExtension(list[i].getPath()) == "")
        {
            data[i][1] = "<dir>";
        }
        else{
            data[i][1] = FilenameUtils.getExtension(list[i].getPath());
        }
        data[i][2] = list[i].length();
        data[i][3] = df2.format(new Date(list[i].lastModified()));
    }
}
[...]

And then part of MainFrame class, that is calling that method from within an actionListener.

TableModel model1 = new TableModel(listRoots()[0]);
JTable table = new JTable(model1);
table.setShowGrid(false);
table.setIntercellSpacing(new Dimension(0, 0));
table.setFillsViewportHeight(true);
table.getTableHeader().setReorderingAllowed(false);
JScrollPane scrollPane = new JScrollPane(table);
pane.add(scrollPane, c);

//combo box's actionListener. Is supposed to work like it does in totalCommander
combo.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        JComboBox cb = (JComboBox)e.getSource();
        model1.UpdateTable(cb.getSelectedItem().toString());
        model1.fireTableDataChanged();
        table.repaint();
    }   
});

I've already tried using "fireTableDataChanged()" in my update method or in SetValueAt(), but it didin't really help or change a thing.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
PlainLazy
  • 67
  • 1
  • 6

1 Answers1

3
model1.fireTableDataChanged();

Your application code should never invoke that method. It is the job of the custom TableModel to invoke the method

with custom model that extends AbstractTableModel

Then you have implemented a method incorrectly.

Why are you creating a custom model? There is nothing special about your model. You can just use the DefaultTableModel since is supports dynamic changes to the data.

Your updateTable(...) method could look something like:

setRowCount(0);

for (...)
{
    Vector row = new Vector();
    row.addElement(...);
    row.addElement(...);
    addRow( row );
}

So you first clear the data from the model and then you add the data back in one at a time. As each row is added the appropriate fireXXX method is automatically invoked.

You can extend the DefaultTableModel to add this method, or just have this as a method in your class.

Also, method names should NOT start with an upper case character. "UpdateTable(...)" should be "updateTable(...)"`

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Thanks a lot! Your suggestions did not fix the actual problem but did surely help me improve my code overall. For the record, problem happened to be connected to sorters, as they somehow bound both models, despite of creating actual JTables with different ones. I can now continue my work from that point, so thanks again! – PlainLazy May 14 '16 at 21:11