Reputation: 855
I have a matrix that is always square, and I made a JTable to display its contents. I need the JTable to adjust its number of rows/columns to match the matrix. The method I'm using adjusts the numbers of rows show on the table, but the number of columns stays the same. Why is that? And how should I do it then?
The code bellow is missing methods that are not relevant to this question. The matrix is being updated as it should be, I checked.
public class SomeClass{
TableModel tableModel = new AbstractTableModel() {
public int getColumnCount() {
return matrix.lines.size()+1;
}
public int getRowCount() {
return matrix.lines.size()+1;
}
public Object getValueAt(int row, int col) {
Object val = "+";
if(row == 0 && col == 0)
return " ";
if(row == 0) {
try {
val = matrix.lines.get(0).cells.get(col-1).nodeId;
} catch (Exception e){
val = "-";
}
return val;
}
if(col == 0) {
try {
val = matrix.lines.get(row-1).nodeId;
} catch (Exception e){
val = "-";
}
return val;
}
try {
val = (int)observer.nodeList.get(id).matrix.lines.get(row-1).cells.get(col-1).dist;
} catch (Exception e){
val = "-";
}
return val;
}
};
public void updateTable(){
//STUFF HERE
}
}
The updateTable
method is called after the matrix is updated. I have tried a couple of implementations for this method, with mixed results, presented below.
Implementation 1
public void updateTable(){
((AbstractTableModel) table.table.getModel()).fireTableDataChanged();
}
Result: The number of rows is updated, but the number of columns stays the same.
Implementation 2
public void updateTable(){
((AbstractTableModel) table.table.getModel()).fireTableStructureChanged();
}
Result: Works, most of the time... Both dimensions are updated, but an exception is thrown occasionally:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1 >= 1
at java.util.Vector.elementAt(Vector.java:474)
at javax.swing.table.DefaultTableColumnModel.getColumn(DefaultTableColumnModel.java:294)
at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2012)
at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1812)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
at javax.swing.JComponent.paintComponent(JComponent.java:780)
at javax.swing.JComponent.paint(JComponent.java:1056)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5210)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502)
at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
at javax.swing.JComponent._paintImmediately(JComponent.java:5158)
at javax.swing.JComponent.paintImmediately(JComponent.java:4969)
at javax.swing.RepaintManager$4.run(RepaintManager.java:831)
at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Upvotes: 2
Views: 120
Reputation: 16137
When you create a custom TableModel
extending AbstractTableModel
you are responsible for firing the proper TableModel
events (reference).
That means that when your matrix
is changed by adding/deleting columns, you should call fireTableStructureChanged
(from within the AbstractTableModel
subclass).
If the autoCreateColumnsFromModel
property of the JTable is true, the JTable
will discard any table columns that it had and reallocate default columns in the order they appear in the model.
That means that your updateTable method should read:
public void updateTable()
{
fireTableStructureChanged();
}
Upvotes: 1