JTable com loop dando ConcurrentModificationException, botão que precisa clicar 50 vezes...

Java

30/04/2021

Boa tarde, pessoal!



Gostaria de pedir a ajuda de vocês, estou com alguns problemas no meu código.

Seguinte... Tem uma tabela no meu programa, a qual coloquei um loop para buscar os dados do MySQL e atualizar de segundo em segundo.

É a primeira vez que faço algo do tipo, e é a primeira vez que mexo com TimerTask, e estou obtendo alguns erros com isto.



O primeiro código que utilizei, foi para ficar verificando se tem algum cupom pendente para ser gerado.

private static Timer loop = new Timer();
    private static ArrayList<String> cuponsAFazer = new ArrayList<>();//ID Pedido => chaves a serem pegas
    private static ArrayList<String> cuponsACancelar = new ArrayList<>();//Chave do cupom

	private static void loop() {
        loop.scheduleAtFixedRate(new TimerTask() {
            public void run() {
                //Verificar cupons com ordem de geração
                if (cuponsAFazer != null && !cuponsAFazer.isEmpty()) {
                    for (Object i : cuponsAFazer) {//O ERRO É EXATAMENTE NESTA LINHA
                        buscarChave(Integer.valueOf(i.toString()));
                    }
                }
                //Cancelar cupons
                for (String s : cuponsACancelar) {
                    try {
                        String cancelar = "ChaveNota=" + s;
                        PrintWriter escrever = new PrintWriter(Main.config.getPastaMonitora() + "\\Cancela\" + s + ".tx2", "UTF-8");
                        escrever.print(cancelar);
                        escrever.close();
                        remover.add("cancelar;" + s);
                    } catch (FileNotFoundException | UnsupportedEncodingException ex) {
                    }
                }

                for (String s : remover) {//Limpeza dos dados após finalização das tarefas. comando;variável
                    if (s.split(";")[0].equalsIgnoreCase("cancelar")) {
                        cuponsACancelar.remove(s.split(";")[1]);//ADICIONEI ISTO, POIS NÃO CONSIGO REMOVER DIRETAMENTE DENTRO DO FOR ACIMA, FOI A "GAMBIARRA" QUE ENCONTREI.
                    }
                    if (s.split(";")[0].equalsIgnoreCase("fazer")) {
                        //cuponsAFazer.remove(s.split(";")[1]);
                    }
                }
                remover.clear();
            }

        }, 0, 1 * 1000);
    }



O primeiro erro é o seguinte:

Exception in thread "Timer-1" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at o.pdv.config.SAT$1.run(SAT.java:255)
at java.util.TimerThread.mainLoop(Unknown Source)








E, tem um segundo erro, que dá ao ficar atualizando a tabela para atualizar os pedidos recebidos do MySQL.

Erro:

Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at o.visual.pdv.Pedidos.atualizarTabela(Pedidos.java.74)
Que pertence ao seguinte código:

    public void atualizarTabela() {
        int[] selectedIndex = tabela.getSelectedRows();
        DefaultTableModel dtm = (DefaultTableModel) tabela.getModel();
        dtm.setRowCount(numPedidosNaLista);
        if (numPedidosNaLista == 0) {
            return;
        }
        int ultimaLinha = 0;
        ArrayList<resumoPedido> temp = pedidos;
        for (resumoPedido p : temp) {//O ERRO É EXATAMENTE NESTA LINHA. ANTES ESTAVA assim: for(resumoPedido p : pedidos), porém tentei mudar para isto, para fazer uma cópia temporária e acessar apenas a array temp, mas o erro permanece o mesmo
            if (p == null) {
                continue;
            }
            if (filtro.getNomeCliente() != null && !filtro.getNomeCliente().isEmpty()) {
                if (p.getNomeCliente() == null || p.getNomeCliente().isEmpty()) {
                    continue;
                }
                if (!p.getNomeCliente().toLowerCase().startsWith(filtro.getNomeCliente().toLowerCase())) {
                    continue;
                }
            }
            if (!filtro.temNomeCliente() && p.linhaDaTabela == -1) {
                continue;
            }
            if (ultimaLinha > resultadosPorPagina - 1) {
                continue;
            }
            if(dtm.getRowCount() < ultimaLinha){
                continue;
            }
            String data = getData(p.dataAgendamento);
            String status = p.getStatus();
            double valRestante = p.valTotal - p.valPago;
            dtm.setValueAt(p.IDPedido, ultimaLinha, 0);
            dtm.setValueAt(p.getIDCliente() == -13 ? "-" : p.getIDCliente(), ultimaLinha, 1);
            dtm.setValueAt(p.getNomeCliente(), ultimaLinha, 2);
            dtm.setValueAt(data, ultimaLinha, 3);
            dtm.setValueAt(p.valPago == 0 ? "" : Metodos.FN("#,###.##", p.valPago), ultimaLinha, 4);
            dtm.setValueAt(p.valTotal == 0 ? "" : Metodos.FN("#,###.##", p.valTotal), ultimaLinha, 5);
            dtm.setValueAt(valRestante <= 0 ? "" : Metodos.FN("#,###.##", valRestante), ultimaLinha, 6);
            dtm.setValueAt(p.IDEnredeço > 0 ? "Sim" : "", ultimaLinha, 7);
            dtm.setValueAt(status, ultimaLinha, 8);
            ultimaLinha++;
        }
        temp = null;
        System.gc();
        if (ultimaLinha < (resultadosPorPagina)) {
            dtm.setRowCount(ultimaLinha);
        }
    }







Também estou com um outro probleminha.. Nunca vi isto acontecer antes. As vezes, o usuário tem que clicar várias e várias vezes no botão para ele poder funcionar. Alguém já viu algo do tipo? Não dá erro nem nada... O botão parece que simplesmente não funciona as vezes. (PS: Todos os botões de um JFrame estão assim. Os demais botões dos demais JFrames estão normais.)



Se alguém conseguir me ajudar serei eternamente grato!



Obrigado, bom dia!
Rafael

Rafael

Curtidas 0
POSTAR