2

i have one jtable with listselectionlistener i can dynamically added the new rows in to my table,when i select the row the selected row content will be appear in text box i can able to edit and remove the data ,for my application i stored the table data into xml file,when i add new row,that will be added into table successfully. but when i select a row and update means table doesn't get update(here i call load table()).( but updated values changed in xml file correctly) this my sample code for creating table*

    ListSelectionModel selectionModel;
    JTable table1;
    model = new DefaultTableModel();
    table = new JTable(model);       table.setRowHeight(20);
    selectionModel = table.getSelectionModel();                  
    selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

 selectionModel.addListSelectionListener(new ListSelectionListener() {
        public void valueChanged(ListSelectionEvent e) {

            stxtBox.setText("");
            ptxtBox.setText("");
            ntxtBox.setText("");

            if (!e.getValueIsAdjusting()) {



             model1 = table.getSelectionModel();
                int lead = model1.getLeadSelectionIndex();
                int columns = table.getColumnCount();
                String sip = "";
                String sport = "";
                String snoq = "";
                for (int col = 0; col < columns; col++) {
                    Object o = table.getValueAt(lead, col);

                    if (col == 0) {
                        sip += o.toString();
                        stxtBox.setText(sip);
                        selectedip = sip;

                    } else if (col == 1) {

                        sport += o.toString();
                        ptxtBox.setText(sport);
                        selectedport = sport;
                    } else {

                        snoq += o.toString();
                        ntxtBox.setText(snoq);
                    }
                    selectedreq = snoq;

                }



            }table.clearSelection();
        }
    });

i load the table content like this

  int rowCount=0;

            File file = new File("serverconfig.xml");

            if (file.exists())

            {

                System.out.print("in load");
                int e = table.getRowCount();

                if(e> 0)
                {

                while (table.getRowCount() > 0) {
                    ((DefaultTableModel) table.getModel()).removeRow(0);
                }

                }

//here i will load table content from my xml file (that's working fine)

the problem is when i update my table content i will call loadtable() function ever time i will get this error

java.lang.ArrayIndexOutOfBoundsException: 1 >= 1
    at java.util.Vector.elementAt(Unknown Source)
    at javax.swing.table.DefaultTableModel.getValueAt(Unknown Source)
    at javax.swing.JTable.getValueAt(Unknown Source)
    at Testsample$18.valueChanged(Testsample.java:1810)
    at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
    at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
    at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
    at javax.swing.DefaultListSelectionModel.insertIndexInterval(Unknown Source)
    at javax.swing.JTable.tableRowsInserted(Unknown Source)
    at javax.swing.JTable.tableChanged(Unknown Source)
    at javax.swing.table.AbstractTableModel.fireTableChanged(Unknown Source)
    at javax.swing.table.AbstractTableModel.fireTableRowsInserted(Unknown Source)
    at javax.swing.table.DefaultTableModel.insertRow(Unknown Source)
    at javax.swing.table.DefaultTableModel.addRow(Unknown Source)
    at javax.swing.table.DefaultTableModel.addRow(Unknown Source)
    at Testsample.loadtable(Testsample.java:577)
    at Testsample$10.actionPerformed(Testsample.java:1551)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
Mr.Cool
  • 1,525
  • 10
  • 32
  • 51

4 Answers4

8

The old story: if there's high-level api to reach a goal, never-ever use the lower-level. Or maybe a related story: read the api doc, again and again :-)

For DefaultTableModel, the high-level api to remove all rows is:

model.setRowCount(0); 

Edit

Looking at your stacktrace, the error is not caused by the remove, but by accessing a newly added row.. My (random, without seeing more or your code :-) guess would be the rowIndex lead in

Object o = table.getValueAt(lead, col);

you'll have to check if its valid, might be negative (no lead) or still the old (index before adding) Note that the selection state is updated as a consequence of adding/removing data in the tableModel (as well as by user interaction) The important rule here is to be sure that table's internals are updated after model changes before accessing any state in client code. You can do so by wrapping it in invokeLater:

void updateTextBox() {
    if (selectionModel.getLeadSelectionIndex() >= table.getRowCount() ||
        selectionModel.getLeadSelectionIndex() < 0) return;
    .... // update text panel here
}

public void valueChanged(...) {
    if (e.getValueIsAdjusting()) return;
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
           updateTextBox();
        }
    }));
}
kleopatra
  • 51,061
  • 28
  • 99
  • 211
5

for example

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.table.*;

public class RemoveAddRows extends JFrame {

    private static final long serialVersionUID = 1L;
    private Object[] columnNames = {"Type", "Company", "Shares", "Price"};
    private Object[][] data = {
        {"Buy", "IBM", new Integer(1000), new Double(80.50)},
        {"Sell", "MicroSoft", new Integer(2000), new Double(6.25)},
        {"Sell", "Apple", new Integer(3000), new Double(7.35)},
        {"Buy", "Nortel", new Integer(4000), new Double(20.00)}
    };
    private JTable table;
    private DefaultTableModel model;

    public RemoveAddRows() {

        model = new DefaultTableModel(data, columnNames) {

            private static final long serialVersionUID = 1L;

            @Override
            public Class getColumnClass(int column) {
                return getValueAt(0, column).getClass();
            }
        };
        table = new JTable(model) {

            private static final long serialVersionUID = 1L;

            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                Component c = super.prepareRenderer(renderer, row, column);
                int firstRow = 0;
                int lastRow = table.getRowCount() - 1;
                int width = 0;
                if (row == lastRow) {
                    ((JComponent) c).setBackground(Color.red);
                } else if (row == firstRow) {
                    ((JComponent) c).setBackground(Color.blue);
                } else {
                    ((JComponent) c).setBackground(table.getBackground());
                }
                /*if (!isRowSelected(row)) {
                String type = (String) getModel().getValueAt(row, 0);
                c.setBackground("Buy".equals(type) ? Color.GREEN : Color.YELLOW);
                }
                if (isRowSelected(row) && isColumnSelected(column)) {
                ((JComponent) c).setBorder(new LineBorder(Color.red));
                }*/
                return c;
            }
        };
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane);
        JButton button1 = new JButton("Remove all rows");
        button1.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {
                if (model.getRowCount() > 0) {
                    for (int i = model.getRowCount() - 1; i > -1; i--) {
                        model.removeRow(i);
                    }
                }
                System.out.println("model.getRowCount() --->" + model.getRowCount());
            }
        });
        JButton button2 = new JButton("Add new rows");
        button2.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {
                Object[] data0 = {"Buy", "IBM", new Integer(1000), new Double(80.50)};
                model.addRow(data0);
                Object[] data1 = {"Sell", "MicroSoft", new Integer(2000), new Double(6.25)};
                model.addRow(data1);
                Object[] data2 = {"Sell", "Apple", new Integer(3000), new Double(7.35)};
                model.addRow(data2);
                Object[] data3 = {"Buy", "Nortel", new Integer(4000), new Double(20.00)};
                model.addRow(data3);
                System.out.println("model.getRowCount() --->" + model.getRowCount());
            }
        });
        JPanel southPanel = new JPanel();
        southPanel.add(button1);
        southPanel.add(button2);
        add(southPanel, BorderLayout.SOUTH);
    }

    public static void main(String[] args) {
        RemoveAddRows frame = new RemoveAddRows();
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • 1
    you don't need the if block around the loop removing - with rowCount == 0 it wouldn't start anyway :-) – kleopatra Jul 25 '12 at 08:45
0

this will do the task

DefaultTableModel dm = (DefaultTableModel)table.getModel();
dm.getDataVector().removeAllElements();
dm.fireTableDataChanged();

for this to work you need to create table like this

String[] columnNames = {"First Name",
            "Last Name",
            "Sport",
            "# of Years",
            "Vegetarian"};

Object[][] data = {
{"Kathy", "Smith",
"Snowboarding", new Integer(5), new Boolean(false)},
{"John", "Doe",
"Rowing", new Integer(3), new Boolean(true)},
};

JTable jTable = new JTable();
jTable.setModel(new DefaultTableModel(data,columnNames));
sunil
  • 6,444
  • 1
  • 32
  • 44
  • -1 no: never-ever change the data structure under the feet of the model - even though you at least _fired_ an event (though not the correct which would be rowsRemoved). – kleopatra Jul 25 '12 at 08:43
0

It's very easy: just do this:

DefaultTableModel model = (DefaultTableModel)table.getModel();

while(model.getRowCount() > 0){
   for(int i = 0 ; i < model.getRowCount();i++){
      model.removeRow(i);
   }
}
Mihai8
  • 3,113
  • 1
  • 21
  • 31
Peter
  • 6,509
  • 4
  • 30
  • 34
  • looping is wrong in itself (because there's api to removeAll), nesting loops (when a single done correctly will suffice) is just ... weird – kleopatra Aug 07 '13 at 15:33
  • The fact that there's api to removeAll does not make the looping wrong. – Peter Aug 07 '13 at 15:45
  • 1
    it's wrong because it's polluting the code space with unnecessary code: each and every maintainer of that code will scratch their head and try to find the hidden reason why you didn't do it straightaway .. failing to find it, they will not touch it and - what is worse - even copy it elsewhere. – kleopatra Aug 07 '13 at 16:15
  • The `for` goes in the wrong direction: you'll be removing row 0 so row 1 will become row 0, but then `i++` so you'll remove row 2, etc. I guess that's why you added the extra `while`... Use a reverse `for` loop like @mKorbel did in his example, or, better yet, use `removeAll()` as ever-wise @kleopatra suggested ;) – Matthieu Aug 10 '13 at 17:59
  • 1
    @Matthieu repeating (my answer, the comment was a bit off the head :-) just for the record: the api for "rmoveAll" is a bit unintuively ... `setRowCount(0)` :-) – kleopatra Aug 10 '13 at 20:51
  • ... and I can't edit my comment anymore to correct. Thanks anyway! – Matthieu Aug 11 '13 at 03:27