0

Hi I'm building an application using a JTable to display data from a database and I keep getting an IndexOutOfBoundException from tableModel.getValueAt(row,col) during painting. I debugged the code and it seems like the data isn't being saved to the DefaultTableModels data vector.

This is my code...

    public class TableFrame extends JFrame{
        public static void main(String[] args){
            TableFrame frame = new TableFrame();

        }

        private TablePanel tablePanel;
        public TableFrame(){
            super();
            setSize(new Dimension(500,500));
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            tablePanel = new TablePanel();
            add(tablePanel);

            updateLabels();
            setVisible(true);
        }

        public void updateLabels() {
            setTitle("Main Frame");

            tablePanel.updateLabels();
        }

        private static class TablePanel extends JPanel{

            private DefaultTableModel tableModel;
            private DefaultTableColumnModel colModel;
            private JTable table;

            private JPanel buttonPanel;
            private JButton refreshButton;

            public TablePanel(){
                setLayout(new BorderLayout());

        buttonPanel = new JPanel(new FlowLayout());
        refreshButton = new JButton();
        refreshButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                refreshData();
            }
        });
        buttonPanel.add(refreshButton);
        add(buttonPanel,BorderLayout.NORTH);

        //TODO:Set the column renderers and editors
        colModel = new DefaultTableColumnModel();
        colModel.addColumn(new TableColumn(0,75));
        colModel.addColumn(new TableColumn(0,75));
        colModel.addColumn(new TableColumn(0,75));
        colModel.addColumn(new TableColumn(0,75));
        colModel.addColumn(new TableColumn(0,75));
        colModel.addColumn(new TableColumn(0,75));
        colModel.addColumn(new TableColumn(0,75));
        colModel.addColumn(new TableColumn(0,75));
        colModel.addColumn(new TableColumn(0,75));
        colModel.addColumn(new TableColumn(0,75));
        colModel.addColumn(new TableColumn(0,75));

        tableModel = new DefaultTableModel();

        table = new JTable(tableModel,colModel);

        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane,BorderLayout.CENTER);

        updateLabels();
    }

    //This is going to query data from a database and populate the table
    //problem occurs during painting
    public void refreshData(){
        Random rand = new Random();

        for(int i=0;i<1000;i++){
            Vector<Object> fields = new Vector<Object>();
            for(int j=1;j<=11;j++){
                fields.add(rand.nextInt());
            }
            tableModel.addRow(fields);
        }
    }

    public void updateLabels() {
        colModel.getColumn(0).setHeaderValue("Col 1");
        colModel.getColumn(1).setHeaderValue("Col 2");
        colModel.getColumn(2).setHeaderValue("Col 3");
        colModel.getColumn(3).setHeaderValue("Col 4");
        colModel.getColumn(4).setHeaderValue("Col 5");
        colModel.getColumn(5).setHeaderValue("Col 6");
        colModel.getColumn(6).setHeaderValue("Col 7");
        colModel.getColumn(7).setHeaderValue("Col 8");
        colModel.getColumn(8).setHeaderValue("Col 9");
        colModel.getColumn(9).setHeaderValue("Col 10");
        colModel.getColumn(10).setHeaderValue("Col 11");

                refreshButton.setText("Refresh");

                repaint();
            }
        }
    }

This is the exception...

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
at java.util.Vector.elementAt(Vector.java:447)
at TableFrame$TablePanel.refreshData(TableFrame.java:108)
at TableFrame$TablePanel$1.actionPerformed(TableFrame.java:64)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2012)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2335)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:404)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6268)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6033)
at java.awt.Container.processEvent(Container.java:2045)
at java.awt.Component.dispatchEventImpl(Component.java:4629)
at java.awt.Container.dispatchEventImpl(Container.java:2103)
at java.awt.Component.dispatchEvent(Component.java:4455)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4633)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4297)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4227)
at java.awt.Container.dispatchEventImpl(Container.java:2089)
at java.awt.Window.dispatchEventImpl(Window.java:2517)
at java.awt.Component.dispatchEvent(Component.java:4455)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:649)
at java.awt.EventQueue.access$000(EventQueue.java:96)
at java.awt.EventQueue$1.run(EventQueue.java:608)
at java.awt.EventQueue$1.run(EventQueue.java:606)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:116)
at java.awt.EventQueue$2.run(EventQueue.java:622)
at java.awt.EventQueue$2.run(EventQueue.java:620)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:619)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:138)

I debugged the code and added a call to tableModel.getDataVector().getElementAt(0).getElementAt(0) and tableModel.getRowCount(). getRowCount() returned 1000 but getElementAt() resulted in the IndexOutOfBounds exception, just like in the awt event queue. I think what I did should work but obviously there's something I'm missing.

wattostudios
  • 8,666
  • 13
  • 43
  • 57
Marcipicus
  • 11
  • 4
  • 1
    The exception tells you where it happens exactly (line 108 of TableFrame.java), but it doesn't tell us because the code throwing the exception is not the code you pasted here: `refreshData()` never calls `Vector.getElementAt()`. – JB Nizet Jun 05 '12 at 14:07
  • I can't answer post the whole stack trace but here's the topException in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0 at java.util.Vector.elementAt(Vector.java:447) at javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:650) at javax.swing.JTable.getValueAt(JTable.java:2719) at javax.swing.JTable.prepareRenderer(JTable.java:5719) at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2108) at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2010) – Marcipicus Jun 05 '12 at 19:15
  • Just figured it out. I never called tableModel.setColumnCount() so the tableModel justified the data to the number of columns it knew about. I thought the tableModel had knowledge about the column model but apparently it doesn't. I'm not allowed to post an answer for the next two hours but I'll do so as soon as I'm allowed.Thanks for checking out the question JB. – Marcipicus Jun 05 '12 at 19:27

1 Answers1

1

The TableModel doesn't refer to the ColumnModel to get the number of columns so this has to be set using tableModel.setColumnCount(). Otherwise the defaultTableModel justifies the data and truncates the row to the number retreived by getColumnCount().

Botz3000
  • 39,020
  • 8
  • 103
  • 127
Marcipicus
  • 11
  • 4