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.
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(...)"`