1

I have written the following function which i can use to can remove the rows from the DefaultTableModel:

private static void removeTableRows(JTable tableToClear){
    DefaultTableModel defaultModel = 
            (DefaultTableModel) tableToClear.getModel();
    int rows = defaultModel.getRowCount();

      while(rows>0) {
         defaultModel.removeRow(0);
      }
      String[] test = {"a","b","c"};
     defaultModel.addRow(test);
}

which throws the following exception:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
    at java.util.Vector.elementAt(Vector.java:427)
    at javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:632)
    at org.swx.nursing.tools.gui.DefaultTableGui$2.tableChanged(DefaultTableGui.java:217)
    at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:280)
    at javax.swing.table.AbstractTableModel.fireTableRowsDeleted(AbstractTableModel.java:245)
    at javax.swing.table.DefaultTableModel.removeRow(DefaultTableModel.java:447)
    at org.swx.nursing.tools.gui.DefaultTableGui.removeTableRows(DefaultTableGui.java:357)
    at org.swx.nursing.tools.gui.DefaultTableGui.actionPerformed(DefaultTableGui.java:330)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
    at java.awt.Component.processMouseEvent(Component.java:6297)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3275)
    at java.awt.Component.processEvent(Component.java:6062)
    at java.awt.Container.processEvent(Container.java:2039)
    at java.awt.Component.dispatchEventImpl(Component.java:4660)
    at java.awt.Container.dispatchEventImpl(Container.java:2097)
    at java.awt.Component.dispatchEvent(Component.java:4488)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4575)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4236)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4166)
    at java.awt.Container.dispatchEventImpl(Container.java:2083)
    at java.awt.Window.dispatchEventImpl(Window.java:2489)
    at java.awt.Component.dispatchEvent(Component.java:4488)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:674)
    at java.awt.EventQueue.access$400(EventQueue.java:81)
    at java.awt.EventQueue$2.run(EventQueue.java:633)
    at java.awt.EventQueue$2.run(EventQueue.java:631)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
    at java.awt.EventQueue$3.run(EventQueue.java:647)
    at java.awt.EventQueue$3.run(EventQueue.java:645)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:644)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

The tablechanged method is overridden as follows:

 //Add table cell listener
    model.addTableModelListener(new TableModelListener(){

        public void tableChanged(TableModelEvent e) {
             int row = e.getFirstRow();
             int col = e.getColumn();
             TableModel tableModel = (TableModel)e.getSource();
             Object data = null ;

             try{
                 data = tableModel.getValueAt(row, col);
             } catch (Exception ex) {
                 LOGGER.error("Failed to access table data: "+ex.getMessage());
             }

             boolean ishotKeyColEmpty = tableModel.getValueAt(row, 0).toString().isEmpty();
             boolean ishTypeColEmpty = tableModel.getValueAt(row, 2).toString().isEmpty();     
             /*
              * If the Application path column is empty, then clear the contents from
              * the hotKey and Type cells for this row 
              * 
              */
             if(data != null 
                     && data.toString().equals("") 
                     && !ishotKeyColEmpty 
                     && !ishTypeColEmpty) {
                 tableModel.setValueAt("", row, 0);
                 tableModel.setValueAt("", row, 2);
             }      
        }
    });

I am not sure what is causing this exception..

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Rookie
  • 5,179
  • 13
  • 41
  • 65

1 Answers1

3

there are 2 problems in your code .

1)try to get values from none existing row/column - in modellistner.

2)continuously remove rows without stopping even when there are no more rows-in removeTableRows method


let me explain 2nd error first.

2) inside the while loop you are not update row count.you are getting row count but this while loop condition never become false.for example you have 3 rows and count is 3 now inside while loop you are checking (rows > 0) no matter how much time it loops it's always true so when loop runs 4th time you get a error because there is no more rows to remove. you have to recount the row count

change method to

DefaultTableModel defaultModel= (DefaultTableModel) tableToClear.getModel();
int rows = defaultModel.getRowCount();
while (rows > 0) {
       defaultModel.removeRow(0);
       rows = defaultModel.getRowCount(); // this is very important
}
String[] test = {"a", "b", "c"};
defaultModel.addRow(test);


note:

you can use method defaultModel.RowCount(0); method to remove all rows .you don't need to do it using a loop

1) make sure row and col is 0 or more than it .because those can be -1 when they doesn't exist.then you will get lot of errors

so this line is important

 (row >= 0 && col >= 0){}

and also here

boolean ishotKeyColEmpty = tableModel.getValueAt(row, 0).toString().isEmpty();

you have to safely check getValueAt(row, 0) is not null before call toString().isEmpty() method. in your

complete code

addTableModelListener(new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent e) {

                int row = e.getFirstRow();
                int col = e.getColumn();
                TableModel tableModel = (TableModel) e.getSource();
                Object data = null;

                try {
                    if (row >= 0 && col >= 0) {
                        data = tableModel.getValueAt(row, col);

                        boolean ishotKeyColEmpty = false;
                        boolean ishTypeColEmpty = false;
                        if (tableModel.getValueAt(row, 0) != null) {
                            ishotKeyColEmpty = tableModel.getValueAt(row, 0).toString().isEmpty();
                        }
                        if (tableModel.getValueAt(row, 2) != null) {
                            ishTypeColEmpty = tableModel.getValueAt(row, 2).toString().isEmpty();
                        }

                        if (data != null && data.toString().equals("") && !ishotKeyColEmpty && !ishTypeColEmpty) {
                            tableModel.setValueAt("", row, 0);
                            tableModel.setValueAt("", row, 2);
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }

            }

        }
Madhawa Priyashantha
  • 9,633
  • 7
  • 33
  • 60
  • 1
    Thanks a lot for explaining this to me...worked like a charm! (and I have tried so many things to fix it :/) – Rookie Jul 02 '15 at 18:12
  • 1
    @Rookie good .but there was a problem in my side in previous answer .so i updated it. actually you should check `(row >= 0 && col >= 0)` in model listner.i updated code for model listner – Madhawa Priyashantha Jul 02 '15 at 18:52
  • let me explain 2nd error first. & change method to == DefaultTableModel.setRowCount(0) reseting all .. – mKorbel Jul 02 '15 at 19:17
  • @mKorbel what ?i don't get it – Madhawa Priyashantha Jul 02 '15 at 19:19
  • whats reason to avoids null value from XxxTableModel, I can't see any thats make me some sense – mKorbel Jul 02 '15 at 19:19
  • have you any issue to search about DefaultTableModel.setRowCount(0) – mKorbel Jul 02 '15 at 19:20
  • @mKorbel i stated it's easy to use `rowcount` than removing rows using that kind of method – Madhawa Priyashantha Jul 02 '15 at 19:22
  • or removin must be recrusive, by decreasing an index from max to zero imdex , have to accept that many array has the same problem with – mKorbel Jul 02 '15 at 19:24
  • @mKorbel `tableModel.getValueAt(row, 0)` can be null so if we call toString isempty there would be a nullpointer exception .isn't it?but of course it depend on how data add to the table . – Madhawa Priyashantha Jul 02 '15 at 19:26
  • by trying to put all together [override getValueAt](http://stackoverflow.com/a/17946486/714968) inside XxxTableModel [rather than ...](http://stackoverflow.com/questions/8099098/why-never-change-the-notifier-in-receiving-a-change-event), for null + isEmpty or "" to use some of attempts about ternary operator, btw JTables view hasn't some issue with null, empty – mKorbel Jul 02 '15 at 19:34
  • @mKorbel TNX FOR YOUR COMMENT .it will helps to op as well – Madhawa Priyashantha Jul 02 '15 at 19:40