Mensagem de Exceção ArrayIndexOutOfBoundsException

Olá, gostaria de uma ajuda.

Seguinte,
Estou com um problema de exceção que não consigo detectar aonde o java está disparando a mensagem de exceção.

Basicamente o que eu faço:

Eu tenho uma JTable, nessa JTable eu mostro apenas os “pedidos” que estão para chegar em um “estabelecimento”.
Depois, que o pedido chegar, o usuário irá lançar o pedido que chegou no estoque.

Então é, só é mostrado na JTable pedidos com “STATUS” de “Aguardando Entrega”, caso contrario ele não mostra.

Pois bem, vamos a situação:

Vamos supor que nessa Jtable tenho duas linhas.
E vamos ainda supor que o produto da linha 1, ou seja, linhas começam do 0, acabou de chegar, e o sujeito vai lançar no estoque. Aí eu faço um lançamento normal desse pedido.
Só que quando eu clico no botão de incluir no estoque esse pedido que não é mais “Aguardando Entrega”, ele não deve mais aparecer na minha jTable e esta fica apenas com 1 linha.
É nessa hora que aparece a mensagem de exceção.

Basicamente eu eu faço isso para incluir no estoque (Uso o swing worker) e depois chamo o carregamento da Jtable novamente. Segue

     private void start() {
        SwingWorker worker = new SwingWorker() {
        @Override
        protected Void doInBackground() throws Exception {
        // aqui dentro tem os códigos de inclusão no banco do estoque.

        // aqui tambem eu faço um try para carregar novamente a JTable, ou seja
       // só os dados com a coluna Status = "Aguardando entrega"
       try {
           startPedidos();
           System.out.println("Carregou Pedidos");
            } catch (Exception e) {
                System.out.println(e.toString());
            }
        }

        return null;
    }
};
  worker.execute();

}

private void startPedidos(){
    
    SwingWorker worker = new SwingWorker() {
        @Override
        protected Void doInBackground() throws Exception {
            try{
                MostrarTabelas mostrarBaseProdutosPedidos = new MostrarTabelas();
                TabelaPedidosTH model = new TabelaPedidosTH(mostrarBaseProdutosPedidos.lerTabelaDePedidosParaRecebimento());       
                lst_pedidos_em_andamento.setModel(model);
                lbl_contador_de_pedidos.setText("Registros em pedido: " + String.valueOf(lst_pedidos_em_andamento.getRowCount()));
            }catch(ArrayIndexOutOfBoundsException e){
                System.out.println("erro: " + e.toString());
            }
            return null;
        }
    };
  worker.execute();
}

Eu estou usando o abstract Table Model.

Segue meu abstract

public class TabelaPedidosTH extends AbstractTableModel{

private List<Pedidos> linhas = null;
private String[] colunas = new String[] {"ID_PEDIDO","PRODUTO", "DESCRIÇÃO", "UNID.", "FORNECEDOR", "QUANTIDADE", "DATA PEDIDO", "PREVISÃO DE CHEGADA", "VALIDADE (A)", "VALIDADE (B)", "STATUS PEDIDOS"};

public TabelaPedidosTH(List<Pedidos> pedidos) {
      this.linhas = pedidos;
}

public void setColunas(String[] colunas) {
    this.colunas = colunas;
}

public void setLinhas(ArrayList linhas) {
    this.linhas = linhas;
}

@Override
public int getRowCount() {
    return linhas.size();
}

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

public String[] getColunas() {
    return colunas;
}

@Override
public Object getValueAt(int rowIndex, int columIndex) {
    Pedidos p = null;
    p = linhas.get(rowIndex);
    switch(columIndex){
        case 0:
            return p.getId_pedido(); 
        case 1:
            return p.getNomeProdutoPedido();
        case 2:
            return p.getDescricaoProdutoPedido();
        case 3:
            return p.getUnidadeProdutoPedido();
        case 4:
            return p.getNomeFornecedorPedido();
        case 5:
            return p.getQuantidadePedido();
        case 6:
            return p.getDataPedido();
        case 7:
            return p.getPrevisaoChegadaPedido();
        case 8:
            return p.getValidadeAProduto();
        case 9:
            return p.getValidadeBProduto();
        case 10:
            return p.getStatuspedido();
        default:
            System.err.println("Índice inválido para propriedade");
    }
    return null;
}

public ArrayList getLinhas() {
    return (ArrayList) linhas;
}

@Override
public String getColumnName(int columnIndex){
    return colunas[columnIndex];
}  

public void limpar() {  
      linhas.clear();    
      fireTableDataChanged();  
}      

public void adicionar(Pedidos novo){
    linhas.add(novo);
    fireTableRowsInserted(linhas.size() - 1, linhas.size() - 1);
    fireTableDataChanged();
}

}

Essa é a mensagem de exceção:

   Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 9 >= 9
at java.util.Vector.elementAt(Vector.java:474)
at javax.swing.table.DefaultTableColumnModel.getColumn(DefaultTableColumnModel.java:294)
at javax.swing.plaf.basic.BasicTableUI.paintGrid(BasicTableUI.java:1973)
at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1809)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
at javax.swing.JComponent.paintComponent(JComponent.java:780)
at javax.swing.JComponent.paint(JComponent.java:1056)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5210)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502)
at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
at javax.swing.JComponent._paintImmediately(JComponent.java:5158)
at javax.swing.JComponent.paintImmediately(JComponent.java:4969)
at javax.swing.RepaintManager$4.run(RepaintManager.java:831)
at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Não sei mais aonde procurar esse estouro do Array.
Por favor, podem me ajudar a sanar essa dificuldade ?

Grato desde já.

Ola,
poste o stackTrace completo da exceção, ajuda a identificarmos onde ocorreu. Lá que é exibido a classe e a linha onde ocorreu a exceção.

Obrigado pelo retorno Rodrigo_Void, eu editei a mensagem acima e coloquei o stackTrace

Cara, no mínimo estranho…
no stackTrace não consegui identificar onde no seu código gerou a exceção.
Porém, oque é possível identificar é que o erro é proveniente da tentativa de acessar uma coluna(9) que não existe.
Ele diz que vc tentou acessar a coluna de índice 9, porém só existem 9 colunas, onde os índices ficam entre 0…8
Seu tablemodel TabelaPedidosTH não tem nenhuma destas características. Este erro está acontecendo em algum outro lugar. Vc mencionou que tinha duas jtable… vai precisar colocar mais detalhes, mais códigos, talvez prints com explicação…

Concordo com Rodrigo_Void.
Ao meu ver, o erro deve estar em um objeto do tipo tabela que esta chamando o método getValueAt(linha, coluna):

`algumaDeSuasTabelas.getValueAt(linha, coluna_inexistente);//o erro deve estar sendo disparado aqui`

Dentre as tabelas que você criou, uma delas tem apenas 9 (nove) colunas.

Não é a tabela que você postou (TabelaPedidosTH ) pois ela tem 11, colunas:

`private String[] colunas = new String[] {"ID_PEDIDO","PRODUTO", "DESCRIÇÃO", "UNID.", "FORNECEDOR", "QUANTIDADE", "DATA PEDIDO", "PREVISÃO DE CHEGADA", "VALIDADE (A)", "VALIDADE (B)", "STATUS PEDIDOS"};`

Então, eu, começaria pelo actionPerformed, deste botão.

Bom dia , Obrigado pelas respostas.
Então eu acho que eu resolvi tirando o “carregaPedidos” do worker, e coloquei um botão para o usuário clicar e atualizar a tabela.

Meu código do actionperfomed é esse:

private void start(){
    
    SwingWorker worker = new SwingWorker() {
        @Override
        protected Void doInBackground() throws Exception {
        
        if (txt_data_recebimento.getDate() == null || txt_lote_produto.getText().equals("") || txt_padrao_produto_A.getText().equals("") || txt_produto_recebimento.getText().equals("") || txt_quantidade_entrada.getText().equals("") || txt_validadeA.getText().equals("")) {
        JOptionPane.showMessageDialog(null, "Campos obrigatórios não preenchidos!");
        if (txt_data_recebimento.getDate() == null) {
            txt_data_recebimento.getDateEditor().getUiComponent().requestFocusInWindow();              
        }else if(txt_lote_produto.getText().equals("")){
            txt_lote_produto.setBackground(new Color(245,126,126));
            txt_lote_produto.requestFocus();
        }else if(txt_padrao_produto_A.getText().equals("")){
            txt_padrao_produto_A.setBackground(new Color(245,126,126));
            txt_padrao_produto_A.requestFocus();
        }else if(txt_produto_recebimento.getText().equals("")){
            txt_produto_recebimento.setBackground(new Color(245,126,126));
            txt_produto_recebimento.requestFocus();
        }else if(txt_quantidade_entrada.getText().equals("")){
            txt_quantidade_entrada.setBackground(new Color(245,126,126));
            txt_quantidade_entrada.requestFocus();
        }else if(Integer.parseInt(txt_padrao_produto_A.getText()) + Integer.parseInt(txt_padrao_produto_B.getText()) + Integer.parseInt(txt_padrao_produto_R.getText()) != Integer.parseInt(txt_quantidade_entrada.getText())){
            JOptionPane.showMessageDialog(null, "A soma das quantidades do tipo A, B e Refugo não estão batendo com o total de entrada. Por favor, verifique as uantidades.");
            txt_padrao_produto_A.requestFocus();
        }else if(txt_validadeA.getText().equals("")){
            txt_validadeA.setBackground(new Color(245,126,126));
            txt_validadeA.requestFocus();
        }
    }else{
        
        int refugo = 0; 
        if(txt_padrao_produto_R.getText().equals("")){txt_padrao_produto_R.setText("0");}else{refugo = Integer.parseInt(txt_padrao_produto_R.getText());}
        if(txt_padrao_produto_B.getText().equals(""))txt_padrao_produto_B.setText("0");
        Date pegaAData = txt_data_recebimento.getDate();
        String form = String.valueOf(sdf.format(pegaAData));

        String dia = form.substring(0,2);
        String mes = form.substring(3,5);
        String ano = form.substring(6);
        String dataparaSQL = ano + "-" + mes + "-" + dia;
        
        String diaA = txt_validadeA.getText().substring(0,2);
        String mesA = txt_validadeA.getText().substring(3,5);
        String anoA = txt_validadeA.getText().substring(6);
        String SqlA = anoA + "-" + mesA + "-" + diaA;
        
        String diaB = txt_validadeB.getText().substring(0,2);
        String mesB = txt_validadeB.getText().substring(3,5);
        String anoB = txt_validadeB.getText().substring(6);
        String SqlB = anoB + "-" + mesB + "-" + diaB;

        int idpedido = (Integer)lst_pedidos_em_andamento.getValueAt(lst_pedidos_em_andamento.convertRowIndexToModel(lst_pedidos_em_andamento.getSelectedRow()), 0);
        
        java.sql.Date datahoje, dataprevisao, datavalA, datavalB;
        SimpleDateFormat sdff = new SimpleDateFormat("yyyy-MM-dd");
        
        if(txt_padrao_produto_B.getText().equals("0"))SqlB = SqlA;
        
        try { 
            datahoje = new java.sql.Date(sdff.parse(dataparaSQL).getTime());
            datavalA = new java.sql.Date(sdff.parse(SqlA).getTime()); 
            datavalB = new java.sql.Date(sdff.parse(SqlB).getTime()); 

            Estoque estoque = new Estoque();
            estoque.setDescricaoproduto(txt_produto_recebimento.getText());
            estoque.setUnidade(txt_unidade_produto.getText());
            estoque.setLote(txt_lote_produto.getText());
            estoque.setDt_entrada(datahoje);
            estoque.setQtd_A(Integer.parseInt(txt_padrao_produto_A.getText()));
            estoque.setQtd_B(Integer.parseInt(txt_padrao_produto_B.getText()));
            estoque.setQtd_R(refugo);
            estoque.setQtd_NF(Integer.parseInt(txt_quantidade_nf.getText()));
            estoque.setQtd_entrada(Integer.parseInt(txt_quantidade_entrada.getText()));
            estoque.setQtd_pedido(Integer.parseInt(txt_quantidade_pedido.getText()));
            estoque.setValidade_a(datavalA);
            estoque.setValidade_b(datavalB);
            
            PedidosSQL pedidos = new PedidosSQL();
            pedidos.atualizaStatusPedido(idpedido, txt_status_pedido_produto.getText());

            EstoqueSQL estoqueSql = new EstoqueSQL();
            estoqueSql.criarEstoque(estoque);
            
            estoqueSql.dias_ValidadeCalcular(estoque.getValidade_a(), estoque.getValidade_b(), estoque.getLote(), estoque.getDescricaoproduto());
            
            limparCampos();
            
            try {
                carregarEstoque();
            } catch (Exception e) {
                System.out.println(e.toString());
            }
           
        } catch (ParseException ex) {
            Logger.getLogger(frm_telaRecebimentos.class.getName()).log(Level.SEVERE, null, ex);
        }
        JOptionPane.showMessageDialog(null, "Produto salvo no estoque com sucesso!");
    }
        ajustarTabelaPedidos();
        return null;
    }
};
 worker.execute();

}

Tem outro tambem, dentro do worker eu coloquei um ajustar tabela, para ajustar as tabelas depois que atualiza-las.

public void ajustarTabelaPedidos(){

    esquerda.setHorizontalAlignment(SwingConstants.LEFT);
    centralizado.setHorizontalAlignment(SwingConstants.CENTER);

    lst_pedidos_em_andamento.convertColumnIndexToModel(0);
    lst_pedidos_em_andamento.convertColumnIndexToModel(1);
    lst_pedidos_em_andamento.convertColumnIndexToModel(2);
    lst_pedidos_em_andamento.convertColumnIndexToModel(3);
    lst_pedidos_em_andamento.convertColumnIndexToModel(4);
    lst_pedidos_em_andamento.convertColumnIndexToModel(5);
    lst_pedidos_em_andamento.convertColumnIndexToModel(6);
    lst_pedidos_em_andamento.convertColumnIndexToModel(7);
    lst_pedidos_em_andamento.convertColumnIndexToModel(8);
    lst_pedidos_em_andamento.convertColumnIndexToModel(9);
    lst_pedidos_em_andamento.convertColumnIndexToModel(10);
    
    lst_pedidos_em_andamento.getColumnModel().getColumn(0).setCellRenderer(centralizado);
    lst_pedidos_em_andamento.getColumnModel().getColumn(1).setCellRenderer(centralizado);
    lst_pedidos_em_andamento.getColumnModel().getColumn(2).setCellRenderer(centralizado);
    lst_pedidos_em_andamento.getColumnModel().getColumn(3).setCellRenderer(centralizado);
    lst_pedidos_em_andamento.getColumnModel().getColumn(4).setCellRenderer(centralizado);
    lst_pedidos_em_andamento.getColumnModel().getColumn(5).setCellRenderer(centralizado);
    lst_pedidos_em_andamento.getColumnModel().getColumn(6).setCellRenderer(centralizado);
    lst_pedidos_em_andamento.getColumnModel().getColumn(7).setCellRenderer(centralizado);
    lst_pedidos_em_andamento.getColumnModel().getColumn(8).setCellRenderer(centralizado);
    lst_pedidos_em_andamento.getColumnModel().getColumn(9).setCellRenderer(centralizado);
    lst_pedidos_em_andamento.getColumnModel().getColumn(10).setCellRenderer(centralizado);
    
    lst_estoque.getColumnModel().getColumn(0).setCellRenderer(centralizado);
    lst_estoque.getColumnModel().getColumn(1).setCellRenderer(centralizado);
    lst_estoque.getColumnModel().getColumn(2).setCellRenderer(centralizado);
    lst_estoque.getColumnModel().getColumn(3).setCellRenderer(centralizado);
    lst_estoque.getColumnModel().getColumn(4).setCellRenderer(centralizado);
    lst_estoque.getColumnModel().getColumn(5).setCellRenderer(centralizado);
    lst_estoque.getColumnModel().getColumn(6).setCellRenderer(centralizado);
    lst_estoque.getColumnModel().getColumn(7).setCellRenderer(centralizado);
    lst_estoque.getColumnModel().getColumn(8).setCellRenderer(centralizado);
    lst_estoque.getColumnModel().getColumn(12).setCellRenderer(centralizado);
    lst_estoque.getColumnModel().getColumn(13).setCellRenderer(centralizado);
    
    lst_estoque.getColumnModel().getColumn(10).setCellRenderer(FormatRenderer.getDateRenderer());
    lst_estoque.getColumnModel().getColumn(11).setCellRenderer(FormatRenderer.getDateRenderer());
    lst_estoque.getColumnModel().getColumn(9).setCellRenderer(FormatRenderer.getDateRenderer());
    
    lst_pedidos_em_andamento.getColumnModel().getColumn(6).setCellRenderer(FormatRenderer.getDateRenderer());
    lst_pedidos_em_andamento.getColumnModel().getColumn(7).setCellRenderer(FormatRenderer.getDateRenderer());
    lst_pedidos_em_andamento.getColumnModel().getColumn(8).setCellRenderer(FormatRenderer.getDateRenderer());
    lst_pedidos_em_andamento.getColumnModel().getColumn(9).setCellRenderer(FormatRenderer.getDateRenderer());
    
    lst_estoque.getColumnModel().getColumn(0).setMinWidth(45);
    lst_estoque.getColumnModel().getColumn(0).setMaxWidth(45);   
    lst_estoque.getColumnModel().getColumn(1).setMinWidth(200);
    lst_estoque.getColumnModel().getColumn(1).setMaxWidth(200);
    lst_estoque.getColumnModel().getColumn(2).setMinWidth(65);
    lst_estoque.getColumnModel().getColumn(2).setMaxWidth(65);        
    lst_estoque.getColumnModel().getColumn(3).setMinWidth(65);
    lst_estoque.getColumnModel().getColumn(3).setMaxWidth(65); 
    lst_estoque.getColumnModel().getColumn(4).setMinWidth(85);
    lst_estoque.getColumnModel().getColumn(4).setMaxWidth(85);
    lst_estoque.getColumnModel().getColumn(5).setMinWidth(65);
    lst_estoque.getColumnModel().getColumn(5).setMaxWidth(65);
    lst_estoque.getColumnModel().getColumn(6).setMinWidth(60);
    lst_estoque.getColumnModel().getColumn(6).setMaxWidth(60);
    lst_estoque.getColumnModel().getColumn(7).setMinWidth(45);
    lst_estoque.getColumnModel().getColumn(7).setMaxWidth(45);
    lst_estoque.getColumnModel().getColumn(8).setMinWidth(60);
    lst_estoque.getColumnModel().getColumn(8).setMaxWidth(60);
    lst_estoque.getColumnModel().getColumn(9).setMinWidth(95);
    lst_estoque.getColumnModel().getColumn(9).setMaxWidth(95);
    lst_estoque.getColumnModel().getColumn(10).setMinWidth(110);
    lst_estoque.getColumnModel().getColumn(10).setMaxWidth(110);
    lst_estoque.getColumnModel().getColumn(11).setMinWidth(110);
    lst_estoque.getColumnModel().getColumn(11).setMaxWidth(110);

}

Eu acho que o erro eram dois:

1 - eu modifica um elemento do swing dentro de um worker, acho que isso não é bom, então eu tirei o carregaPedidos de dentro do worker.

2 - dentro do metodo de ajustar as tabelas, eu tinha que colocar o convertColumnIndexToModel para todas as colunas. Acho que ele não estava conseguindo indentificar o indice correto.

Acho que era isso.

Ah … Esse é o método de carregar a tabela pedido, ou seja, a TABELAPEDIDOSTH

public void carregarPedidos(){
    
    try{
        
        MostrarTabelas mostrarBaseProdutosPedidos = new MostrarTabelas();
        TabelaPedidosTH model = new TabelaPedidosTH(mostrarBaseProdutosPedidos.lerTabelaDePedidosParaRecebimento());   
        lst_pedidos_em_andamento.setModel(model);
        this.lbl_contador_de_pedidos.setText("Registros em pedido: " + String.valueOf(lst_pedidos_em_andamento.getRowCount()));
    }catch(ArrayIndexOutOfBoundsException e){
        System.out.println("erro: " + e.toString());
    }

}

Mas queria entender, pq eu não posso atualizar a jtable da tabela de pedidos, se eu atualizo a tabela de estoque normalmente e está dentro do evento “start” e se eu chamar o método de carregar pedidos ele lança a exceção da minha dúvida.

Olá, não me lembro muito se no swing é assim, mas no JavaFx e Android você não pode modificar elementos visuais por uma thread seundária.