Relogio parando...?

14 respostas
fernandopaiva

salve galera…

Eu consegui fazer o relogio aqui: http://www.guj.com.br/posts/list/224210.java

bem, o relogio ta funcionando blzinha…Mas o problema q eu tenho agora e que consigo faze-lo executar apenas uma vez, e não estou entendendo pq …eu pensei que fosse algo na memoria, mas li e reli o codigo e vi que estou usando referencias diferentes na memoria.
vou tentar explicar melhor…

Eu tenho 6 panels, cada 1 tem um JLabel que exibe o relogio, isso funciona em partes, o caso e que consigo faze-lo exibir em apenas um JLabel por vez…se eu clicar nos outros JLabel ele vai exibindo o relogio mas vai parando os outros que abri nos outros JPanels…vejam o codigo.

/*aqui eu dou um for para pegar todos os components do panel principal que e JPanel1, ele pega os outros panels e seus 
componentes e manda para a classe ControlaPanels
*/

ControlaPanels controlaPanels = new ControlaPanels(); //essa e a instancia da classe que executa os relogios nos panels
for(int x = 0; x < jpanel1.getComponentCount();x++){
      JPanel painel = (JPanel)jPanel1.getComponent(x);
      controlaPanels.setPanel(painel);

      //controlaPanels.setLabelRelogio recebe JLabel do relogio
      JLabel horaCorrente = (JLabel)painel.getComponent(0);
      controlaPanels.setLabelRelogio(horaCorrente);

      //chamo metodo na classe ControlaPanels que ativa os panels com os componentes para cada laço do for.      
      controlaPanels.ativaPanel(); 

 ///ate aqui td funcionando blzinha...
}


public class ControlaPanels {
     private SimpleDateFormat horaFormatada = new SimpleDateFormat("HH:mm:ss");
     private static JPanel panel;
     private static JLabel relogio;
     private String horaCorrente;

     //recebo panel
     public void setPanel(JPanel panel){
            this.panel = panel;
     }

     //aqui seto o relogio com o valor recebido 
     public void setLabelRelogio(JLabel horaCorrente){
            this.relogio = horaCorrente;
     }

     //aqui seto as definicoes do relogio
     public void setHoraCorrente(Date date){
        this.horaCorrente = horaFormatada.format(date);
        this.relogio.setText(horaCorrente);
        this.relogio.setVisible(true) //relogio vindo do panel o estado e false, aqui dou true
    }

   //inicia relogio
    public void iniciaHoraCorrente() {
        ActionListener action = new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 setHoraCorrente(new Date());
             }
        };
        Timer timer = new Timer(1000,action);
        timer.setInitialDelay(0);
        timer.setRepeats(true);
        timer.start();
       }
   }

    public void ativaPanel(){
         // ativa o panel com o relogio
             iniciaHoraCorrente();
    }

Esta tudo funcionando conforme manda o figurino, so nao entendo o pq de o relogio funcionar para 1 panel apenas, eu pensei que fosse referencia de memoria conforme havia dito antes, mas relendo o codigo não consigo achar o pq de não funcionar, principalmente pq o new Timer() cria outro objeto timer na memoria…entaum naum sei realmente o pq de naum funcionar.

alguma sugestão ???

14 Respostas

E

Use este relógio aqui. Você pode adaptá-lo.

http://www.guj.com.br/posts/list/208780.java#1061757

fernandopaiva

Opa entanglement, eu fiz a adaptacao que vc flw…funciona da msma maneira que antes, quando ativo mais de um panel o relogio se exibe apenas no ultimo panel que eu ativei…

ex.

panel1 ativo relogio 10:00:01 —> panel2 ativo relogio 10:30:30 “parou relogio panel1”…
e por ai vai…todos os panels ativos tem q ter o relogio executando, mas qdo ativo outro panel depois de um ja ativo, ele para o que esta ativo.

//adaptacao proposta...

public void iniciaHoraCorrente() {
        horaCorrente.setVisible(true);
         timerSistema = new Timer(1000, new ActionListener(){
             public void actionPerformed(ActionEvent e) {
                 horaCorrente.setText(horaFormatada.format(new Date()));
             }
        });
        timerSistema.start();
        
    }

obrigado

E

Vou modificar o exemplo para você entender o que eu queria transmitir.

package guj;

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ExemploRelogio extends JFrame {

    private static final long serialVersionUID = 1L;
    private JPanel jContentPane = null;
    private JPanel pnlMain = null;
    private Relogio rel01 = null;
    private Relogio rel02 = null;
    private Relogio rel03 = null;

    private Relogio getRel01() {
        if (rel01 == null) {
            rel01 = new Relogio();
            rel01.setFormato("dd/MM/yyyy HH:mm:ss.SSS");
        }
        return rel01;
    }

    private Relogio getRel02() {
        if (rel02 == null) {
            rel02 = new Relogio();
            rel02.setFormato("hh:mm:ss a");
        }
        return rel02;
    }

    private Relogio getRel03() {
        if (rel03 == null) {
            rel03 = new Relogio();
            rel03.setFormato("dd 'de' MMMMM 'de' yyyy, HH:mm:ss");
        }
        return rel03;
    }

    private JPanel getPnlMain() {
        if (pnlMain == null) {
            pnlMain = new JPanel();
            pnlMain.setLayout(new BorderLayout());
            pnlMain.add(getRel01(), BorderLayout.NORTH);
            pnlMain.add(getRel02(), BorderLayout.CENTER);
            pnlMain.add(getRel03(), BorderLayout.SOUTH);
        }
        return pnlMain;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                ExemploRelogio thisClass = new ExemploRelogio();
                thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                thisClass.setVisible(true);
            }
        });
    }

    public ExemploRelogio() {
        super();
        initialize();
    }

    private void initialize() {
        this.setSize(300, 200);
        this.setContentPane(getJContentPane());
        this.setTitle("JFrame");
    }

    private JPanel getJContentPane() {
        if (jContentPane == null) {
            jContentPane = new JPanel();
            jContentPane.setLayout(new BorderLayout());
            jContentPane.add(getPnlMain(), BorderLayout.NORTH);
        }
        return jContentPane;
    }

}
package guj;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JLabel;
import javax.swing.Timer;

public class Relogio extends JLabel {

    public Relogio() {
        super();
        timerAtualizacao = new Timer(500, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                setText(df.format(new Date()));
            }
        });
        timerAtualizacao.start();
    }

    public void setFormato(String formato) {
        df = new SimpleDateFormat(formato);
    }

    private Timer timerAtualizacao;
    private DateFormat df = new SimpleDateFormat("HH:mm:ss");
}


fernandopaiva

entanglement, eu entendi seu exemplo…para cada JPanel criado vc chama um relogio diferente…!!!

Eu ja tenho essa estrutura aqui…veja.

public class ControlaPanels {
    private Timer timer;
    private static JPanel panel;
    private static JLabel relogio;
    public setPanel(JPanel panel){
        this.panel = panel;  //aqui eu recebo o panel que vem da classe onde crio os panels depois eu igualo a panel
        System.out.println(panel.getName()); //aqui ele mostra panel1, panel2, panel3....ate o 50, que e a qtd de panels
    }
   
   public setRelogio(JLabel relogio){ //label vindo de outra classe q e pego com panel.getComponent(2)
         this.relogio = relogio;  //seta a variavel panel com a variavel q chega.
   }
}

//relogio vai aqui.

Entaum o JLabel que quero exibir o relogio esta dentro destes panels e recebo eles vindos de outra classe que exibe os panels da seguinte maneira…panel1.getComponent(1), panel2.getComponent(2) e por ai vai…claro faço td num laço for, para ir passando e ativando a cada laço, como falei acima…ou no click do mouse eu ativo de um em um.

Quando o panel e os labels chegam nessa classe, e que eu vou trata-los…por exemplo: “panel1.setBackground”, “jlabelData.setText” e por ai vai…

Td funciona, ate o relogio funciona. Mas qdo clico em outro panel ou envio outro, esse relogio para de funcionar no que estava para funcionar no que acabei de clicar…Entaum eu vi ai que vc intancia um objeto relogio para cada panel…mas, eu ja to fazendo isso, de uma outra maneira. So naum entendo o pq q esse relogio para qdo clico em outro panel sendo que e enviado outro panel e naum o msm, pq a cada panel q eu clico o processo e o msm, ou seja, ele envia td de novo e deveria ficar executando o tempo todo em todos os panels, a naum ser que seja endereço de memoria, como falei acima…

obrigado novamente…!

fernandopaiva

Tentei ate com Thread e num vai…kkkk !!! Num to conseguindo entender o que ta acontecendo pra ele parar de executar os relogios dos panels…

fiz a thread:

public class ControlaPanels implements Runnable {
        //controla paineis
        private static JPanel panel = null;
        private static JLabel relogio = null;
        
         public JPanel setPanel(JPanel panel){
             this.panel = panel;
        }

        public JLabel setRelogio(JLabel relogio){
              this.relogio = relogio;
        }

       public void run() {
           rodaRelogio();
       }


       public void rodaRelogio(){
          this.relogio.setVisible(true);
          while(true){
            String hora = horaFormatada.format(new Date());
            this.relogio.setText(hora);
          }
 
}


public class Panels {
   
 //cria panels do select na tabela controlapanels no bd
public void criaPanels {
    while(rs.next()){
                reg++;
                JPanel panel = new JPanel();
                panel.setName("panel" + reg);

                // label de indice 1 dentro do panel
                JLabel horaCorrente = new JLabel("Relogio", JLabel.CENTER); //relogio
                horaCorrente.setName("horaCorrente");
                horaCorrente.setVisible(false);
      }

      public void mandaPanelsControlaPanels(){
               //faco isso no click do mouse ou num for em outro metodo...
              
                      ControlaPanels controlaPanels = new ControlaPanels();
                        //manda o panel para ControlaPanels
                        JPanel painel = (JPanel) e.getComponent();
                        controlaPanels.setPanel(painel);

                        //manda o JLabel relogio para ControlaPanels
                        JLabel relogio = (JLabel) painel.getComponent(1);
                        controlaPanels.setRelogio(relogio); //manda jlabel relogio para ControlaPanels    
                        Thread t = new Thread(controlaPanels);
                         t.start();
      }
}

Nem assim funciona, se eu clico em um dos panels o relogio do panel anterior para…Não entendo o que pode estar acontecendo. !

Alguma sugestão ???

obrigado.

E

Alguém pode checar o que ele está fazendo? Não consegui ler o código ainda,

fernandopaiva

E simples…

(1)Cria uma classe para controlar os panels ess classe tem o nome de ControlaPanels, ela vai receber os JPanel e seus componentes JLabel, nessa classe fica o relogio ou thread
(2)Cria uma classe que cria os panels num for ou num while, 1 ou 2 ou mais…

exemplo da classe que cria panels

//exemplo da classe que cria panels
int i = 0;
while(i < 50){ //vai criar 50 panels e seus labels
     JPanel panel = new JPanel(); //cria panels
     panel.setName("panel" + i++); //nome dos panels
     JLabel relogio = new JLabel();
     //aqui o resto
     panel.add(relogio); //add label relogio
     jPanel1.add(panel); //container jpanel1 recebe todos os outros panels q se fazem no while.
}

(3) Manda esses panels e labels que criou no while para a classe que controla os panels class ControlaPanels.

//mandando pelo for
ControlaPanels controlaPanels = new ControlaPanels();
for(int x = 0; x < jpanel1.getComponentCount(); x++){
     JPanel panel = (JPanel)jpanel1.getComponent(x); //aqui pego os panels
     controlaPanels.setPanel(panel) //aqui mando os panels
     
     JLabel relogio = (JLabel)panel.getComponent(1); //aqui pego o relogio
     controlaPanels.setRelogio(relogio); //aqui mando o relogio    
     Thread t = new Thread(controlaPanels);
     t.start();
}

//aqui mandando pelo click do mouse, pseudo codigo para mostrar como faco
ControlaPanels controlaPanels = new ControlaPanels();
public void mouseClick(evento evt){
     JPanel panel = (JPanel)evt.getComponent();
     controlaPanels.setPanel(panel) //manda panel

     JLabel relogio = (JLabel)panel.getComponent(1);
     controlaPanels.setRelogio(relogio); //manda relogio

     Thread t = new Thread(controlaPanels);
     t.start();

}

(4) class ControlaPanels que faz modificacoes no JPanel que recebe e JLabel que recebe, vindo pelo for ou pelo click do mouse.

public class ControlaPanels implements Runnable{
    private static JPanel panel;
    private static JLabel relogio;
    private SimpleDateFormat horaFormatada = new SimpleDateFormat("HH:mm:ss");

    public void setPanel(JPanel panel){
            this.panel = panel;
    }

    public void setRelogio(JLabel relogio){
            this.relogio = relogio;
    }
   
     public void run() {  //run executa relogio
            rodaRelogio();  
      }  
   
   
     public void rodaRelogio(){  
           this.relogio.setVisible(true);  
           while(true){  
             String hora = horaFormatada.format(new Date());  
             this.relogio.setText(hora);  
           }  
    
}

E isso ae que eu faco…Nos panels criados eu tenho o relogio, mas qdo clico em um panel o outro relogio q esta sendo executado em um dos panels para…E problema de referencia, mas naum estou conseguindo resolver.

Se alguem puder ajudar, eu agradeço…obrigado desde ja !!!

Eric_Yuzo

O problema das referências ocorre porque “panel” e “relogio” da sua classe ControlaPanels são estáticas.

Variáveis estáticas são da classe e não do objeto. Você pode criar 50 objetos diferentes que todas estarão acessando a mesma variável estática.

Porque você precisa que estas variáveis sejam estáticas?

fernandopaiva

Eric, eu coloquei elas estaticas pq perco a referencia a elas qdo passo sem elas serem staticas…Eu tbm pensei nisso, pq toda vez q recebe um panel ele muda elas, mas como fazer isso sem perder a referencia, sem elas serem estaticas ???
Tentei usar sem elas serem estaticas, mas tive o erro de NullPointerException…Como fazer isso sem elas serem static e naum perder a referencia ???

obrigado.

Eric_Yuzo

Mas mesmo a variável sendo estática, cada vez que uma nova referência é atribuída a ela, a referência anterior é perdida, não? Explica melhor em que parte ocorre o NullPointerException ou essa questão de perder a referência.

Outra coisa que não entendi é porque a thread ou timer que atualiza o texto da label com a hora tem que estar na classe que controla os panels, ela não poderia estar na própria label, como sugeriu o entanglement?

fernandopaiva

Eric, eu criei uma classe para controlar os panels pq sao varios panels e cada 1 desses panels tem seus labels,…por exemplo. data, hora, hora corrente, status…
Tenho um cadastro de vendas, nesse cadastro de vendas qdo efetuo a venda ele ativa o panel com seus labels…trazendo as respectivas informacoes.
por exemplo.

mesa1 = panel1
mesa2 = panel2
mesa3 = panel3

vai ate o 50, conforme vc viu ae no while…Entaum se vendo na mesa 33, o panel mesa33 ativa com os labels…E quando eu mando um panel para a classe ControlaPanels como mostrei acima, e a instanciacao naum esta static eu perco elas entende ???

veja as imagens…

TelaPrincipal do Sistema Exibindo as mesas.

Fazendo venda para mesa 25 ativar panel

Mesa 25 ativa

veja que qdo vendo para a mesa 25, logo q efetua a venda ele ativa o panel…o primeiro relogio e a hora de entrada na mesa, o segundo relogio e a hora corrente q preciso…

Eric_Yuzo

Cada mesa deve ter uma label rodando a hora corrente. A hora corrente vai ser a mesma em todas as labels, porque não deixa uma única label exibindo o horário em algum ponto da tela? Como se fosse uma barra de status.

Desculpe, mas ainda não entendi essa parte de perder a referência.

fernandopaiva

Seguinte Eric, na hora que eu mando o JPanel para a classe ControlaPanel, se naum estiver static ele perde…veja.

public class ControlaPanels {
    private static JPanel panel;   //aqui se naum estiver static eu perco
    private static JLabel relogio; //aqui tbm

    public JPanel setPanel(JPanel panel){
          this.panel = panel;
    }

    public void ativaPanel(){  ///aqui e onde eu ativo o panel e os labels
          this.panel.setBackground(Color.green); 
          this.relogio.setForeground(Color.green);
    }
}

Ai e onde eu recebo o panel, os labels etc…etc…etc…E com isso, se naum estiver static, eu perco a referencia da NullPointerException.

Eric_Yuzo

É que o valor padrão para uma variável de referência é null. Pra evitar o NullPointerException aí teria que chamar o “setPanel” e o “setRelogio” antes de chamar o ativaPanel().

Criado 11 de novembro de 2010
Ultima resposta 11 de nov. de 2010
Respostas 14
Participantes 3