Ajuda Simples com Threads

8 respostas
L

Pessoal,

Estou com um pequeno impasse por aqui e vim pedir a ajuda de vocês.
Estou adptando um pequeno exemplo da utilização de Threads em java e o código ja está em andamento porém não consigo utilizar efetivamente as threads, segue o código para que possam entender.

import javax.swing.*;
	import java.awt.*;
	import java.text.DateFormat;
	import java.text.SimpleDateFormat;
	import java.util.Date;
	import java.util.Timer;
	import java.util.TimerTask;
	
	public class ExemploThread extends JFrame
	{
	    private JLabel lblHora;
	    private String titulo;
	    private JFrame janela;
	
	    JFrame getJanela()
	    {
	        return janela;
	    }
	    String getTitulo()
	    {
	        return titulo;
	    }
	    // Formatador da hora
	    private static final DateFormat FORMATO = new SimpleDateFormat("HH:mm:ss");
	    public ExemploThread()
	    {
	        // Construímos nosso frame
	
	        super("Threads em JAVA.");
	        setLayout(new FlowLayout());
	        JLabel lblThread = new JLabel("Teste");
	        getContentPane().add(lblThread);
	        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);
	
	    }
	    
	    public ExemploThread(JFrame janela)
	    {
	        this.janela = janela;
	        this.titulo = janela.getTitle();
	    }
	    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[]) 
	    {
	        ExemploThread t1 = new ExemploThread();
	        t1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	    }
	}
	class MinhaThread extends Thread
	{
	        ExemploThread t1 = new ExemploThread();
	        private JFrame janela = t1.getJanela();;
	        private String titulo = t1.getTitle();
	
	      
	        public void run()
	        {
	 try
	    {
	      while(true)
	      {
	        if(janela.getTitle().equals(""))
	          janela.setTitle(titulo);
	        else
	          janela.setTitle("");
	
	        Thread.sleep(300);
	      }
	    }
	    catch(InterruptedException ex)
	    {
	      // precisa fazer nada aqui
	    }
	  }
	    }

A intenção é utilizar threads para a janela (título) ficar piscando enquanto o relógio segue atualizando, consegui alguns exemplos parecidos no entanto não soube implementar.
Alguém pode me informar o que devo incluir ou modificar?

Grato,

Kleiton

8 Respostas

otaviojava

Seria interessante você fazer uma classe que seria a janela e ter uma classe (Thread) que ficasse mudando esse label.
Tenta isso e passa aqui para agente.

ViniGodoy

Tive um deja vú nesse código... hehehhehe

Ao invés de criar uma nova thread, simplesmente modifique o método setHora:
public void setHora(Date date)   
{  
   if(janela.getTitle().equals(""))  
      janela.setTitle(titulo);  
   else  
      janela.setTitle("");  

   getLblHora().setText(FORMATO.format(date));  
}

No mesmo tópico onde vc pegou esse exemplo, na página 2, existe duas implementações mais simples usando Timers. Recomendo que use a implementação que usa o Timer do Swing, pois ela é bem mais simples:
http://www.guj.com.br/java/52964-captando-a-hora-do-sistema-no-modelo-hhmmss/2#279092

L

Vini,

Estou tentando aqui mais da uns erros de compilação quando altero o if.
Sei pouco a respeito da classe Swing, estou lendo teus códigos para tentar entender + ainda meio perdido.

Tentei seguir a orientação do Otavio também mais como ja esperava não soube separar as classes.

ViniGodoy

Lock:
Vini,

Estou tentando aqui mais da uns erros de compilação quando altero o if.
Sei pouco a respeito da classe Swing, estou lendo teus códigos para tentar entender + ainda meio perdido.

Tentei seguir a orientação do Otavio também mais como ja esperava não soube separar as classes.

Quais erros?

L
import javax.swing.*;
	import java.awt.*;
	import java.text.DateFormat;
	import java.text.SimpleDateFormat;
	import java.util.Date;
	import java.util.Timer;
	import java.util.TimerTask;
	
	public class ExemploThread extends JFrame
	{
	    private JLabel lblHora;
	    private String titulo;
	    private JFrame janela;
	
	    JFrame getJanela()
	    {
	        return janela;
	    }
	    String getTitulo()
	    {
	        return titulo;
	    }
	    // Formatador da hora
	    private static final DateFormat FORMATO = new SimpleDateFormat("HH:mm:ss");
	    public ExemploThread()
	    {
	        // Construímos nosso frame
	
	        super("Threads em JAVA.");
	        setLayout(new FlowLayout());
	        JLabel lblThread = new JLabel("Teste");
	        getContentPane().add(lblThread);
	        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);
	
	    }
	    
	    public ExemploThread(JFrame janela)
	    {
	        this.janela = janela;
	        this.titulo = janela.getTitle();
	    }
	    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)   
	    {  
	       if(janela.getTitle().equals(""))  
	          janela.setTitle(titulo);  
	       else  
	          janela.setTitle("");  

	       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[]) 
	    {
	        ExemploThread t1 = new ExemploThread();
	        t1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	    }
	}
	class MinhaThread extends Thread
	{
	        ExemploThread t1 = new ExemploThread();
	        private JFrame janela = t1.getJanela();;
	        private String titulo = t1.getTitle();
	
	      
	        public void run()
	        {
	 try
	    {
	      while(true)
	      {
	        if(janela.getTitle().equals(""))
	          janela.setTitle(titulo);
	        else
	          janela.setTitle("");
	
	        Thread.sleep(300);
	      }
	    }
	    catch(InterruptedException ex)
	    {
	      // precisa fazer nada aqui
	    }
	  }
	    }

Aparece isso aqui:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at ExemploThread.setHora(ExemploThread.java:67)
	at ExemploThread$ClockTask$1.run(ExemploThread.java:94)
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at ExemploThread.setHora(ExemploThread.java:67)
	at ExemploThread$ClockTask$1.run(ExemploThread.java:94)
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at ExemploThread.setHora(ExemploThread.java:67)
	at ExemploThread$ClockTask$1.run(ExemploThread.java:94)
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

Têm mais, copiei uma parte pois ele não paraliza o programa.

E

Bem vamos la

amigo voçe tem 2 construtores certo um voçe chama as configuração da tela no outro voçe passa um JFrame deve estar dando nullpointer nao e essa sua variavel que passa no construtor nao tem ligação nenhum com o JFrame que voçe esta montando na sua classe MinhaThread voçe chamo o contrutor padrao e o outro construtor no qual voçe usa sua variavel janela esta como null

faça assim no 2 contrutor :

this.frame = j;
	
frame = this;

e coloque o conteudo do primeiro construtor no segundo aqui acho que deve pegar e lembrando que voçe tem que ta start no seu thread se nao for posta ai o erro

ViniGodoy

Você não precisa da variável janela, do tipo JFrame, porque sua classe ExemploThread já é uma janela (veja, ele extends JFrame).

Além disso, vc não deu "new" na sua variável Janela.

Deve ficar mais ou menos assim (não compilei aqui para testar):

import javax.swing.*;
import java.awt.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
	
public class ExemploThread extends JFrame
{
   private JLabel lblHora;
   private String titulo;
	
   // Formatador da hora
   private static final DateFormat FORMATO = new SimpleDateFormat("HH:mm:ss");
   public ExemploThread(String titulo) {
      // Construímos nosso frame
      super(titulo);
      setLayout(new FlowLayout());
      JLabel lblThread = new JLabel("Teste");
      getContentPane().add(lblThread);
      getContentPane().add(getLblHora());
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setSize(200, 75);
	
      // 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) {  
      if(this.getTitle().equals(""))  
         this.setTitle(titulo);  
      else  
         this.setTitle("");  

      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[]) {
      ExemploThread t1 = new ExemploThread();
      t1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      t1.setVisible(true);
   }
}

PS: Você se confundiu com uma coisa muito básica. Sugiro que você volte e estude os conceitos básicos da linguagem (classes, atributos, passagem de parâmetro, etc) antes de tentar voos mais altos com Swing e Thread.

L

Acho que entendi
Vou tentar aqui

Obrigado Vini e erato690 pelas respostas.

Realmente tenho que revisar conceitos básicos.

Abraço

Criado 17 de abril de 2011
Ultima resposta 18 de abr. de 2011
Respostas 8
Participantes 4