How to use JProgressBar while method (return value) performs reading of XML files?

4

I have a little knowledge in Java and I have already researched the internet on how to use a JProgressBar while I run a method, but I have not got any examples that work according to my needs since my method returns a value. Logica = I have a Class (LoadXmls), which has a method (xmlAut), this method reads n of Xml files and adds each of them into a list which then lists the list and added it to a tableModel (templateAutAll). After reading the last file the method returns a TableModel that will be used to fill a table. What I need = While the read method would like either a GIF to wait or a JProgressBar so that the screen does not stay static, giving the impression that it is locked. If anyone can give me information on how to do this mission would be a huge help.

Here is the code for my class LoadXMLs with the xmlAut method:

package br.com.leitorXml;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;

import br.com.Dados.Dados;
import br.com.UTIL.VerificaString;
import br.com.UTIL.XmlUtil;

public class CarregarXmls extends JFrame
{

    @SuppressWarnings("unused")
    private static final long serialVersionUID = 1295991874261633841L;
    File[]  arquivosCanc = null;
    String diretorioBackup = null, conteudoSelecionado = null;


    @SuppressWarnings({ "rawtypes", "unchecked" })
    public ModeloDadosAut xmlAut ()
    {

        JFileChooser fc = new JFileChooser();
        List ListaDadosAut = null;

        final ModeloDadosAut modeloTabelaAut = new ModeloDadosAut();

        // DEVERA ABRIR PASTAS E VARIOS ARQUIVOS
        fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); // ARQUIVOS E DIRETORIOS
        //      fc.setFileSelectionMode(JFileChooser.FILES_ONLY);  // SOMENTE ARQUIVOS

        // TITULO JANELA
        fc.setDialogTitle("Selecione os arquivos ou uma pasta"); 

        // CRIANDO FILTRO XML
        FileNameExtensionFilter filtroXml = new FileNameExtensionFilter 
                ("xml files (*.xml)", "xml");
        fc.setFileFilter(filtroXml); // FILTRANDO SOMENTE ARQUIVOS XMLS
        fc.setMultiSelectionEnabled(true);
        File diretorio;

        // DEFININDO DIRETORIO INCIAL
        //SE A VARIAVEL DIRETORIOBACKUP ESTIVER NULL COLOQUE DIRETORIO INCIAL C:\
        if(diretorioBackup != null)
        {
            diretorio = new File(""+diretorioBackup+"");
        }
        // SE NAO ESTIVER NULL COLOQUE ULTIMO CAMINHO UTILIZADO
        else
            diretorio = new File("c:\");

        fc.setCurrentDirectory(diretorio);

        //  CRIA POP UP
        int res = fc.showOpenDialog(new JFrame());


        //APOS SELECIONAR O BOTAO ABRIR 
        if(res == JFileChooser.APPROVE_OPTION)
        {           

            System.out.println("Verificar o que foi selecionado (pasta ou arquivo) = " +fc.getSelectedFile().getAbsolutePath());
            // ATRIBUINDO NA VARIAVEL conteudoSelecionado PARA QUE SEJA UTILIZADO NO METODO ModeloDadosCanc
            conteudoSelecionado = fc.getSelectedFile().getAbsolutePath();



            // SE FOR SELECIONADO UM OU MAIS ARQUIVOS xml RETORNA FALSE
            if(VerificaString.VerificaConteudoSelecionado(fc.getSelectedFile().getAbsolutePath()) == false)
            {

                File[] arquivos = fc.getSelectedFiles();  
                arquivosCanc = fc.getSelectedFiles(); // ATRIBUINDO PARA DEPOIS SER UTILIZADO NO METODO XMLCANC
                qtdArquivos = arquivos.length;                      

                //                          JOptionPane.showMessageDialog(null, "Voce escolheu os arquivos: \n" + arquivos.getName());
                System.out.println("Voce selecionou os arquivos listados abaixo:");         



                for(int i = 0; i < arquivos.length; i++)
                {
                    try
                    {
                        System.out.println("\nDentro do For (autorizados) = "+arquivos[i].toString());
                        diretorioBackup = arquivos[i].toString();
                        System.out.println("\nDentro do For (autorizados) diretorioBackup "+ diretorioBackup); 
                        ListaDadosAut = XmlUtil.lerArquivoAutorizadoReceita(arquivos[i].getPath(), arquivos[i].getName());

                        modeloTabelaAut.carregarDados(ListaDadosAut);
                    }
                    catch (Exception e1) 
                    {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }// FIM DO FOR
                return modeloTabelaAut;
            }// FIM DO IF SELECIONANDO ARQUIVOS XML

        }
        else
        {
            JOptionPane.showMessageDialog(null, "Voce nao selecionou nenhum arquivo.");         
            return null;
        }
        return modeloTabelaAut;

        }// Fim do METODO xmlAut
    
asked by anonymous 24.12.2015 / 12:44

1 answer

2

As your calling code is in the Event Dispatcher Thread - and he needs to complete before releasing the EDT to continue managing the Swing graphical interface - then you only have two options:

  • Modify the calling code to not do this update in the EDT, but in another thread;
  • Return your empty table model, populate it into another thread, and then notify the table that that template has changed.
  • I think this second option is simpler if it does not have any undesired effect on using an empty table template while the data is filled out. The only change you would have to make in your code is this:

    // Precisa ser final, pra poder ser acessada dentro do thread
    final File[] arquivos = fc.getSelectedFiles();  
    
    arquivosCanc = fc.getSelectedFiles(); // ATRIBUINDO PARA DEPOIS SER UTILIZADO NO METODO XMLCANC
    qtdArquivos = arquivos.length;         
    System.out.println("Voce selecionou os arquivos listados abaixo:");         
    
    new Thread(new Runnable() {
        public void run() {
    
            for(int i = 0; i < arquivos.length; i++)
            {
                try
                {
                    System.out.println("\nDentro do For (autorizados) = "+arquivos[i].toString());
                    diretorioBackup = arquivos[i].toString();
                    System.out.println("\nDentro do For (autorizados) diretorioBackup "+ diretorioBackup); 
                    ListaDadosAut = XmlUtil.lerArquivoAutorizadoReceita(arquivos[i].getPath(), arquivos[i].getName());
    
                    modeloTabelaAut.carregarDados(ListaDadosAut);
                }
                catch (Exception e1) 
                {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }// FIM DO FOR
    
            modeloTabelaAut.fireTableDataChanged(); // Notifica a tabela que os dados mudaram
    
        } // Fim do run
    }).start();
    
    return modeloTabelaAut; // A tabela está sendo retornada vazia
    

    (Note: if the structure table also changed inside the loop - for example columns were added or changed - use fireTableStructureChanged instead of fireTableDataChanged )

    Then you can freely update a JProgressBar within the loop that is in the thread. For example, assuming you have created a progress bar called barraProgresso , you can update it as follows:

    barraProgresso.setValue(0);
    barraProgresso.setMaximum(arquivos.length + 1);
    
    new Thread(new Runnable() {
        public void run() {
    
            for(int i = 0; i < arquivos.length; i++)
            {
                barraProgresso.setValue(i+1);
                ...
            }
            barraProgresso.setValue(arquivos.length + 1);
    
        
    28.12.2015 / 17:27