Ajuda. Não consigo interromper uma thread!

Olá pessoal, estou tentando de todas as maneiras mas não consigo interromper essa thread que criei. O objetivo é que apareça uma tela de introdução por apenas 3 segundos. Logo após esse tempo ela desapareça e suba a tela de login. Tudo está acontecendo, mas o problemas é que a cada 3 segundos surge uma nova tela de login, incessantemente! Como resolver isso? Alguém poderia dar uma ajuda?
Vejam o código:

[code]import java.awt.;
import javax.swing.
;
import java.awt.event.*;
import java.util.TimerTask; ;
import java.util.Timer;

class TelaIntroducao extends JFrame {
public static final long TEMPO = (3000);
FontMetrics fm;
String s = “Teste…”;

public TelaIntroducao() {
setTitle(“Testes”);

getContentPane().setLayout(new FlowLayout()); 

 Timer timer = null;      
     if (timer == null) {      
         timer = new Timer();    
                   
         TimerTask tarefa = new TimerTask() {   

             public void run() { 
                   
                 try {
                        new TelaLogar();   
                        dispose();
                        
                  }catch (Exception e){
                  	e.printStackTrace();     
                      
                 } 
                  		    
             } 
               
         };
                 
        timer.scheduleAtFixedRate(tarefa, TEMPO,TEMPO);
    }
	
Font font = new Font("Jokerman", Font.ITALIC, 36);
setFont(font);
fm = getFontMetrics(font);
setSize(fm.stringWidth(s)+30, fm.getHeight()+60);
	
setVisible(true);
setSize(550, 550);
setResizable(false);
setLocationRelativeTo(null);	

}

public void paint(Graphics g) {

  Insets ins = getInsets();
  int w = getSize().width-ins.left-ins.right;
  int h = getSize().height-ins.top-ins.bottom;

  int centerX = w/2 + ins.left;
  int centerY = h/2 + ins.top;

  g.setColor(Color.red);
  g.fillRect(ins.left, ins.top, w, h);

  g.setColor(Color.yellow);
  g.drawString(
     s, 
     centerX-fm.stringWidth(s)/2, 
     centerY + (fm.getAscent()-fm.getDescent())/2
  );

}
}[/code]

É a tela de splash que deve se matar sozinha, não uma thread que deve criar a tela. Vou dar um exemplo daqui a pouco.

package guj;

import java.awt.BorderLayout;

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

public class ExemploAplicacao extends JFrame {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JLabel lblExemplo = null;
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				ExemploAplicacao thisClass = new ExemploAplicacao();
				thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				
				ExemploSplash exemploSplash = new ExemploSplash(thisClass);
				exemploSplash.setVisible(true);
			}
		});
	}

	/**
	 * This is the default constructor
	 */
	public ExemploAplicacao() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(300, 200);
		this.setContentPane(getJContentPane());
		this.setTitle("Aplicação Exemplo");
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			lblExemplo = new JLabel();
			lblExemplo.setText("Exemplo!");
			lblExemplo.setHorizontalTextPosition(SwingConstants.CENTER);
			lblExemplo.setHorizontalAlignment(SwingConstants.CENTER);
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(lblExemplo, BorderLayout.CENTER);
		}
		return jContentPane;
	}

}
package guj;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.Timer;

class ExemploSplash extends JFrame {


	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JLabel lblSplash = null;

	/**
	 * This is the default constructor
	 */
	public ExemploSplash(JFrame nextFrame) {
		super();
		initialize();
		this.nextFrame = nextFrame;
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(200, 100);
		this.setContentPane(getJContentPane());
		this.setTitle("Splash");
		this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

		closeTimer = new Timer (3000, new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				ExemploSplash.this.dispose();
			}
		});
		closeTimer.start();
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosed(WindowEvent e) {
				closeTimer.stop();
				nextFrame.setVisible(true);
			}
		});
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			lblSplash = new JLabel();
			lblSplash.setText("Splash!");
			lblSplash.setHorizontalAlignment(SwingConstants.CENTER);
			lblSplash.setHorizontalTextPosition(SwingConstants.CENTER);
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(lblSplash, BorderLayout.CENTER);
		}
		return jContentPane;
	}
	
	private Timer closeTimer;  //  @jve:decl-index=0:
	private JFrame nextFrame;
}

Por que não usar o recurso de splash do java 6 e reduzir esse código para… 0 linhas?

De fato isso é uma sugestão melhor, exceto naquele malfadado caso em que você tem de fazer a coisa rodar em Java 5. Por exemplo, aqui escrevi uma aplicação que requer Java 6 (por causa do SwingWorker, basicamente). Agora tenho de transformar essa aplicação em uma applet (tolerável, já que ela tem uma tela só) mas infelizmente eu tenho de fazer um downgrade para Java 5 (argh - nem a Sun suporta mais esse cara, exceto com contrato pago) porque as máquinas aqui na firma, por algum motivo incerto e não sabido, estão com o plugin do Java 5 instalado, não do Java 6, e não tem como mexer nisso (argh argh argh).

E como seria usar esse recurso? Já pesquisei sobre esse assunto também, mas não consegui assimilar as idéias. Teria como explicar ou disponibilizar um exemplo?
Obrigado.

Quando executo o 1º exemplo acontece 2 erros:
cannot find symbol: linha 25
cannot find symbol: linha 26
O que seria?

Você precisa compilar os dois arquivos. Compile primeiro o segundo arquivo, se é isso que está dando problemas (como é que você compila as coisas? Use uma IDE como o Eclipse ou o NetBeans para evitar esses problemas bobocas) , e então compile o primeiro arquivo.

Eu uso o JCreator. Vou compilar os dois então, e ja posto o resultado.

JCreator???

Pow legal :shock:

Corajoso :twisted:

Estou no 5º semestre de sistemas e a única noção que tenho é o aprendizado da faculdade mesmo.

Procura usar uma IDE, Eclipse (meu favorito) ou NetBeans

Além de ser mais prático a criação de códigos, te ajuda muito se caso vc escrever algum código errado e ele te mostra. 8)

Correto, já me disseram isso, mas como o prof. da matéria não quer que use, aliás, ele disse que para quem está aprendendo a linguagem, o melhor é não usar as IDEs. Mas voltando aquela minha dúvida inicial, se eu quisesse interromper aquele looping, teria como me explicar o que fazer? Aqueles exemplos que você me passou foram ótimos mas gostaria de resolver minha dúvida. Obrigado.
Veja o código novamente:

[code]import java.awt.;
import javax.swing.
;
import java.awt.event.*;
import java.util.TimerTask; ;
import java.util.Timer;

class TelaIntroducao extends JFrame {
public static final long TEMPO = (3500);
FontMetrics fm;
String s = “Testar”;

public TelaIntroducao() {
setTitle(“Testar”);

getContentPane().setLayout(new FlowLayout()); 

 Timer timer = null;                                                     // looping começa aqui 
     if (timer == null) { 

         timer = new Timer();    
                   
         TimerTask tarefa = new TimerTask() {   

             public void run() { 
                   
                 try {
                 	    new TelaLogar();   
                        dispose();
                  }catch (Exception e){
                  	e.printStackTrace();     
                      
                 } 
                  		    
             } 
               
         };
                 
         timer.scheduleAtFixedRate(tarefa, TEMPO,TEMPO);
    }                                                                       //termina aqui
	
Font font = new Font("Jokerman", Font.ITALIC, 36);
setFont(font);
fm = getFontMetrics(font);
setSize(fm.stringWidth(s)+30, fm.getHeight()+60);
	
setVisible(true);
setSize(550, 550);
setResizable(false);
setLocationRelativeTo(null);	

}

public void paint(Graphics g) {

  Insets ins = getInsets();
  int w = getSize().width-ins.left-ins.right;
  int h = getSize().height-ins.top-ins.bottom;

  int centerX = w/2 + ins.left;
  int centerY = h/2 + ins.top;

  g.setColor(Color.red);
  g.fillRect(ins.left, ins.top, w, h);

  g.setColor(Color.yellow);
  g.drawString(
     s, 
     centerX-fm.stringWidth(s)/2, 
     centerY + (fm.getAscent()-fm.getDescent())/2
  );

}
}[/code]

Nem li seu programa, mas:

a) Threads não foram feitas para serem interrompidas. O que se deve fazer é você indicar para sua thread, setando uma variável que pertença à classe, que você quer que ela seja encerrada. Além disso, threads != janelas; normalmente, threads são invisíveis (não têm janelas associadas). Só para você ter uma idéia, o Swing processa todas as operações de janelas em uma única thread (e isso é que é a parte “misteriosa” da coisa).
Se você quer que uma janela se feche sozinha, crie um timer que a feche, assim como eu fiz com o programa. Você entendeu mesmo o que fiz? Não há um jeito muito mais simples de fazer o que eu fiz (exceto, é claro, usar o Java 6 e passar um parâmetro mágico -splash para o java.exe.)

b) “ScheduleAtFixedRate” quer dizer que você está agendando uma operação para que ocorra repetidamente, a uma determinada taxa (por exemplo, uma vez a cada 3 segundos). É isso que você quer fazer? É melhor ler a documentação primeiro (ela está em Timer.scheduleAtFixedRate. Veja os outros métodos dessa classe.

Vou desmontar seu código para poder entender passo-a-passo, e já posto o resultado.

Já fiz algumas alterações, mas estou com problemas na hora de chamar minha “TelaLogar”. Ela está aparecendo junto com a tela de apresentação, aquela que se encerra após alguns segundos. Teria como me orientar nesse sentido? Obrigado.
Veja o código:

[code]import java.awt.;
import javax.swing.
;
import java.awt.event.*;

public class TelaIntroducao extends JFrame {

public TelaIntroducao() {

    //new TelaLogar();
    setTitle("Tela de Login"); 
    setSize(220, 150);
    setLocationRelativeTo(null);
}  

}

class LogoIntroducao extends JFrame {

private static final long serialVersionUID = 1L;  
private JPanel jContentPane = null;  
private JLabel lblSplash = null;    
public LogoIntroducao(JFrame nextFrame) {  
    setTitle("Apresentação");  
    initialize();  
    this.nextFrame = nextFrame;  

}

private void initialize() {  
    setSize(550, 550);
    setResizable(false);
    setLocationRelativeTo(null); 
    setContentPane(getJContentPane());    
    closeTimer = new Timer (4500, new ActionListener() {  
        public void actionPerformed(ActionEvent e) {  
            LogoIntroducao.this.dispose();  
        }  
    });  
    closeTimer.start();  
    this.addWindowListener(new WindowAdapter() {  
        public void windowClosed(WindowEvent e) {  
            closeTimer.stop();  
            nextFrame.setVisible(true);  
        }  
    });  
}  
private JPanel getJContentPane() {  
    if (jContentPane == null) {  
        lblSplash = new JLabel();  
        lblSplash.setHorizontalAlignment(SwingConstants.CENTER);  
        lblSplash.setHorizontalTextPosition(SwingConstants.CENTER);  
        jContentPane = new JPanel(); 
        jContentPane.setBackground(Color.RED); 
        jContentPane.setLayout(new BorderLayout());  
        jContentPane.add(lblSplash, BorderLayout.CENTER); 
        
        Icon bug = new ImageIcon("travelbug.gif");   
        JLabel l1 = new JLabel(new ImageIcon("C:\Des\Introducao.jpg")); 
        jContentPane.add(l1);
    }  
    return jContentPane;  
}    
private Timer closeTimer;  
private JFrame nextFrame;  

} [/code]

Você viu o truque que eu usei? Quem chama o “setVisible” da janela principal (a “TelaLogar” no seu caso) é o método que é chamado quando a janela do splash está fechando. Isso para que a parte de logar fique sempre depois da tela de splash.

Certo, mas o que acontece, é que, ao executar o código, o primeiro frame que aparece é o de login, e depois ele desaparece rapidamente, e aí sim a tela de apresentação permanece por alguns segundos. Sendo que o de login teria que ser secundário. O que eu fiz de errado, no caso?