GUJ Discussões   :   últimos tópicos   |   categorias   |   GUJ Respostas

Captando a hora do sistema no modelo hh:mm:ss

Pessoal,
sou bem iniciante na linguagem ainda e gostaria como posso fazer para criar um método que mostra a hora do sistema dinâmicamente como em java-script onde os segundos vão passando: tipo 22:45:36

Alguém tem este método ou sabe como fazer? Desde já agradeço …

Tiago [ HcK ]

Podes fazer isso instanciando um objecto da classe java.util.Date;

Exemplo: [code]

Date data = new Date();
System.out.println(data);
[/code]

Ele irá mostrar a data no momento da instanciação;

Se quiseres dinamismo terás de usar Threads, ou crias um ciclo infinito em que em cada iteração ele mostra a data.

Isso mesmo. Primeiro você instancia um Date:

Date date = new Date();

Depois, gere a String formatada para esse date. Há duas maneiras de se fazer isso. A primeira é usando um DateFormat. A segunda é usando o método String.format() ou equivalente. Vou mostrar aqui com o DateFormat:

DateFormat formato = new SimpleDateFormat("HH:mm:ss.SSS");
String formattedDate = formato.format(date);

Finalmente, imprima essa data formatada continuamente numa nova thread. No run() de sua thread, faça:

DateFormat formato = new SimpleDateFormat(“HH:mm:ss.SSS”);

try {
   while (true) {
      Date date = new Date();
      String formattedDate = formato.format(date);
      EventQueue.invokeLater(new Runnable() {
         public void run() {
            suaLabel.setText(formattedDate);
         }
      });
      Thread.sleep(1000);
   }
}
catch (InterruptedException e) {
}

Vini entendi o que deve ser feito,
sei o que são threads mas somente o que aprendi em S.O teórico sabe, não tenho a mínima idéia de como criar uma thread no JAVA. Estou utilizando a IDE NetBeans 5.0, ou esta thread é apenas um arquivo java class comum?

Tentei colocar o código no mais de meu sistema, segue o código:

public static void main(String args[]) {
        
        Date date = new Date();        
        DateFormat formato = new SimpleDateFormat("HH:mm:ss.SSS");
        try {
            while (true) {
                Date date = new Date();
                String formattedDate = formato.format(date);
        
                java.awt.EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        new sistema().setVisible(true);
                        horas.setText(formattedDate);
                    }
                });
        }
        }catch (InterruptedException e) { } 
    }

eu consigui formatar a data pegando apenas o horário, através de sua substring na posição de 12 a 18, quanto às threads, também gostaria de conhecer como se implementa isso em Java. Existe algum componente como o reloginho no delphi onde se colocava processos rodando sem travar o programa?

Beleza, acho que é isso mesmo.

Só que não seria melhor criar o sistema e dar o setVisible fora do while? Depois a Thread poderia cuidar apenas da atualização do label.

Finalmente, coloque também o sleep() que eu havia esquecido de manhã. Meu código já está atualizado ali em cima! :slight_smile:

Nilson,

Existe sim, mas não é um componente. É uma classe. Na verdade existem duas.

Dê uma pesquisada nas classes java.util.Timer e java.swing.Timer. Normalmente eu uso a primeira, ou gerencio através de Threads mesmo.

tiagosarno nem precisa colocar numa thread coloca um while dentro de um metodo da uma olhada no exemplo abaixo espero ter ajudado.

package clock;

import java.awt.Font;
import java.awt.Rectangle;
import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Relogio extends JDialog {

	private static final long serialVersionUID = 1L;
	private JPanel 	painelPrincipal 	= null;
	private JLabel 	lblHora 		= null;
	private JLabel 	by 				= null;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Relogio app = new Relogio();
		app.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
	}

	/**
	 * @param owner
	 */
	public Relogio() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setBounds(200,200,300, 200);
		this.setTitle("...:: Hora Certa ::...");
		this.setContentPane(getPainelPrincipal());
		this.setVisible(true);
		
		horaCerta();
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getPainelPrincipal() {
		if (painelPrincipal == null) {
			by = new JLabel();
			by.setBounds(new Rectangle(179, 141, 94, 22));
			by.setText("by correainfo");
			lblHora = new JLabel();
			lblHora.setBounds(new Rectangle(103, 63, 115, 33));
			lblHora.setFont(new Font("Dialog", Font.BOLD, 24));
			lblHora.setText("");
			painelPrincipal = new JPanel();
			painelPrincipal.setLayout(null);
			painelPrincipal.add(lblHora, null);
			painelPrincipal.add(by, null);
		}
		return painelPrincipal;
	}

	public void horaCerta(){
		while (true) {
			GregorianCalendar calendario = new GregorianCalendar(); 
			int hr = calendario.get(Calendar.HOUR_OF_DAY); 
			int min = calendario.get(Calendar.MINUTE); 
			int sec = calendario.get(Calendar.SECOND); 

			String hora2 = 
				((hr < 10) ? "0" : "") 
				+ hr 
				+ ":" 
				+ ((min < 10) ? "0" : "") 
				+ min 
				+ ":" 
				+ ((sec < 10) ? "0" : "") 
				+ sec; 


			lblHora.setText(hora2);
			
		}
	}
}

Qualquer duvida post ae…

Vini desculpa ai cara mais ainda consegui, acho que o código agora esta certo mas esta dando um erro que desconheço, o erro é:
non-static variable LabelHora cannot be referenced from a static context. Na linha ’ LabelHora.setText(formattedDate); ’

Eis o código, a linha que esta dando erro esta marcada com " <-- ":

public static void main(String args[]) {                            
        
        java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            
            new sistema().setVisible(true); /* CHAMADA PARA APRESENTAÇÃO DA INTERFACE */
            String formattedDate = null;    
            Date date = new Date();
            DateFormat formato = new SimpleDateFormat("HH:mm:ss.SSS");
            formattedDate = formato.format(date);
            
            try{
                while (true) {
                   Date data = new Date();
                   formattedDate = formato.format(data);
                   LabelHora.setText(formattedDate); /* <-- Erro nesta linha */
                   Thread.sleep(1000);
                }
            }catch(InterruptedException e){ /* NADA */ }

         } /* void run */
      }); /* EventQueue */
   } /* main */

Acho que tem alguma coisa a ver com váriavel global mas como sou novo na linguagem não sei bem o que é este erro. Help please …

Olá, este problema é por você estar trabalhando com uma declaração não estática (LabelHora) dentro de um método estático (Main).
No caso o seu Label deve estar declarado como componente no escopo da classe do seu “formulário”.
Daí você pode fazer duas coisas:

  • Instanciar todo seu formulário e tudo mais dentro do seu método Main e trabalhar lá sem problemas (muita confusão).
    ou
  • De seu método Main, instanciar a classe que implementa o formulário e então a partir desta (do form), trabalhar com os componentes.

Seguinte: O Net Beans 5.0 não vem com um jar que vem apenas no 3.6 que é o Timer.jar e deve ser adicionado na sua biblioteca do Net Beans…
Este é o único porém que vi… e consigo rodar relógios…

Pessoal será que alguém pode me mostrar como instanciar este formulário em meu código, já tentei de tudo quanto é jeito e fica sempre dando este erro, o código é o seguinte:

public static void main(String args[]) {                            
         
         java.awt.EventQueue.invokeLater(new Runnable() {
          public void run() {
             
             new sistema().setVisible(true); /* CHAMADA PARA APRESENTAÇÃO DA INTERFACE */
             String formattedDate = null;    
             Date date = new Date();
             DateFormat formato = new SimpleDateFormat("HH:mm:ss.SSS");
             formattedDate = formato.format(date);
             
             try{
                 while (true) {
                    Date data = new Date();
                    formattedDate = formato.format(data);
                    LabelHora.setText(formattedDate); /* <-- Erro nesta linha */
                    Thread.sleep(1000);
                 }
             }catch(InterruptedException e){ /* NADA */ }
 
          } /* void run */
       }); /* EventQueue */
    } /* main */

Tiago.

A label não é um componente da classe de interface sistema?

Então você teria que alterar a criação para:
sistema s = new sistema();
s.setVisible(true);

Depois, na linha que dá erro, você deve fazer:

EventQueue.invokeLater(new Runnable() {
   public void run() {
       s.LabelHora.setText(formattedDate);
   }
});

E. do contrário que disse o colega, precisa sim de outra thread para executar o código, caso contrário sua interface gráfica ficará travada.

Segue abaixo um exemplo que realmente funciona:

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class MyFrame extends JFrame {
    // Local onde atualizaremos a hora
    private JLabel lblHora;

    // Formatador da hora
    private static final DateFormat FORMATO = new SimpleDateFormat("HH:mm:ss");

    public MyFrame() {
        // Construímos nosso frame
        super("Exemplo");
        setLayout(new FlowLayout());
        getContentPane().add(getLblHora());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(200, 75);

        // Iniciamos a thread do relógio. Tornei uma deamon thread para que seja
        // automaticamente finalizada caso a aplicação feche.
        Thread clockThread = new Thread(new ClockRunnable(), "Clock thread");
        clockThread.setDaemon(true);
        clockThread.start();
    }

    private JLabel getLblHora() {
        if (lblHora == null) {
            lblHora = new JLabel();
        }
        return lblHora;
    }

    /**
     * Método para atualizar a hora no formulário. Não é thread-safe, portanto,
     * se o utilizado fora da thread da AWT, deve-se utilizar um dos comandos da
     * EventQueue (invokeLater ou invokeAndWait).
     */
    public void setHora(Date date) {
        getLblHora().setText(FORMATO.format(date));
    }

    /**
     * Runnable que contém o código que atuará na nossa thread. Basicamente, ele
     * chama o método setHora de segundo em segundo, passando a data atual.
     */
    private class ClockRunnable implements Runnable {
        public void run() {
            try {
                while (true) {
                    // Aqui chamamos o setHora através da EventQueue da AWT.
                    // Conforme dito, isso garante Thread safety para o Swing.
                    EventQueue.invokeLater(new Runnable() {
                        public void run() {
                            // Só podemos chamar setHora diretamente dessa
                            // forma, pois esse Runnable é uma InnerClass não
                            // estática.
                            setHora(new Date());
                        }
                    });
                    // Fazemos nossa thread dormir por um segundo, liberando o
                    // processador para outras threads processarem.
                    Thread.sleep(1000);
                }
            }
            catch (InterruptedException e) {
            }
        }
    }

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

Segue abaixo um outro exemplo, usando Timer do pacote util.
Note que nem o while e nem o sleep() são mais necessários.

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class MyFrame extends JFrame {
    // Local onde atualizaremos a hora
    private JLabel lblHora;

    // Formatador da hora
    private static final DateFormat FORMATO = new SimpleDateFormat("HH:mm:ss");

    public MyFrame() {
        // Construímos nosso frame
        super("Exemplo");
        setLayout(new FlowLayout());
        getContentPane().add(getLblHora());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(200, 75);
        setVisible(true);

        // Iniciamos um timer para atualizar o relógio
        Timer t = new Timer("ClockTimer", true);
        
        //Pedimos para ele disparar a cada 1 segundo.
        t.schedule(new ClockTask(), 0, 1000);
        
    }

    private JLabel getLblHora() {
        if (lblHora == null) {
            lblHora = new JLabel();
        }
        return lblHora;
    }

    /**
     * Método para atualizar a hora no formulário. Não é thread-safe, portanto,
     * se o utilizado fora da thread da AWT, deve-se utilizar um dos comandos da
     * EventQueue (invokeLater ou invokeAndWait).
     */
    public void setHora(Date date) {
        getLblHora().setText(FORMATO.format(date));
    }

    /**
     * Runnable que contém o código que atuará na nossa thread. Basicamente, ele
     * chama o método setHora de segundo em segundo, passando a data atual.
     */
    private class ClockTask extends TimerTask {
        @Override
        public void run() {
            // Aqui chamamos o setHora através da EventQueue da AWT.
            // Conforme dito, isso garante Thread safety para o Swing.
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    // Só podemos chamar setHora diretamente dessa
                    // forma, pois esse Runnable é uma InnerClass não
                    // estática.
                    setHora(new Date());
                }
            });
        }
    }

    public static void main(String args[]) {
        new MyFrame();
    }
}

Finalmente, um outro exemplo usando o timer do Swing.

Note que agora nem mesmo o EventQueue.invokeLater é necessário, uma vez que esse timer gera ações na Thread certa. Creio que para o seu caso, seja o mais fácil de se implementar.

import java.awt.FlowLayout;
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.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;

public class MyFrame extends JFrame {
    // Local onde atualizaremos a hora
    private JLabel lblHora;

    // Formatador da hora
    private static final DateFormat FORMATO = new SimpleDateFormat("HH:mm:ss");

    public MyFrame() {
        // Construímos nosso frame
        super("Exemplo");
        setLayout(new FlowLayout());
        getContentPane().add(getLblHora());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(200, 75);
        setVisible(true);

        // Iniciamos um timer para atualizar o relógio
        Timer t = new Timer(1000, new ClockAction());               
        t.setInitialDelay(0);
        t.setRepeats(true);
        t.start();
    }

    private JLabel getLblHora() {
        if (lblHora == null) {
            lblHora = new JLabel();
        }
        return lblHora;
    }

    /**
     * Método para atualizar a hora no formulário. Não é thread-safe, portanto,
     * se o utilizado fora da thread da AWT, deve-se utilizar um dos comandos da
     * EventQueue (invokeLater ou invokeAndWait).
     */
    public void setHora(Date date) {
        getLblHora().setText(FORMATO.format(date));
    }

    /**
     * Action que contém o código que atuará na nossa thread. Basicamente, ele
     * chama o método setHora de segundo em segundo, passando a data atual.
     * Roda diretamente na thread da AWT. 
     */
    private class ClockAction implements ActionListener {

        public void actionPerformed(ActionEvent e)
        {
            // Só podemos chamar setHora diretamente dessa
            // forma, pois esse Runnable é uma InnerClass não
            // estática.
            setHora(new Date());
        }
    }

    public static void main(String args[]) {
        new MyFrame();
    }
}

Ai Vini valew d+ cara :p,
fiquei um tempão ai sem postar nada né, é porque eu estava estudando um pouco mais e tentando fazer funcionar o código, após entender como você fez seu exemplo acima, pude concluir com facilidade a implementação em meu programa, muito obrigado.

Caro “correainfo”, o seu código está muito bom, porém está acontecendo algo muito ruim na execução do seu programa:
ele, o seu programa está acabando com a “CPU”. Execute-o uma vez, dê um “Crl+Alt+Del” e veja o desempenho da CPU.
Observe que mesmo encerrado o seu programa, o desempenho da CPU não volta ao normal. E tem mais. a medida que executamos o progrma
, MESMO ENCERRANDO-O, a CPU fica cada vez mais lenta…e então?? como podemos solucionar esse problema?
saudações.

O mesmo ocorre com o último código de “ViniGodoy”.
e então galera?
Saudações.