[Resolvido] Problemas ao excluir linhas selecionadas em Jtable com AbstractTableModel

Olá pessoal!

Estou recebendo o erro abaixo ao excluir linhas selecionadas em uma jtable, além de não excluir corretamente as linhas a qual seleciono, tudo ocorre certo quando excluo apenas uma linha.
Minha jtable é alimentada pelos dados digitados nela, aqual são salvos no banco de dados. Utilizo um KeyEvent em minha jtable para quando quiser apagar alguma linha, aperto a tecla DELETE.
utilizo AbstractTableModel a qual estou postando aqui para verificação.


Exception in thread “AWT-EventQueue-0” java.lang.IndexOutOfBoundsException: Index: 2, Size: 1
at java.util.ArrayList.rangeCheck(ArrayList.java:604)
at java.util.ArrayList.get(ArrayList.java:382)
at sms.ClienteModel.setValueAt(ClienteModel.java:72)
at javax.swing.JTable.setValueAt(JTable.java:2744)
at javax.swing.JTable.editingStopped(JTable.java:4726)
at javax.swing.AbstractCellEditor.fireEditingStopped(AbstractCellEditor.java:141)

TableModel:

import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;
  
  public class ClienteModel extends AbstractTableModel {   
  
      // Lista que vai conter todos os dados do JTable   
      private List<ClienteBean> dataset;   
      // Constante que defini o nome das colunas   
      private static final String[] col = {"Celular", "Nome", "Nascimento", "Campo Extra"};   
      
      // Construtor da classe recebe os dados a ser populado   
      public ClienteModel(List<ClienteBean> bean) {   
          dataset = new ArrayList<ClienteBean>(bean);   
          fireTableStructureChanged();   
      }   
         
      // Método sobrescrito que retorna o número de linhas do JTable, após populado   
      @Override   
      public int getRowCount() {   
          return dataset.size();   
      }   
  
      // Método sobrescrito que retorna o número de colunas do JTable após populado   
      @Override   
      public int getColumnCount() {   
         return col.length;   
      }   
  
      // Método sobrescrito que vai popular e retornar cada célula do JTable   
      @Override   
      public Object getValueAt(int rowIndex, int columnIndex) {   
           ClienteBean cbean = dataset.get(rowIndex);   
           		switch (columnIndex) {
                case 0: // Primeira coluna é o nome.
			return cbean.getCod();
		case 1: // Primeira coluna é o nome.
			return cbean.getNome();
		case 2: // Terceira coluna é a data de cadastro.
			return cbean.getIdade();
		case 3: // Quarta coluna é a mensalidade.
			return cbean.getExtra();

		default:
			// Se o índice da coluna não for válido, lança um
			// IndexOutOfBoundsException (Exceção de índice fora dos limites).
			// Não foi necessário verificar se o índice da linha é inválido,
			// pois o próprio ArrayList lança a exceção caso seja inválido.
			throw new IndexOutOfBoundsException("columnIndex out of bounds");

               } 
      }   
         
       /* Este método sobrescrito, defini se o JTable será editável ou não.  
           Voce pode definir qual coluna de qual linha será editável. Caso voce  
            defina que o seu JTable seja editável, então é necessário definir também  
           o método "setValueAt" que vem logo a seguir,  caso contrário, é só retornar  
           false para todas as linhas e colunas, como definido abaixo. */   
      @Override   
      public boolean isCellEditable(int rowIndex, int columnIndex){   
          return true;   
      }   
         
      /* Este método sobrescrito, permite voce editar o JTable, caso o método anterior  
          tenha algumas colunas de algumas ou todas linhas editáveis setadas para true,  
          ou que tenha como retorno o valor true para todas as linhas e colunas. */   
      @Override         
      public void setValueAt(Object value, int row, int col) {   
          ClienteBean dado = dataset.get(row);   
          switch (col){   
               case 0: dado.setCod((String)value); break;   
               case 1: dado.setNome((String)value); break;   
               case 2: dado.setIdade((String)value); break;
               case 3: dado.setExtra((String)value); break;
          }   
           fireTableDataChanged();    
       }   
  
      // Este método sobrescrito defini que tipo de dado será retornado para cada coluna   
      @Override   
      public Class getColumnClass(int column){   
           if (column == 0 || column == 2) {   
               return String.class;   
           } else {   
               return String.class;   
           }   
      }   
  
    /* Este método criado por nós, vai retornar o conjunto  
        de dados inteiro do JTable, através de um List contendo  
        Objetos ClienteBean populados. */   
    public List<ClienteBean> getDataSet(){   
       return dataset;   
    }   
       
    /* Este método sobrescrito vai definir o nome das colunas  
        que foi atribuído na constante "col" logo no início da classe */   
    @Override   
    public String getColumnName(int column){   
        return col[column];   
    }   
  
    /* Este método foi criado por nós para retornar um objeto ClienteBean  
        populado, de acordo com o número de linha do JTable fornecido pelo  
        parâmetro "int row" */   
    public ClienteBean getRow(int row) {   
         return dataset.get(row);   
    }   
       
    /* Este método criado por nós, serve para voce criar um  
        ClienteBean e populá-lo fora do JTable e passar para este  
        método que vai acrescentar os dados na última linha do JTable  
        sem que haja a necessidade de se usar o método "setValueAt(...)" */   
    public void addRow(ClienteBean bean){   
        dataset.add(bean);   
        fireTableDataChanged();   
    }   
  
    /* Este método foi criado por nós para remover uma linha  
        específica do JTable, de acordo com linha fornecida pelo  
        parâmetro "int row" */   
    public void removeRow(int row) {   
         dataset.remove(row);   
         fireTableRowsDeleted(row, row);   
    }   
  public void removeSocio(ClienteBean bean) {
		// Remove o sócio da linha especificada.
		dataset.remove(bean);

		// Reporta a mudança. O JTable recebe a notificação
		// e se redesenha permitindo que visualizemos a atualização.
		 fireTableDataChanged();
	}

    /* Este método criado por nós, acrescenta uma linha em branco  
        no JTable, caso voce queira inserir dados diretamente no JTable  
        tem que chamar este método antes. */   
    public void addEmptyRow(){   
        dataset.add(new ClienteBean());   
        fireTableDataChanged();   
    }   
  
}  

Metodo KeyEvent para apagar linhas selecionadas ao clicar DELETE:

                    int selecionados[] = jTable2.getSelectedRows();
                    if (selecionados.length > 0) {
                        List<ClienteBean> bean = new ArrayList<ClienteBean>();

                        for (int i = 0; i < selecionados.length; i++) {
                            selecionados[i] = jTable2.convertRowIndexToModel(selecionados[i]);
                            bean.add(model.getRow(selecionados[i]));
                        }
                        for (ClienteBean p : bean) {
                          model.removeSocio(p);
                        }
                        
                    }

Agradeço muito pela ajuda!

ajuda ae pessoal :slight_smile:

:stuck_out_tongue: Descobri o problema !

não sei por que motivo, mais percebi que o problema acontece quando tendo deletar as linhas a partir do evento da tecla DELETE.
passei a função que deleta as linhas selecionas para um action de um Botão e apagou tudo sem problemas.

Que zica…não me pergunte porque não funciona com evento da tecla DELETE :shock:

Você poderia especificar o método jTable2.getSelectedRows(), não há menção do código dele acima, obrigado pela atenção.