Thread Worker / Observer!

37 respostas
G

Bom dia galera da GUJ! Em um ato desesperador é que peço vossa ajuda, estou preso em tal problema há UMA SEMANA (faz hoje), e agora é que complicou de vez. Pois bem, a princípio eu só queria uma jProgressBar que contasse o tempo de um determinado processo, depois resolvi que seria um contador que iria rodar em uma thread... eu não sabia como usava thread então fui estudar; logo mais, vi um tópico aqui no GUJ que falava de Observer e Observable, lá vai eu estudar denovo e tentar implementar. OK, aprendi isso e implementei numa classe A PARTE do meu programa, APENAS para testes... e lá funcionou, agora quando eu tento adaptar no meu programa, FAZENDO EXATAMENTE A MESMA COISA, o JFrame abre de forma estranha, como se por dentro ficasse invisível. O Mais estranho, é que se eu chamo esse objeto(GUI) de QUALQUER canto do meu programa, acontecerá a mesma coisa; porém se eu chamo lá da classe que eu criei apenas para testes, ela funciona PERFEITAMENTE.

O que eu faço é o Seguinte: Eu instancio uma classe GUI, que tem um frame com uma label Contador, lanço uma thread com um processo em um objeto observable, a cada iteração no run() eu notifico os Observers (Classe GUI) e incremento minha Label contadora.

Segue o código da minha classe TESTE:

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Observable;
import modelo.Item;
import modelo.ObjetoPublico;
import visualizacao.ContadorProgresso;

/**
 *
 * @author HTS
 */
public class NewClass{
    static MeuObservable ob;
    static ContadorProgresso cp;

    public MeuObservable getOb() {
        return ob;
    }


    public NewClass(){
       
        ob = new MeuObservable();
        
        cp = new ContadorProgresso("Teste.txt",this);
        
    }

  


    public static void main(String arg[]){
        
       new NewClass();
    }



    public class MeuObservable extends Observable implements Runnable{
        public void changeSome(){
            setChanged();
            notifyObservers();
        }

        public void run() {
            BufferedReader cargaPLU = Conexao.arqCargaCod();
        boolean erro;
        if (cargaPLU == null) {
                erro = false;
            }
            String codBarra = "", quantidade = "", descricao = "", codInterno = "", tipoProd = "";
            try {
                while (cargaPLU.ready()) {
                    String linha = cargaPLU.readLine();
                    for (int i = 0; i < linha.length(); i++) {

                        ob.changeSome();
                        Item item = new Item();
                        codBarra = "";
                        quantidade = "";
                        descricao = "";
                        codInterno = "";
                        tipoProd = "";
                        while (i < 13) {
                            codBarra += linha.charAt(i);
                            i++;
                        }
                        while (i < 22) {
                            quantidade += linha.charAt(i);
                            i++;
                        }
                        while (i < 47) {
                            descricao += linha.charAt(i);
                            i++;
                        }
                        while (i < 53) {
                            codInterno += linha.charAt(i);
                            i++;
                        }
                        while (i < 54) {
                            tipoProd += linha.charAt(i);
                            i++;
                        }
                        //item.setDigitoVerificador(String.valueOf(codBarra.charAt(12))); Isso fica para depois.
                        item.setCodigoBarra(codBarra); // para excluir o digito verificador: Usar 0~12
                        item.setCodigoInterno(codInterno);
                        item.setQuantidade(quantidade);
                        item.setTipoProd(tipoProd);
                        ObjetoPublico.getCargaCod().add(item);
                           //  System.out.println("CodBarra - "+item.getCodigoBarra()+" Qnt - "+item.getQuantidade()+" descrição - "+item.getDescricao()+" codInterno - "+item.getCodigoInterno()+" tipo PRod - "+item.getTipoProd());


                    }
                }
                //cp.done();
            } catch (IOException e) {
                erro = false;
            }
            erro = true;
    

        }
    }

}

/*Fim da classe de teste*/

Segue a minha função GUI (Observer)

import dao.ItemDAO.*;

import dao.NewClass;

import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 *
 * @author HTS
 */
public class ContadorProgresso extends javax.swing.JFrame implements Observer{
    private int contador = 1;
    
    public void setLabelArquivo(JLabel LabelArquivo) {
        this.LabelArquivo = LabelArquivo;
    }

    public void setLabelCont(JLabel LabelCont) {
        this.LabelCont = LabelCont;
    }

    public JLabel getLabelArquivo() {
        return LabelArquivo;
    }

    public JLabel getLabelCont() {
        return LabelCont;
    }



    /** Creates new form ContadorProgresso */
    public ContadorProgresso(String nomeArquivo, Object a) {
        initComponents();
        setLocationRelativeTo(null);
        getLabelArquivo().setText(nomeArquivo);
        setVisible(true);
        JFrame frame2 = this;
        
        if(a instanceof NewClass){
            NewClass nc = (NewClass) a;
            nc.getOb().addObserver(this);
            nc.getOb().run();
        } else if(a instanceof ObserverArqCod){
            repaint();
            ObserverArqCod ob = (ObserverArqCod) a;
            ob.addObserver(this);
            ob.run();

        }
        
    }

    /** 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();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        LabelArquivo = new javax.swing.JLabel();
        LabelCont = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel2.setFont(new java.awt.Font("Calibri", 1, 12));
        jLabel2.setText("Arquivos Carregados");

        jLabel3.setFont(new java.awt.Font("Calibri", 1, 13));
        jLabel3.setText("Carregando o Arquivo ");

        LabelArquivo.setFont(new java.awt.Font("Calibri", 1, 13));

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel3)
                    .addComponent(jLabel2))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(LabelCont, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(LabelArquivo, javax.swing.GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE))
                .addContainerGap(22, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGap(16, 16, 16)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel3)
                    .addComponent(LabelArquivo, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 25, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel2)
                    .addComponent(LabelCont, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(36, 36, 36))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            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)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

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

    /**
    * @param args the command line arguments
    */
   

    // Variables declaration - do not modify                     
    private javax.swing.JLabel LabelArquivo;
    private javax.swing.JLabel LabelCont;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPanel jPanel1;
    // End of variables declaration                   

    

    public void atualiza(){
        getLabelCont().setText(String.valueOf(contador));
        contador++;
        pack();
        validate();
        repaint();
    }

    public void done(){
        dispose();
    }

    public void update(Observable o, Object arg) {
        System.out.println("Contador = "+contador+"Objeto Observável - "+o.toString());
        //JOptionPane.showMessageDialog(null,contador); teste
        atualiza();
    }
}

/*Fim da classe GUI*/




AGORA, Um Canto que eu tento chamar tal objeto GUI e ele instancia de forma errada (Não acusando nenhuma exception)


private boolean carregaArqCod(){
        BufferedReader cargaPLU = Conexao.arqCargaCod();
        
        ob = new ObserverArqCod(cargaPLU);
        cp = new ContadorProgresso("Teste.txt",ob);
        
        return ob.isErro();
     }

Segue a private classe ObserverArqCod

public class ObserverArqCod extends Observable implements Runnable{
        private boolean erro;
        private BufferedReader cargaPLU;

        public boolean isErro() {
            return erro;
        }

        public ObserverArqCod(BufferedReader cPLU){
            cargaPLU = cPLU;
        }

        public void changeSome(){
            setChanged();
            notifyObservers();
        }

        public void run() {
            if (cargaPLU == null) {
                erro = false;
            }
            String codBarra = "", quantidade = "", descricao = "", codInterno = "", tipoProd = "";
            try {
                while (cargaPLU.ready()) {
                    String linha = cargaPLU.readLine();
                    for (int i = 0; i < linha.length(); i++) {

                        ob.changeSome();
                        Item item = new Item();
                        codBarra = "";
                        quantidade = "";
                        descricao = "";
                        codInterno = "";
                        tipoProd = "";
                        while (i < 13) {
                            codBarra += linha.charAt(i);
                            i++;
                        }
                        while (i < 22) {
                            quantidade += linha.charAt(i);
                            i++;
                        }
                        while (i < 47) {
                            descricao += linha.charAt(i);
                            i++;
                        }
                        while (i < 53) {
                            codInterno += linha.charAt(i);
                            i++;
                        }
                        while (i < 54) {
                            tipoProd += linha.charAt(i);
                            i++;
                        }
                        //item.setDigitoVerificador(String.valueOf(codBarra.charAt(12))); Isso fica para depois.
                        item.setCodigoBarra(codBarra); // para excluir o digito verificador: Usar 0~12
                        item.setCodigoInterno(codInterno);
                        item.setQuantidade(quantidade);
                        item.setTipoProd(tipoProd);
                        ObjetoPublico.getCargaCod().add(item);
                           //  System.out.println("CodBarra - "+item.getCodigoBarra()+" Qnt - "+item.getQuantidade()+" descrição - "+item.getDescricao()+" codInterno - "+item.getCodigoInterno()+" tipo PRod - "+item.getTipoProd());
                        
                        
                    }
                }
                //cp.done();
            } catch (IOException e) {
                erro = false;
            }
            erro = true;
        }
        
    }

Note que eu faço a mesma coisa em ambos casos, no entanto o frame fica "invisível" em um dos casos, como segue o print:

http://imageshack.us/f/38/semttuloaay.png/

Muito Obrigado pessoal!!

37 Respostas

G

Ah, e outra coisa, se lá na classe ItemDAO eu tentar instanciar a classe NewClass, e usá-la, dá o mesmo erro… ou seja, o erro não está na private class Observable…

G

Já tentei com InvokeLater mas o contador não atualiza.

G

E antes que alguém pergunte… já tentei Pack, repaint, validate… o carai a 4…

B

ja tentou ler as regras do forum?

P

ja tentou ler as regras do forum?²

G

Eu Realmente li as regras…

O que tem de errado aí?

Podem me ajudar? Eu realmente tou precisando…

P

Agora, o mais importante: CÓDIGO-FONTE!!!
Agora que você já sabe o básico sobre como utilizar a formatação BB no seu texto, por favor, POR OBSÉQUIO, PELO AMOR DE DEUS, sempre que for postar código fonte no seu post, deixe-o envolvido pela tag BB de código fonte… Isso fará com que, além de seu código ficar em destaque, toda a indentação, os espaços, a fonte mono-espaçada, etc é preservada. Por exemplo, se você queisesse postar um HelloWorld básico, faça assim:

public class HelloWorld{ 
_public static void main(String[] args) { 
__System.out.println("Hello, World!"); 
_} 
}
Se você não colocar o código fonte envolto pela tag BB de código fonte, o seu programinha vai aparecer assim para a comunidade do GUJ:

public class HelloWorld{

public static void main(String[] args) {

System.out.println(Hello, World!);

}

}

Isso  fica difícil de ler pra um programinha simples desse. Imagina agora quando você coloca um programa com umas 100 linhas Fica um caos total

Sabia que muitos - inclusive eu - desistem de responder, ou melhor, desistem de ler o seu tópico se o código fonte tiver sem a formatação adequada

Caso tenha alguma dúvida sobre como utilizar alguma formatação BB, basta parar o cursor do mouse sobre o botão correspondente, que vai aparecer uma mensagem te explicando a sintaxe daquela formatação.</blockquote>

http://www.guj.com.br/java/50115-voce-e-novo-no-guj-vai-criar-um-topico-e-colar-seu-codigo-fonte-leia-aqui-antes-por-favor

G

Entendi… mals, vou criar um outro tópico; formatado…

Por favor, moderação apagar este.

P

nao precisa criar outro manolo, so editar e colocar seu codigo na tag que ta tudo certo :slight_smile:

G

Pronto, lindo e maravilhoso…

Me salvem :~!

É Algum erro de Thread, certeza…

só não sei aonde.

A

Olá Gabriel. Tudo bom?
Pra poder te ajudar precisaríamos (antes de criticar) que você colocasse seu modelo de código no padrão do fórum, utilizando as tags para implementá-lo na pergunta e ficar de forma legível pra gente.
De princípio não me parece que você tenha feito algo errado. Utilizar o padrão “Observer” é boa prática sim em ambientes Desktop. Você tentou debugar e o erro ocorreu em qual linha?
Seria importante pra gente (levando em conta que você deve ser novo na área) para podermos te dar uma sugestão. Pode ser?
Debuga aí e passa a linha em que está ocorrendo o erro. Aliás…não esquece de padronizar o teu código pra gente poder entender.

Abraço.

G

Obrigado arthurgon, Então; não acontece nenhuma Exception… o “ERRO”, pois nem erro pode-se afirmar que é; está no setVisible(true), que a janela fica em “freeze” como se outro processo estivesse sendo executado. Eu Realmente acho que é algum erro em minhas Threads, estou dando uma lida no SwingWorker…

A Formatação já foi feita.

Att.

G

Então galera, Obrigado aí, mas por esta dúvida; já foi solvida, sei que outras virão e estarei denovo.

Então, o GRANDIOSÍSSIMO problema era, meu frame estava entrando em “Freeze” que parava e outro processo era executado, a grande dúvida era: QUAL!!!

Então lancei alguns prints ao redor do meu código para saber qual Thread que estava rodando, e estranhamente, a minha GUI estava rodando em uma outra thread, sem ser a main. Isso me deixou com uma pulga atrás da orelha, ATÉ QUE FINALMENTE, eu lhi e vi que o

FILHO DA PUUUUUUUUUUUUUUUUU** do NetBeans, não instanciava o GUI com new Frame().setvisible(true)… ele dava um InvokeLater, que jogava meu GUI para outra thread, separando-o da Main.

Então deletei o invokelater, e instanciei normal; e tudo se resolveu-se.

UMA SEMANA nisso. E Finalmente … its over.

G

Gabriel Lopes:
Então galera, Obrigado aí, mas por esta dúvida; já foi solvida, sei que outras virão e estarei denovo.

Então, o GRANDIOSÍSSIMO problema era, meu frame estava entrando em “Freeze” que parava e outro processo era executado, a grande dúvida era: QUAL!!!

Então lancei alguns prints ao redor do meu código para saber qual Thread que estava rodando, e estranhamente, a minha GUI estava rodando em uma outra thread, sem ser a main. Isso me deixou com uma pulga atrás da orelha, ATÉ QUE FINALMENTE, eu lhi e vi que o

FILHO DA PUUUUUUUUUUUUUUUUU** do NetBeans, não instanciava o GUI com new Frame().setvisible(true)… ele dava um InvokeLater, que jogava meu GUI para outra thread, separando-o da Main.

Então deletei o invokelater, e instanciei normal; e tudo se resolveu-se.

UMA SEMANA nisso. E Finalmente … its over.

Sei que depois de tanta dor de cabeça você não vai querer mexer no que está funcionando, mas tem algumas coisas que não estão 100% corretas nessa aplicação, e infelizmente só está funcionando por uma coincidência.

Primeiro algo simples, é apenas uma correção de conceito que não deve interferir de imediato no funcionamento: a relação entre Observer e Observable está um pouco distorcida, pois o Observer está GERENCIANDO o Observable (é ele quem inicia a tarefa!), ao invés de apenas observar.

A segunda é a questão das threads.
TUDO o que o swing faz acontece dentro de sua própria thread (chamada de Event Dispatching Thread). Ou seja, diferente do que vc colocou, não é a chamada ao InvokeLater que faz isso. Com ou sem ele, a GUI roda na Event Dispatching Thread.
A diferença é que, chamando o invokeLater, a instanciação das classes também vai para a thread do swing. Depois de instanciadas as classes da GUI, de uma forma de outra essa thread é que assume o controle.
E essa é a recomendação da Sun: apenas a Event Dispatching Thread deve manipular componentes, pois a maioria de seus métodos não são thread-safe e podem acontecer coisas malucas caso tenha mais de uma thread mexendo (por exemplo, a thread main e a Event Dispatching Thread). Portanto o código gerado pelo Netbeans está correto segundo as recomendações.

Então por que funcionou depois de retirar o invokeLater? A resposta é: por acaso! E isso não é bom :frowning:
Ao iniciar a GUI direto no main, você passou a ter duas threads trabalhando, sem perceber. Tente analisar o código e descobrir porque… se quiser discutir o assunto, estamos aí.

Boa sorte!

G

Muito Obrigado gomes, deu para entender muito do que você disse, sou novo em java e MAIS NOVO AINDA em thread, vou ter que dar uma estudada legal, se quiser me ajudar a descobrir por que funcionou… hauhaha o código está aí… realmente eu pensei em mexer e ultilizar o SwingWorker para ficar mais elegante, já que se trata de uma Thread Worker… mas o prazo… sabe como é, e eu perdi 1 semana nisso… foi muito foda. Eu achei que seria simplíssimo… ( e seria, se eu soubesse Observer, Observable e Thread; demorou pois tive que estudar isso )…

V

Olá.

Se seu tópico é urgente, procure seguir essas dicas para ser atendido mais rapidamente, e da forma correta:

  1. Poste-o na sessão certa do fórum. Vale a pena perder alguns minutinhos lendo a lista de fóruns, você perceberia que temos um chamado interface gráfica para dúvidas de Swing, e outro chamado Java avançado, para threads e afins. Mas o que seu tópico não é, é um tópico de Java Básico.
  2. Dê um título descritivo no seu tópico. “Jamais vi isso” não chama a atenção de quem realmente pode te ajudar.
  3. Poste o código sempre usando a TAG code.
  4. Use a busca do fórum. Deve ter pelo menos uns 30 tópicos aqui só falando de barra de progresso, com exemplos funcionais, usando Threads ou o Swing worker. Eu mesmo já postei 2 deles. E também já postei 2 tópicos explicando detalhadamente o funcionamento do invokeLater.
  5. Finalmente, NÃO ESCREVA TÍTULOS COM LETRAS MAIÚSCULAS ou coloque pressão sobre os membros do fórum. Todos nós temos nossas urgências, e a sua não é mais especial que a de ninguém.

Agora que você já resolveu a dúvida, edite seu primeiro post e escreva [Resolvido] antes do título. Na verdade, aproveite para alterar o título para algo mais descritivo, como deveria ter sido desde o início, para que futuros gujnautas que usam a busca do tópico possam entender do que ele se trata sem ter que abri-lo.

G

Feito, obrigado Vinnigodoy.

G

Então GUJZeiros, meu Problema não Foi Resolvido totalmente, quando eu REFAÇO tal processo, que a thread corrente é a AWT-EventQueue-0 (é isso que aparece quando dou um Thread.getName() ), meu GUI Abre freeze novamente.

Realizei o código abaixo criando uma thread para o GUI, mas sem sucesso.. preciso de uma luz :~

private boolean carregaArqCod(){
        Ambiente a = ObjetoPublico.getAmbiente();
        final String nomeArqCod = a.getTabelaEAN13();

        ObserverArqCod oc = new ObserverArqCod();


        cp = new ContadorProgresso(nomeArqCod);
        Thread t2 = new Thread(cp);
        t2.setPriority(Thread.MAX_PRIORITY);
        t2.start();
        
        oc.addObserver(new MeuObserver(cp));
        oc.run();
        

        cp.dispose();
        return true;
     }

Att.

G

Funcionaria se o construtor de ContadorProgresso nao estivesse startando o processo todo na thread atual.
Além dessa alteração que vc acabou de mostrar, remova o ob.run(); do construtor .

Ainda não é o ideal, que seria manipular a GUI somente na Event Dispatch Thread, mas já fica bem melhor que o jeito atual, pois pelo menos vc está explicitamente delegando o processamento para outra thread.

G

Esqueci de postar, fiz outras modificações além dessas:

public ContadorProgresso(String nomeArquivo) {
        initComponents();
        
        getLabelArquivo().setText(nomeArquivo);
    }

Este é meu novo construtor… eu achei que tudo estaria Ok, pois eu estava criando uma thread só para o GUI, e ainda sim ele está entrando em freeze…

Só não entra em freeze na primeira vez que eu passo, que não usa aquele invokeLater, na segunda passada; onde o programa já iniciou, ele entra em freeze.

:// Realmente não entendo…

G

Posta o código completo mais atualizado…

G

/*Aqui é onde inicia o meu Programa, onde tinha um InvokeLater*/

public static void main(String args[]) {
        new TelaInicial().setVisible(true);
}

/*Mudando meu programa inicial, aqui é minha nova classe contadorProgresso, que rodará em um thread e será atualizado por uma classe Observer*/

public ContadorProgresso(String nomeArquivo) {
        initComponents();
        
        getLabelArquivo().setText(nomeArquivo);
    }

public void atualiza(){
        getLabelCont().setText(String.valueOf(contador));
        contador++;
    }

 public void run() {
        
        System.out.println("THREAD DO SWING - "+Thread.currentThread().getName());
        setLocationRelativeTo(null);
        setVisible(true);
    }

/*Aqui é uma classe que tem duas classes privadas, uma que implementa
Observer, outra que extende observable*/

private boolean carregaArqCod(){
        Ambiente a = ObjetoPublico.getAmbiente();
        final String nomeArqCod = a.getTabelaEAN13();

        ObserverArqCod oc = new ObserverArqCod();


        cp = new ContadorProgresso(nomeArqCod);
        Thread t2 = new Thread(cp);
        t2.setPriority(Thread.MAX_PRIORITY);
        t2.start();
        
        oc.addObserver(new MeuObserver(cp));
        oc.run();
        

        cp.getBotaoOk().setVisible(true);
        return true;
     }

/*Classes privadas*/

public class ObserverArqProd extends Observable implements Runnable{
        private boolean sucesso = false;

        public boolean isSucesso() {
            return sucesso;
        }

        public void changeSome(){
            setChanged();
            notifyObservers();
            System.out.println("aaa");
        }
        
        public void run() {
            BufferedReader cargaProd = Conexao.arqCargaProd();

        if(cargaProd == null){
            sucesso = false;
        }

        String codInterno = "", descricao = "", precoVRJ = "", precoATC = "", codOrigem = "";
        String codTributacao = "", aliqTribInterna = "",aliqReducao = "", quantidade = "";
        String tipoLimite = "", quantidadeLimite = "";

        try{
            while(cargaProd.ready()){
                String linha = cargaProd.readLine();
                for(int i = 0;i < linha.length(); i++){
                    
                    changeSome();
                    Item item = new Item();
                    codInterno = "";
                    descricao = "";
                    quantidade = "";
                    precoVRJ = "";
                    precoATC = "";
                    codOrigem = "";
                    codTributacao = "";
                    aliqTribInterna = "";
                    aliqReducao = "";
                    tipoLimite = "";
                    quantidadeLimite = "";

                    while(i < 6){
                        codInterno += linha.charAt(i);
                        i++;
                    }
                    while(i < 36){
                        descricao += linha.charAt(i);
                        i++;
                    }
                    while(i < 38){
                        quantidade += linha.charAt(i);
                        i++;
                    }
                    while(i < 46){
                        precoVRJ += linha.charAt(i);
                        i++;
                    }
                    while(i < 54){
                        precoATC += linha.charAt(i);
                        i++;
                    }
                    while(i < 55){
                        codOrigem += linha.charAt(i);
                        i++;
                    }
                    while(i < 57){
                        codTributacao += linha.charAt(i);
                        i++;
                    }
                    while(i < 61){
                        aliqTribInterna += linha.charAt(i);
                        i++;
                    }
                    while(i < 65){
                        aliqReducao += linha.charAt(i);
                        i++;
                    }
                    while(i < 66){
                        tipoLimite += linha.charAt(i);
                        i++;
                    }
                    while(i < 70){
                        quantidadeLimite += linha.charAt(i);
                        i++;
                    }

                    item.setCodigoInterno(codInterno);
                    item.setCodOrigem(codOrigem);
                    item.setAliqReducao(aliqReducao);
                    item.setAliqTribInterna(aliqTribInterna);
                    item.setDescricao(descricao);
                    item.setTipoLimite(tipoLimite);
                    item.setQuantidade(quantidade);
                    item.setPrecoUnitarioATC(precoATC);
                    item.setPrecoUnitarioVRJ(precoVRJ);
                    item.setCodTributacao(codTributacao);


                    ObjetoPublico.getCargaProd().add(item);

                  
                }
            }
        }catch(IOException e){
            sucesso = false;
        }
        sucesso = true;

        }

    }

    private class MeuObserver implements Observer{
        private ContadorProgresso cp;

        public MeuObserver(ContadorProgresso cp){
            this.cp = cp;
        }

        public void update(Observable o, Object arg) {
            cp.atualiza();
        }

        

    }
}
[code]

Obrigado!

G

Dá uma arrumada, um pedaço ficou formatado como [ code ] e outro não

G

Vi agora, mals… pronto

G

Tem alguns erros de compilação…

  • Em que classe está o método carregaArqCod, e quem o chama?
  • Como é chamado o construtor new Thread(ContadorProgresso) ? ContadorProgresso virou Runnable?
  • Qual é a diferença entre ObserverArqCod e ObserverArqProd ?
  • O que faz o construtor TelaInicial() ?

Se quiser colaborar mais ainda, crie uma versão simplificada do código que demonstre especificamente o seu problema, sem precisar do ambiente completo, com arquivos, utilitarios de conexão, etc.
Uma classe que qualquer um no fórum possa colar no Eclipse e ver exatamente o problema que vc está tentando resolver.

Eu estava tentando justamente criar esse código simplificado quando esbarrei nos problemas acima. Se quiser dar uma olhada, segue em anexo.

G

Sim, o contador virou Runnable, a diferença dos Observables, é que um lê um tipo de arquivo, e o outro lê outro tipo.

o Construtor TelaInicial() aciona o ItemDAO, com método
"cargaPLU", do cargaPLU ele vai lê os dois arquivos, chamando os observables.

Entendo, eu tou resolvendo umas coisas, e assim que puder eu faço isso daí, obrigado!

Mas, o problema é aquele freeze :~.

G

Teve uma ligeira comida de bola ao colocar o processamento em thread separada.

Aqui:

Thread t2 = new Thread(cp); t2.setPriority(Thread.MAX_PRIORITY); t2.start();
Você colocou o contador de progresso como Runnable da thread, mas veja o que o run() dele faz:

setLocationRelativeTo(null);
setVisible(true);

Absolutamente nada que vá consumir tempo para ser realizado! Apenas manda exibir a janela, isso é instantâneo e não tem motivo para estar em outra thread.

Isso sim gasta tempo:

ObserverArqCod oc = new ObserverArqCod();
//...
oc.run();   // Aqui está todo o processamento! É o que deveria ir para uma nova thread.

Então o ContadorProgresso nao tem por que ser Runnable, pode tirar isso. Deixe o setVisible em algum outro lugar qualquer.
E o “oc” é que precisa ser iniciado dentro de uma thread.

Tente fazer aí e diga no que deu.

V

Removido do título o “DUVIDA URGENTE”.

G

Fiz isso gomes, deu em nada; continuou no freeze… colocar o cp como runnable foi apenas um teste, pra ver se separava ele de todo o processo e para ver se tirava o Freeze dele…

ViniGodoy, minha dúvida ainda é Urgente.

Obrigado pela ajuda gomes.

G

Que estranho!

Rodei um teste aqui, é o seu programa sem a parte da leitura de arquivo, que troquei por Sleep apenas para simular um processamento demorado.

Importe essas classes para um projeto no eclipse e veja se vc está fazendo alguma coisa diferente.

G

Novamente gomesrod, muito obrigado por está me ajudando em tal projeto.

Sim, como eu falei a PRIMEIRA PASSADA, Funciona. Tente criar uma outra classe, instanciar a start, executá-la, e após crie um botão, onde você aperte e refaça o processo, pois é assim que está no meu original.

Logo farei isso e postarei aqui, se preferir fazer…

Obrigado !

G

Beleza, então quando puder coloca o botão para que possamos entender melhor o que acontece na situação exata do erro.

V

Isso pouco importa para o fórum.
Se você tem urgência real, pague uma consultoria para ajuda-lo segundo sua agenda.

Como já falei no outro post, é considerado falta de educação apressar membros do fórum, ou chamar atenção para seu tópico. Todos temos nossas urgências e prioridades, e seu tópico não é mais importante que o de ninguém (além disso, se deixarmos URGENTE no título, logo, logo, todos os títulos estarão marcados assim. Quem é que quer ser atendido por último?).

G

Ok, quando poder parar de reclamar e, quem sabe, olhar o meu problema; se puder é claro, agradecerei infinitamente.

Obrigado desde já.

V

Não é questão de reclamar, Gabriel. Sou moderador do fórum, e devo orientar usuários a se como se portar aqui.

Quanto ao seu problema específico, infelizmente não posso te ajudar no momento, pois ando bastante atarefado em meu trabalho e tenho praticamente só ajudado nas tarefas de moderação.

G

Foi isso que eu fiz…

Cara, eu acho que tu resolveu o problema, colocando o processo numa thread… depois vou verificar isso, estou em casa.

eu SÓ acho… pois sempre que eu tentava debugar, e dava um setVisible no COntadorProgresso; o frame já abria em freeze, e não dava certo… o teu abriu em freeze mas deu certo…

vlw.

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { Start s = new Start(); s.iniciar(); }

V

Eu normalmente resolvo problemas como esse assim:

  1. Crio um listener, para a interface gráfica implementar, que vai ser informado do estado do meu processamento. Pode conter método como:

public interface ProcessamentoListener { void processamentoComecou(String nome, int total); void processou(int pos, int total); void processamentoTerminou(bool completo); }

  1. Faço a interface gráfica implementar esse listener, e usa-lo para atualizar o ProgressBar;

  2. Crio uma classe que irá realizar o processamento, cujo código irá rodar numa thread separada. No caso, a classe que tem o Runnable. Ela dispara esses eventos para os listeners dela, já na thread do Swing (usando EventQueue.invokeLater) a medida que o processamento anda.

A vantagem dessa solução é que é relativamente fácil vc criar um JDialog genérico para barras de progresso (o observer), que funcione para qualquer um que implemente esse listener (observable). Foi iso que fiz no meu Editor de imagens.

Criado 14 de outubro de 2011
Ultima resposta 18 de out. de 2011
Respostas 37
Participantes 6