как удалить все строки в jtable?

у меня есть одна jtable с listselectionlistener, я могу динамически добавлять новые строки в свою таблицу, когда я выбираю строку, содержимое выбранной строки будет отображаться в текстовом поле, я могу редактировать и удалять данные, для моего приложения я сохранил таблицу данные в файл xml, когда я добавляю новую строку, которая будет успешно добавлена ​​в таблицу. но когда я выбираю строку и обновляю, это означает, что таблица не обновляется (здесь я вызываю загрузку таблицы ()). (но обновленные значения правильно изменены в файле xml) это мой пример кода для создания таблицы *

    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();
        }
    });

я загружаю содержимое таблицы следующим образом

  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)

проблема в том, что когда я обновляю содержимое своей таблицы, я буду вызывать функцию loadtable() каждый раз, когда я получаю эту ошибку

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)

person Mr.Cool    schedule 24.07.2012    source источник


Ответы (4)


Например

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);
    }
}
person mKorbel    schedule 24.07.2012
comment
вам не нужен блок if вокруг удаления цикла - с rowCount == 0 он все равно не запустится :-) - person kleopatra; 25.07.2012

Старая история: если для достижения цели есть высокоуровневый API, никогда не используйте низкоуровневый. Или, может быть, похожая история: читайте документацию по API снова и снова :-)

Для DefaultTableModel высокоуровневый API для удаления всех строк:

model.setRowCount(0); 

Изменить

Глядя на вашу трассировку стека, ошибка вызвана не удалением, а доступом к недавно добавленной строке. Мое (случайное, не видя больше или вашего кода :-) предположение было бы rowIndex lead в

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

вам нужно будет проверить, действительно ли он действителен, может быть отрицательным (без свинца) или все еще старым (индексировать перед добавлением). Обратите внимание, что состояние выбора обновляется как следствие добавления/удаления данных в tableModel (а также пользователем взаимодействие) Важным правилом здесь является убедиться, что внутренние компоненты таблицы обновляются после изменения модели, прежде чем обращаться к какому-либо состоянию в клиентском коде. Вы можете сделать это, обернув его в 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();
        }
    }));
}
person kleopatra    schedule 25.07.2012

это сделает задачу

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

чтобы это работало, вам нужно создать таблицу, подобную этой

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));
person sunil    schedule 24.07.2012
comment
-1 нет: никогда не меняйте структуру данных под ногами модели - даже если вы хотя бы запустили событие (хотя и не правильное, которое будет rowsRemoved). - person kleopatra; 25.07.2012

Это очень просто: просто сделайте это:

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

while(model.getRowCount() > 0){
   for(int i = 0 ; i < model.getRowCount();i++){
      model.removeRow(i);
   }
}
person Peter    schedule 20.09.2012
comment
зацикливание само по себе неправильно (потому что есть API для удаленияВсе), вложенные циклы (когда одного правильно выполненного будет достаточно) просто... странно - person kleopatra; 07.08.2013
comment
Тот факт, что есть API для удаленияВсех, не делает зацикливание неправильным. - person Peter; 07.08.2013
comment
это неправильно, потому что это загрязняет кодовое пространство ненужным кодом: каждый мейнтейнер этого кода будет чесать затылок и пытаться найти скрытую причину, почему вы не сделали этого сразу ... не найдя ее, они не будут ее трогать и, что еще хуже, даже скопируйте его в другом месте. - person kleopatra; 07.08.2013
comment
for идет в неправильном направлении: вы удалите строку 0, чтобы строка 1 стала строкой 0, но затем i++, чтобы удалить строку 2 и т. д. Думаю, поэтому вы добавили дополнительные while... Используйте обратный цикл for, как это сделал @mKorbel в своем примере, или, что еще лучше, используйте removeAll(), как всегда мудрый @kleopatra предложил;) - person Matthieu; 10.08.2013
comment
@Matthieu повторяет (мой ответ, комментарий был немного неуместным :-) просто для протокола: API для rmoveAll немного неинтуитивно ... setRowCount(0) :-) - person kleopatra; 11.08.2013
comment
... и я больше не могу редактировать свой комментарий, чтобы исправить. Спасибо, в любом случае! - person Matthieu; 11.08.2013