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!