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

30/04/2021

0

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

Responder

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar