[RESOLVIDO]jProgressBar1

14 respostas
C

Boa tarde a todos,

Estou criando uma aplicação que faz a leitura de um arquivo .XML, gravando as informações em um .TXT

No entanto, tenho por objetivo em criar uma interface gráfica para o mesmo, onde peço a colaboração de vocês.

Estou utilizando as ferramentas do próprio Netbeans, onde a interface gráfica será básica..

A interface será composta por:
-jTextField que recebe o caminho do arquivo, após selecionar o mesmo, através do JFileChooser(Está Ok).
-jProgressBar e jLabel, para mostrar o progresso do processo.
-jButton, para iniciar o processo.

O problema está no momento em que clico no jButton para processar as informações, sabendo-se após efetuar o mesmo, a interface fica desabilitada para fazer outras informações, até que conclua a aplicação da classe que meu jButton chamou, ou seja, não consigo fechar a aplicação, somente pelo próprio Java.

E meu objetivo era que assim que chamasse a minha classe para efetuar a leitura do XML e gravar em um .txt, a cada registro gravado, incrementasse em meu jProgressBar..

Trecho da minha classe LerXML:

//esse trecho tempor objetivo, somente percorrer o arquivo para verificar a quantidade de registros para enviar para o meu jProgressBar1.setMaximum();

public int Contador() throws JDOMException, IOException{
        SAXBuilder arq = new SAXBuilder();
        Document docs = arq.build("C:\\Users\\Eduardo\\ArquivosXML\\LASER\\XML.xml");
        Element eleme = docs.getRootElement();
        
        List<Element> asdfg = eleme.getChildren();
        int reg=0;
        for (Element uuyy: asdfg){
            reg++;
        }
        return reg;
    }
.
.
.
.
.

int iop=0;

        //Este for irá percorrer todo o arquivo, ou seja, a cada vez que ele roda, ele faz a leitura de um registro, 
        //portanto, criei um contador com a intenção de atualizar meu ProgressBar.

        for (Element data : dadosAssinan) {
           iop++;    
           frame = new JFXML();
           frame.setjProgressBar1(iop);
           frame.AtualizaLabel();

Classe JFrame (Interface gráfica):

//depois do initComponents();

classeleitor = new ClasseLeitor();
try {
            jProgressBar1.setMaximum(classeleitor.Contador());
} catch (IOException ex) {
            Logger.getLogger(JFXML.class.getName()).log(Level.SEVERE, null, ex);
}

.
.
.
// no final do código, criei dois métodos, pensando que poderia atualizar meu JFrame enquanto rodasse a minha Classe LerXML

    void  setjProgressBar1(int num){
        jProgressBar1.setValue(num);
    }
    
    void AtualizaLabel(){
        jLabel1.setText(Integer.toString(jProgressBar1.getValue()*100/jProgressBar1.getMaximum())+"%");
    }

Ou seja, esse código, foram algumas tentativas, no entanto, aguardo por mais orientações.
Desde já Agradeço, Eduardo.

14 Respostas

ViniGodoy

Movido para o fórum de interface gráfica.

E… para resolver o seu problema, coloque o processamento do JButton dentro de uma thread separada.

C

Desculpe-me Viny, mas meu conhecimento é muito limitado,
Quando diz thread, refere-se a que?

ViniGodoy

A thread mesmo. :slight_smile:
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/simple.html

C

Com a utilização de threads. Será possível resolver o meu problema?

Pelo que eu pude compreender, as threads são utilizadas quando tenho a necessidade de executar mais de um processo ao mesmo tempo…

Esses processos devem ser distintos ou podem ser interligados?

Pois tenho por objetivo que minha jProgressBar atualize conforme a execução da minha classe LerXML, assim que eu pressionar o jButton.

Haveria possibilidade de parar a execução da minha classe LerXML no meio do processo?

Att, Eduardo Pereira

C

Agradecido Vinny;
Fiz o teste, conforme me orientou, no entanto, obtive sucesso.

O problema está em acessar meu jProgressBar, pois estou implementando diretamente pelo Netbeans e o mesmo é private, onde preciso acessá-la de outra classe, sabendo-se que dá erro se eu criar um método set sem ser privado…

ViniGodoy

Poste aqui o método do botão que dispara o processamento pesado.

C
Método do botão:
try {
            ClasseLeitor leitor = new ClasseLeitor();
            Thread thread = new Thread(leitor);
            thread.start();
        } catch (Exception err){
            err.getMessage();
        }

Método Run:

@Override
    public void run(){
        try{
            lerXML();
        }catch(Exception err){
            err.getMessage();
        }
    }

Trecho do Método lerXML:

for (Element data : dadosAssinan) {

Ou seja, dentro do "for" do meu Método "lerXML" eu gostaria de atualizar meu jProgressBar, mas o que está complicando é que o meu jProgressBar é private da minha classe JFXML, então não consigo acessar ele..

C

Na realidade não saberia dizer se é devido o modificador, mas gostaria de saber como farei para acessar meu jProgressBar

Desde Já Agradeço, Eduardo.

C

Então Vinny..
Fiz diferente agora, ao invés de criar objetos para acessar a minha outra classe..
inclui ela na minha classe principal como métodos, no entanto, segue o código completo de minha classe principal:

/*

package XML;

import java.io.*;
import java.util.*;
import javax.swing.JOptionPane;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;
import java.io.BufferedWriter;
import java.io.FileWriter;
import javax.swing.JTextField;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import org.jdom.JDOMException;

/**
 *
 * @author Eduardo
 */
public class JFXML extends javax.swing.JFrame implements Runnable {

    /** Creates new form JFXML */
    public JFXML() throws JDOMException {
        initComponents();
        jTextField1.setText("");
        jTextField1.setEditable(false);
        jLabel1.setText(null);
        jButton1.requestFocus();
        try {
            jProgressBar1.setMaximum(Contador());
        } catch (IOException ex) {
            Logger.getLogger(JFXML.class.getName()).log(Level.SEVERE, null, ex);
        }

        //setjProgressBar1(500);
        //AtualizaLabel();

    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jTextField1 = new javax.swing.JTextField();
        jButton1 = new javax.swing.JButton();
        jProgressBar1 = new javax.swing.JProgressBar();
        jButton2 = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Arquivos XML");
        setResizable(false);

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Selecione o Arquivo:"));

        jTextField1.setText("jTextField1");
        jTextField1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextField1ActionPerformed(evt);
            }
        });

        jButton1.setText("...");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 301, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButton1)
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButton1))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jButton2.setText("Run");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jLabel1.setText("0%");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jProgressBar1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 384, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jButton2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 316, Short.MAX_VALUE)
                        .addComponent(jLabel1)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jButton2)
                    .addComponent(jLabel1))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                        

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        JFileChooser abrir = new JFileChooser();
        int retorno = abrir.showOpenDialog(null);
        if (retorno == JFileChooser.APPROVE_OPTION) {
            String caminho = abrir.getSelectedFile().getAbsolutePath();
            jTextField1.setText(caminho);
            jProgressBar1.setValue(0);
        }
    }                                        

    private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {                                            
        // TODO add your handling code here:
    }                                           

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        try {
            ClasseLeitor leitor = new ClasseLeitor();
            Thread thread = new Thread(leitor);
            thread.start();
        } catch (Exception err) {
            err.getMessage();
        }
    }                                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                try {
                    new JFXML().setVisible(true);
                } catch (JDOMException ex) {
                    Logger.getLogger(JFXML.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }
    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    public javax.swing.JLabel jLabel1;
    private javax.swing.JPanel jPanel1;
    public javax.swing.JProgressBar jProgressBar1;
    public javax.swing.JTextField jTextField1;
    // End of variables declaration                   

    private void setjProgressBar1(int num) {
        jProgressBar1.setValue(num);
    }

    private void AtualizaLabel() {
        jLabel1.setText(Integer.toString(jProgressBar1.getValue() * 100 / jProgressBar1.getMaximum()) + "%");
    }

    @Override
    public void run() {
        try {
            lerXML();
        } catch (Exception err) {
            err.getMessage();
        }
    }

    private int Contador() throws JDOMException, IOException {
        String caminho = "";
        caminho = "C:\\Users\\Eduardo\\ArquivosXML\\LASER\\XML.xml";
        SAXBuilder arq = new SAXBuilder();
        Document docs = arq.build(caminho);
        //Document docs = arq.build("C:\\Users\\Eduardo\\ArquivosXML\\LASER\\XML.xml");
        //Criamos um objeto Element que recebe as tags do XML
        Element eleme = docs.getRootElement();

        List<Element> asdfg = eleme.getChildren();
        int reg = 0;
        for (Element uuyy : asdfg) {
            reg++;
        }
        return reg;
    }

    public void lerXML() throws JDOMException, IOException {
        //Criamos um objeto SAXBuilder
        //para ler o arquivo

        SAXBuilder sb = new SAXBuilder();
        FileWriter writer = new FileWriter("C:\\Users\\Eduardo\\ArquivosXML\\LASER\\XML.txt");
        FileWriter teste = new FileWriter("C:\\Users\\Eduardo\\ArquivosXML\\LASER\\ERROR.txt");
        //Criamos um objetvo Document que irá receber o conteúdo do arquivo

        Document doc = sb.build("C:\\Users\\Eduardo\\ArquivosXML\\LASER\\XML.xml");
        //Criamos um objeto Element que recebe as tags do XML
        Element elements = doc.getRootElement();
        List<Element> dadosAssinan = elements.getChildren();

        NumAtendimento[] numatendimento = new NumAtendimento[5];
        Descricao[] descricao_numatendimento = new Descricao[16];
        Descricao[] descricao_instrucaoboleto = new Descricao[6];
        ItenBoleto[] itenboleto = new ItenBoleto[50];
        ItenNotaFiscal[][] itennotafiscal = new ItenNotaFiscal[2][50];
        NotaFiscal[] notafiscal = new NotaFiscal[2];
        int cont;
        int iop = 0;
        //Loop em fonesElement para pegar as demais tags
        for (Element data : dadosAssinan) {
            iop++;
            jProgressBar1.setValue(iop);
            jLabel1.setText(Integer.toString(jProgressBar1.getValue() * 100 / jProgressBar1.getMaximum()) + "%");
            //AtualizaLabel();

           //
           //   AQUI VAI TODO O CÓDIGO
           //   PARA A MANIPULAÇÃO DOS DADOS
           //   
           //
           //
           //
           //


    }
}
ViniGodoy

Tente deixar assim, criando apenas uma inner para sua thread:

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) { try { new Thread(new Runnable() { @Override public void run() { try { lerXML(); catch (Exception e) { throw new RuntimeException(e); } } }).start(); }

C

Funcionou Vinny!

Sou grato novamente pela colaboração.

Sabendo que não é a primeira vez que tem me ajudado, no entanto, uma vez você me disse que o importante é compreender o funcionamento do mesmo, não apenas ver o negócio funcionando. Portanto, você poderia me explicar as alterações no método Run e do meu jButton?

Att, Eduardo Pereira

ViniGodoy

O que eu usei ali foi um conceito chamado de Inner Class (classe interna) anônima:
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

Sempre que você faz:

new UmaClasseQualquer() { @Override void umMetodoQualquer() { } }

Você está criando uma classe filha de UmaClasseQualquer, e sobrescrevendo os métodos, nesse caso, umMetodoQualquer().

Uma das vantagens das classes internas é que elas podem enxergar as partes privadas da classe que as contém.
Por isso, o Runnable que criei na forma de uma inner class pode chamar diretamente o método lerXML().

Esse runnable foi passado como construtor da classe Thread e, ao chamarmos o método .start(), disparou uma nova thread, que percorreu o método lerXML().

É necessário usar 2 threads pois o Swing não irá atualizar a tela até que seu evento termine de executar. Com uma thread separada, a execução do evento termina imediatamente, deixando o Swing livre para processar as demais tarefas de interface gráfica.

mcirqueira

Boa noite!
Você pode postar o programa completo?

C

Terá que ser em partes, devido a extensão do mesmo.

Mas de qualquer forma o problema já foi resolvido, agradeço a colaboração.

Criado 29 de janeiro de 2012
Ultima resposta 30 de jan. de 2012
Respostas 14
Participantes 3