Ajuda com Threads por favor!

Galera, tenho esse código pro carro andar, e oque ocorre é que ele ta andando t udo certo sozinho (simplifiquei os metodos dos cases só pra dar uma idéia). Cada tecla que o usuário aperta ele vai para o lado correto sozinho, mas oque ocorre é que cada tecla ele cria uma nova Thread, entao se aperto pra ele ir pra cima ele vai na velocidade correta, mas se aperta direita ou para baixo, ele vai na direção correta só que mais rápido e vai ficando mais e mais rápido.

Será que tem como evitar que essa thread seja criada mais de uma vez? Alguém poderia me ajudar? Tentei singleton mas nao deu muito c erto, nao sei como poder no código a instancia com o run.

[code] public void andarCarro(int tecla) {
this.ultimaTecla = tecla;
System.out.println(“nova thread”);
Thread t = new Thread() {

        @Override
        public void run() {

            while (ultimaTecla != 0) {

                switch (ultimaTecla) {
                    case 37:
                        x - 1;
                    case 38:
                        x +1;
                    case 39:
                        y+1;
                    case 40:
                        y -1;
                    default:
                        return;
                }
                try {
                    Thread.sleep(300);
                } catch (InterruptedException ex) {
                    Logger.getLogger(Controle.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    };
    t.start();
}[/code]

Olá.

Fiz um exemplo aqui para vc. Apenas uma thread fica executando e mandando o painel se repintar.

Carro.java

[code]import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;

/**

  • Um carro.

  • @author David
    */
    public class Carro {

    private int x;
    private int y;

    // velocidades
    private int vx;
    private int vy;

    public int getVx() {
    return vx;
    }

    public void setVx( int vx ) {
    this.vx = vx;
    }

    public int getVy() {
    return vy;
    }

    public void setVy( int vy ) {
    this.vy = vy;
    }

    public int getX() {
    return x;
    }

    public void setX( int x ) {
    this.x = x;
    }

    public int getY() {
    return y;
    }

    public void setY( int y ) {
    this.y = y;
    }

    // pinta o carro
    public void paintMe( Graphics g ) {
    Graphics2D g2d = ( Graphics2D ) g;
    g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
    g2d.fill( new Ellipse2D.Double( getX(), getY(), 20, 20 ) );
    }

}[/code]

ThreadCarro.java

[code]/**

  • Repinta o painel.

  • @author David
    */
    public class ThreadCarro implements Runnable {

    private boolean executando;
    private PainelCarro painelCarro;

    public ThreadCarro( PainelCarro painelCarro, boolean executar ) {
    this.painelCarro = painelCarro;
    this.executando = executar;
    }

    public void run() {
    try {
    while ( executando ) {
    painelCarro.repaint();
    Thread.sleep( 100 );
    }
    } catch ( InterruptedException exc ) {
    exc.printStackTrace();
    }
    }

    public boolean isExecutando() {
    return executando;
    }

    public void setExecutando( boolean executando ) {
    this.executando = executando;
    }

}[/code]

PainelCarro.java

[code]import java.awt.Graphics;
import javax.swing.JPanel;

/**

  • Atualiza o carro e o repinta.

  • @author David
    */
    public class PainelCarro extends JPanel {

    private Carro carro;

    public PainelCarro( Carro carro ) {
    this.carro = carro;
    }

    @Override
    protected void paintComponent( Graphics g ) {
    super.paintComponent( g );
    carro.setX( carro.getX() + carro.getVx() );
    carro.setY( carro.getY() + carro.getVy() );
    carro.paintMe( g );
    }

}[/code]

Janela.java

[code]import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;

/**
*

  • @author David
    */
    public class Janela extends JFrame implements KeyListener {

    private Carro carro;
    private ThreadCarro threadCarro;
    private PainelCarro painelCarro;

    public Janela() {

     // instancia os componentes
     carro = new Carro();
     painelCarro = new PainelCarro( carro );
     threadCarro = new ThreadCarro( painelCarro, true );
    
     // configura o frame
     add( painelCarro, BorderLayout.CENTER );
     setSize( 400, 400 );
     setTitle( "Olha o Carro!" );
     setVisible( true );
     setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
     addKeyListener( this );
    
     // cria uma nova thread e a inicia
     new Thread( threadCarro ).start();
    

    }

    @Override
    public void keyTyped( KeyEvent e ) {
    }

    @Override
    public void keyPressed( KeyEvent e ) {
    // atualiza os valores do carro
    if ( e.getKeyCode() == KeyEvent.VK_UP ) {
    carro.setVy( carro.getVy() - 1 );
    } else if ( e.getKeyCode() == KeyEvent.VK_DOWN ) {
    carro.setVy( carro.getVy() + 1 );
    } else if ( e.getKeyCode() == KeyEvent.VK_LEFT ) {
    carro.setVx( carro.getVx() - 1 );
    } else if ( e.getKeyCode() == KeyEvent.VK_RIGHT ) {
    carro.setVx( carro.getVx() + 1 );
    }
    }

    @Override
    public void keyReleased( KeyEvent e ) {
    }

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

}[/code]

Qualquer dúvida avise.

[]´s

Péraí, quem é que chama o método andarCarro() ? Se esse método já é executado a cada evento de tecla, então você não tem porquê de executar uma thread a cada vez que uma tecla é pressionada.
Já se você quer que ele mantenha o carro andando em uma determinada direção indefinidamente até alguém dar outro comando para mudar a direção, aí é melhor postar mais do código para tentarmos adaptá-lo.

O andarCarro() é executado por um keyListener que fica na JFrame principal.

O lance é que se o cara apertar pra frete o carro deve continuar andando pra frente até ele apertar pro lado ou pra trás, entende?

aí esse método que cada vez que o keylistner dispara o evento ele cria uma Thread e acho que é isso que está errado. Teria que criar a Thread no Jframe principal?

valeu :d

O ideal é fazer como o David Postou. Dá uma estudada no código dele, está muito bom.