How to use Jprogressbar while method(returns value) performs reading XML files?

Asked

Viewed 1,376 times

4

I have a little knowledge in Java and I have already researched in the internet about how to use a Jprogressbar while running a method, but I could not get any example that works according to my need since my method returns a value. Logica = I have a Class (Carregarxmls), which has a method (xmlAut), this method performs the reading of n Xml files and adds each of them in a list that then the list and added to a tableModel (modelTabelAut) . After reading the last file the method returns a Tablemodel that will be used to fill a table. What I need = While the method performs the reading would like either a GIF or a Jprogressbar so that the screen does not become static, giving the impression that it is locked. If anyone can give me information on how to do this mission would be of enormous help.

Follow code from my class Carregarxmls with 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
  • Knows how to use Threads?

  • I have been researching some examples with Threads, but I saw that when I run the method in a Thread it is not possible to return a value. And in my case I need you to return a Tablemodel.

  • http://www.guj.com.br/t/jprogressbar-em-thread/225147/2

  • Try using a global variable.

  • Is using netbeans ?

  • Here is another example: http://stackoverflow.com/questions/19312658/how-to-set-the-jprogressbar-working-according-to-the-time-taken-for-a-task-in-ja

  • Take a look at Future<V>. The idea is to return not one ModeloDadosAut but a Future<ModeloDadosAut>, and make the thread responsible for the execution (for example a SwingWorker, implementing Future) put a final value on this Future when ready. Because returning directly is not feasible - especially if the method is called in the Event Dispatcher thread (since then the screen would lock all until the end of the execution).

  • @mgibsonbr could not understand very well how to implement this Future<v>. Would have some practical example to show me?

  • @Techies I am using Eclipse, the examples Voce sent me are examples that I had already tried to adapt to my use, but could not.

  • @Douglasribeiro Yes, I can try, just give me a little time. I would also like to know the following: who calls the xmlAut? Can the return value of this method be changed? And the code you call xmlAut is running from that thread? (for example, if this code runs after the click of a button, it is in the Event Dispatcher thread, unless you have put it to run in a different thread) I ask because if you have no problem block off this thread, the solution becomes simpler (but if it is the EDT then it can not block otherwise hangs the screen).

  • No problems@mgibsonbr ,I cannot change the return value of the method, the code that calls xmlAut is not running on a thread. It is executed after one click. It follows code from my vision class that calls the xmlAut method of the Load class. E chamado dentro de um Jbutton: btnCarregar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { tabelaAut.setModel(xml.xmlAut()); } });// END OF BTNCARREGAR -

  • I thought here, and did not find a way to do what you want. Because the code of ActionListener will run on EDT, it needs to complete before releasing the EDT, and you cannot lock the EDT without locking the screen. What you can do is create and return your ModeloDadosAut, empty, then populate it in another thread and at the end call modeloTabelaAut.fireTableStructureChanged().

Show 7 more comments

1 answer

2


How your calling code is on Event Dispatcher Thread - and it needs to complete before releasing the EDT to continue managing the Swing graphical interface - so you only have two options left:

  1. Modify the calling code not to make this update in the EDT but in another thread;
  2. Return your empty table template, populate it into another thread, and then notify the table that this model has changed.

I think this second option is simpler if it doesn’t have any unwanted effect on using an empty table template while the data is filled in. The only change you would have to make to your code is as follows::

// 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 inside the loop that is in the thread. For example, assuming you 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);
  • really the screen gets totally locked just did not know it was due the EDT has not yet been finished, this second option worked and through this forum I managed to learn a lot about Threads. Thank you very much!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.