Cronometro, a duvida continua

10 respostas
R

auhhh, eai pessola, ja perguntei varias vezes sobre esse bendito cronometro que naum to conseguindo implementar, ate agora o que eu tenho é isso:

public class Cronometro implements Runnable{
    private long mil, inicio;
    private int min = 0;
    private int seg = 0;
    private int cent = 0;
    private int mile = 0;
    /** Creates a new instance of cronometro */
    public Cronometro(){
    }
    
    public String crono(boolean start){
        String tempo = "";
        
        inicio = System.currentTimeMillis();
        
        while(start){ //se start for true faça
            mil = System.currentTimeMillis(); 
            mil = mil - inicio; //tira a diferença do tempo inicial com o tempo atual
            
            //contador dos milesegundos
            if(mile < 1000){
                mile++;
            }
            else{
                mile = 0;
                cent++;
            }
            
            //conta os segundos e zera os centesimos
            if (cent >= 99){
                cent = 0;
                seg++;
            }
            //conta os minutos e zera o segundos
            if(seg >= 59){
                seg = 0;
                min++;
            }
            
            //passa para o formato correto
            if(min < 10){
                min = Integer.parseInt("0" + String.valueOf(min));
            }
            if(seg < 10){
                seg = Integer.parseInt("0" + String.valueOf(seg));
            }
            if(cent < 10){
                cent = Integer.parseInt("0" + String.valueOf(cent));
            }
            
            //concatena
            tempo = String.valueOf(min) + ":" + String.valueOf(seg) + ":" + String.valueOf(cent);
            System.out.println(tempo);
            return tempo;
        }
        return tempo;
    }

    public void run() {
        crono(true);  //com ou sem esse comando ele não funciona
    }
}

e o chamo dessa forma na minha classe principal:

if(jbCronometro.getText() == "Iniciar"){
            jbCronometro.setText("Parar");  //muda o label do botão
            new Thread(cr).start();  //executa a classe Cronometro
            //System.out.println(cr.crono(true));
        }
        else{   
            new Thread(cron).stop(); //seria para parar o tempo, mas naum faz nd, so da um warning [deprecation] in java.lang.Thread has been deprecated.
            jbCronometro.setText("Iniciar"); //muda o label do botão
            //System.out.println(cr.crono(false));
        }

O problema é o seguinte, naum estou conseguindo fazer com que o tempo apareça correndo, ele so incrementa o tempo a cada clique no botão e naum a cada centesimo, e tbm qual é o comando que faz parar de correr o tempo? ja que stop esta me parecendo que naum é?

Mas é isso, desde ja agradeço.
Vlw

10 Respostas

R

POR FAVOR ME AJUDEM

neofito

Meu amigo, toma vergonha nessa sua cara de pau, a faz a porcaria da tua lição de casa…

Nem sei pq tô respondendo ainda…

R

aki é um site pra tirar duvidas, ajuda quem quer

Dieval_Guizelini

Rafael,

como é um exercício eu não vou te dar a solução pronta, mas vou te dar algumas dicas, veja esta parte do seu código:

if(jbCronometro.getText() == "Iniciar"){ new Thread(cr).start(); //executa a classe Cronometro } else{ new Thread(cron).stop(); //seria para parar o tempo, mas naum faz nd, so da um warning [deprecation] in java.lang.Thread has been deprecated. }

o segundo new, cria um novo objeto thread e ai você pede para parar o segundo objeto e não a thread do primeiro.

Segunda dica: A informação que você quer atualizar a partir da thread cronometra esta no objeto que cria a thread, mas você não passa uma referência desse objeto para a thread. Segundo, o cronometro não passa para o objeto original (ou thread primária) a informação do tempo corrido.

e dê mais uma olhada nesta outra parte do seu código:

mil = System.currentTimeMillis();   
            mil = mil - inicio; //tira a diferença do tempo inicial com o tempo atual   
               
            //contador dos milesegundos   
            if(mile < 1000){

Será que você não queria:

mile = mil - inicio; //tira a diferença do tempo inicial com o tempo atual

Threads são linhas de execução em paralelo, mas também são objetos e você deve tratá-los da mesma forma para a troca de mensagens entre elas.

fw e bom estudo.

R

Dieval, mas como assim eu posso receber o parametro da classe cronometro, tive que retirar o metodo crono que fazia a operação, coloquei tudo dentro do metodo run, agora o cronometro funciona, so não esta sendo atualizado na frame, ja tentei instanciar minha classe principal e chamar um metodo que faça essa atualização passando como parametro o valor final, so que da erro de estouro de pilha, tbm tentei usar o extends, e usar o metodo direto na classe filha(cronometro), mas tbm da erro de pilha.

Não entendi o que vc quiz dizer com, passar referencia para a thread, meu comando esta assim:

<blockquote>        SComm sc = new SComm();

new Thread(sc).start();

sc.HabilitarLeitura();

sc.ObterIdDaPorta();

sc.AbrirPorta();

sc.LerDados();</blockquote>

isso la no construtor da minha tela principal. como vou passar um parametro por ele ou receber?

Há e sobre o erro de codigo do comando mile, realmente estava errado, so que naum sei pq esta cronometrando o tempo corretamente, sem ter corrigido akele erro. Mostrei os valores com um system print e fui vendo no relogio e estão sendo mostrados certo.

Vlw

Dieval_Guizelini

Veja esse exemplo:

public class JanelaFrame extends javax.swing.JFrame {
    public JanelaFrame() {
        initComponents();
    }
    public void novoValor(String s) {
        jLabel1.setText(s);
        jLabel1.updateUI();
    }
    public static void main(String[] args) {
        Cronometro c = new Cronometro();
        JanelaFrame jan = new JanelaFrame();
        jan.setVisible(true);
        c.setJanela(jan);
        c.start();
        System.out.println("O método main acabou de ser executado.");
    }
                         
    private void initComponents() {
        jLabel1 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        jLabel1.setText("jLabel1");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(111, 111, 111)
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 108, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(181, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(100, 100, 100)
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(142, Short.MAX_VALUE))
        );
        pack();
    }  
    private javax.swing.JLabel jLabel1;
}
Preste atenção nesta parte do código:
Cronometro c = new Cronometro();
       (...)
        c.setJanela(jan);

e a thread cronometro:

public class Cronometro extends Thread {
    private long tempo,inicio = 0L;
    private JanelaFrame janela;
    public Cronometro() { }
    public void run() {
        inicio = System.currentTimeMillis();
        do {
            tempo = System.currentTimeMillis() - inicio;
            janela.novoValor(""+tempo);
            try {
                Thread.currentThread().sleep(5);
            } catch( InterruptedException i) { }
        } while( tempo < 10000 );
        System.out.println("O que tinha que ser feito aqui foi concluído.");
    }
    public void setJanela(JanelaFrame janela) {
        this.janela = janela;
    }
}

e novamente nesta linha no método run:

janela.novoValor(""+tempo);

fw

R

Cara, isso naum da pra fazer ja tentei fazer instanciando minha classe principal e chamnado meu metodo que atualiza o campo:

principal pri = new principal();

e la no final do metodo run, depois de executar todas as operações que preciso, coloco: pri.atualizaInfo(tempo);

deu o mesmo erro que fazendo desse jeito que eu entendi que vc me passou:
Classe principal:

//instancio as classes
private Cronometro cr = new Cronometro();   
private principal pri = new principal();

//no botão que executa o cronometro
    private void jbCronometroTP1ActionPerformed(java.awt.event.ActionEvent evt) {                                                
// TODO add your handling code here:
        if(jbCronometroTP1.getText() == "Iniciar"){
            jbCronometroTP1.setText("Parar");
            cr.setFrame(pri);
            new Thread(cr).start(); 
            //System.out.println(cr.crono(true));
        }
        else{   
            cr.stop(); 
            jbCronometroTP1.setText("Iniciar");
            //System.out.println(cr.crono(false));
        }
    }
Minha classe cronometro:
public class Cronometro /*extends principal*/ implements Runnable{
    private boolean comece;
    public String tempo = "";
    private principal pri; 
    
    //private principal pri = new principal();
    
    /** Creates a new instance of cronometro */
    public Cronometro(){
    }

    public void run() {        
        comece = true;
        
        inicio = System.currentTimeMillis();
        
        while(comece){
                //executa toda a operação
        }
    }
    public void stop(){ //finaliza a execução
        comece = false;
    }

Mesmo usando extends e instanciando a classe principal na classe cronometro, da erro de estouro de pilha, overStack.

Tem alguma outra forma de fazer essa atualização, so falta isso pra mim terminar, meu projeto, ja faz comunicação com bancos de dados, com porta serial, faz tudo, menos atualizar os campos da tela principal

Vlw

public void setFrame(principal pri){ //seta a frame
this.pri = pri;
}
}

Dieval_Guizelini

Em primeiro lugar você poderia ter copiado e executado o meu código,

mas vamos continuar olhando o seu código e observar o seguinte:

if(jbCronometroTP1.getText() == "Iniciar"){   
            jbCronometroTP1.setText("Parar");   
            cr.setFrame(pri);   
            new Thread(cr).start();
Nessa parte do seu código, já tem melhorias, afinal você tá passando um objeto para a classe Cronometro, só não sei se é o objeto correto. Você poderia fazer assim:
cr.setFrame(this);

Outro ponto, vale a pena você dar uma olhada nesse método do ActionEvent getActionCommand().

Mas volto a te dizer que, neste ponto:

new Thread(cr).start();

você deveria preservar a referência do objeto thread criado.

e na classe cronometro, você tem que acertar alguns detalhes, tais como:

public class Cronometro /*extends principal*/ implements Runnable{  
   private boolean comece = true;   // opção 1
    public String tempo = "";   
    private principal pri;   
       
    //private principal pri = new principal();   
       
    /** Creates a new instance of cronometro */   
    public Cronometro(){   
          comece = true;   // opção 2
    }   
  
    public void run() {           
       // comece = true;   
       setComece( true );
           
        inicio = System.currentTimeMillis();   
           
        while( isComece() ){   
                //executa toda a operação   
               pri.atualizaLabel( tempo );    // veja que a variável tempo é algo que você já possui com outro nome e tem que ser String
        }   
    }   
    public synchronized void stop(){ //finaliza a execução   
        comece = false;   
    }  
    public synchronized boolean isComece() { return comece; }
   public synchronized void setComece( boolean comece ) { this.comece = comece; }
}

A sua propriedade comece poderá ser acessada por duas threads diferentes ao mesmo tempo, portanto ela precisa de synchronized.
Desta forma deve funcionar.

R

Cara, muito obrigado, agora funcionou do jeito que eu queria.

Vlw.

Dieval_Guizelini

fw

Criado 17 de outubro de 2007
Ultima resposta 21 de out. de 2007
Respostas 10
Participantes 3