Iniciar Tela com jtable vazio

Pessoal tenho um form com uma jtable, jtextfiel e botoes crud funcionando certinho, como essa tela está pronta zerei a tabela do bd e fui realizar o primeiro cadastro da tela e apresentou o seguinte erro ao abrir o form:

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0

sei que este erro é porque não tenho nada na tabela do bd, mas não estou sabendo como resolver isso…

alguém poderia me dar um help de como criar a lista vazia.

Obs: se realizo um cadastro direto no bd, tudo funciona…

aqui o metodo que carrega a tabela ao iniciar o form:

public void carregaTabela() throws SQLException {     
            ArrayList lista = (ArrayList) dao.selectAll();
            modeloTabela = new TableArroladoPor(lista);
            configuraTabela(modeloTabela);
    }

aqui meu dao.selectAll()

public List<ArroladoPor> selectAll() throws SQLException {
        List lista = new ArrayList();
        String select = "SELECT * From arroladoPor order by arr_descricao";
        try (PreparedStatement stmt = getConnection().prepareStatement(select);
                ResultSet rs = stmt.executeQuery()) {
            while (rs.next()) {
                ArroladoPor Obj = new ArroladoPor();
                Obj.setIdArrolado(rs.getInt("arr_codigo"));
                Obj.setDescricao(rs.getString("arr_descricao"));
                lista.add(Obj);
            }
        }
        return lista;
    }

Posta o fonte da classe TableArroladoPor

package Model.Table;

import Model.ArroladoPor;
import java.util.ArrayList;
import java.util.Collections;

/**
 *
 * @author Usuario
 */
public class TableArroladoPor extends TableModelPadrao {

    public TableArroladoPor(ArrayList linhas) {
        super(linhas);
    }
    
    
    

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        ArroladoPor a = (ArroladoPor) linhas.get(rowIndex);
        switch (columnIndex) {
            case 0:
                return a.getIdArrolado();
            case 1:
                return a.getDescricao();
            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("Numero de colunas no TableArroladoPor"
                        + " não é compativel com dados do banco");
        }
    }

    @Override
    protected String[] criarColunas() {
        return new String[]{"Id", "Descricão"};
    }

    @Override
    protected boolean[] colEditavel() {
        return new boolean[]{false, false};
    }

    @Override
    public void addRow(Object o) {
        this.linhas.add(o);
        Collections.sort (this.linhas);
        this.fireTableDataChanged();
        
    }

           
    @Override
    public void removeRow(int linha) {
        this.linhas.remove(linha);
        this.fireTableRowsDeleted(linha, linha);
        
    }

    @Override
    public void setValueAt(Object obj, int linha, int coluna) {
        ArroladoPor a = (ArroladoPor) linhas.get(linha);
        switch (coluna) {
//            case 0: // Primeira coluna é o codigo.
//                a.setIdArrolado(Integer.parseInt((String) obj));
//                break;
            case 1: // Segunda coluna é o descricao.
                a.setDescricao(obj.toString());
                break;
        }
        this.fireTableCellUpdated(linha, coluna);    
    }
    
    @Override
	public int getRowCount() {
		return linhas.size();
	}

	@Override
	public int getColumnCount() {
		return colunas.length;
	} 
}

Provavelmente o erro está nos seus métodos getValueAt e setValueAt, você tem que verificar se a linha recebida por parâmetro é maior ou igual a zero e menor que linhas.size() senão não tem como acessar aquela posição em sua sua lista.

Olá estava analisando sua ajuda, eu devo realizar essa verificação em que momento?

eu sei como fazer a verificação, mas não entendi onde e porquê aplica-la.

fiz isso, mas deu não deu…

 @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        ArroladoPor a = (ArroladoPor) linhas.get(rowIndex);
        if (rowIndex >= 0 && rowIndex < linhas.size()) {
            return null;
        } else {
            
            switch (columnIndex) {
                case 0:
                    return a.getIdArrolado();
                case 1:
                    return a.getDescricao();
                default:
                    throw new IndexOutOfBoundsException("Numero de colunas no TableArroladoPor"
                            + " não é compativel com dados do banco");
            }
        }
    }

Então, só um pouco de falta de atenção mesmo, veja:

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    ArroladoPor a = (ArroladoPor) linhas.get(rowIndex); // aqui você já está tentando acessar a posição que não existe
    if (rowIndex >= 0 && rowIndex < linhas.size()) {    // então o erro vai acontever antes de cair nesse teste

Faça assim:

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    if (rowIndex >= 0 && rowIndex < linhas.size()) { // primeiro testa
        ArroladoPor a = (ArroladoPor) linhas.get(rowIndex); // depois acessa
        switch (columnIndex) {
            case 0:
                return a.getIdArrolado();
            case 1:
                return a.getDescricao();
        }
    }
    return null;
}