AmiguelS
AmiguelS

Reputation: 855

Dynamical increase JTable size

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

Answers (1)

TT.
TT.

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

Related Questions