Enquanto uma animação está executando a outra trava - runnable e thread

Alô turma do Guj!
Tô tentando fazer uma brincadeira aqui, usando a classe runnable e thread. Conheço um pouco de java, mas essas classes estou começando a usar. O problema que apareceu é: Eu executo a classe ‘Pinball’ clico no button ‘start’ e a label azul(que depois vai ser a bola) se move no eixo y ate um ponto aleatorio e outro método faz ela ir à esquerda e então a idéia é rebater com uma label ‘Raq’ . Tá tudo no começo. o problema é que enquanto a label azul está se movendo prá esquerda e mesmo depois que ela pára a label amarela ‘raq’ trava e não consigo movê-la com as setas ‘->’ e as demais. Só consigo fazer funcionar as setas reiniciando a aplicação ou antes de clicar em ‘start’. Porque esse travamento enquanto as classes que movem o quadrado azul(‘bola’) estão em execução? Onde está o êrro? Me ajudem, por favor! Abaixo estão as classes envolvidas no programa.

package Run_;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.KeyEvent;
import java.lang.Math;
import java.util.Random;

public class Pinball extends JFrame implements ActionListener, KeyListener, ItemListener, FocusListener // setEnabled
{
    private Container c;
    public static JLabel lBall, lEsq, lBaixo, lDir, lRaq, lPts, lExPts;
    private JLabel lTitTema, lPow;
    private JButton bSair, bStart, bReset;
    private ImageIcon iconTema, iconOk, iconSair, iconEstat, iconReset, iconVerif, iconIr, iconQuest, icon;
    public static JButton  bDir, bStop;
    private JTextField t1;
    static int lRaqY = 0, lRaqX = 0;
    static int lBallY = 0, lBallX = 0;
    static int cont = 0, max=0, min=0;
    static int num_Al = 0;
	
    public Pinball()
	{
		super( " Pinball " );
		c = getContentPane();
	    c.setLayout(null);
	    c.setBackground(new java.awt.Color(255, 90, 50));

	    t1 = new JTextField();
	   
	    t1.addKeyListener(this);

        iconTema = new ImageIcon("TitTema.jpg");
        iconOk = new ImageIcon("Tick.png");
        iconSair = new ImageIcon("exit.png");
        iconEstat = new ImageIcon("estat.png");
        iconReset = new ImageIcon("reset.png");
        iconVerif = new ImageIcon("verif.png");
        iconIr = new ImageIcon("ir.png");
        iconQuest = new ImageIcon("questao.png");
        icon = new ImageIcon("background.jpg");
        
        

	    lBall  = new JLabel("");
	    lBall.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));
	    lBall.setBackground(new java.awt.Color(0, 210, 255));
	    lBall.setOpaque(true);

	    lTitTema  = new JLabel(" P I N B A L L ", JLabel.CENTER);
	    lTitTema.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));
	    lTitTema.setBackground(new java.awt.Color(148, 227, 0));//223
	    lTitTema.setOpaque(true);

	    lEsq  = new JLabel("");
	    lEsq.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));
	    lEsq.setBackground(new java.awt.Color(148, 227, 0));//223
	    lEsq.setOpaque(true);

	    lBaixo  = new JLabel("");
	    lBaixo.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));
	    lBaixo.setBackground(new java.awt.Color(148, 227, 0));//223
	    lBaixo.setOpaque(true);

	    lDir  = new JLabel("");
	    lDir.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));
	    lDir.setBackground(new java.awt.Color(148, 227, 0));//223
	    lDir.setOpaque(true);

	    lRaq  = new JLabel("");
	    lRaq.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));
	    lRaq.setBackground(new java.awt.Color(255, 235, 0));
	    lRaq.setOpaque(true);

	    lPts  = new JLabel("PONTOS:", JLabel.CENTER);
	    lPts.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));
	    lPts.setBackground(new java.awt.Color(255, 235, 0));
	    lPts.setOpaque(true);

	    lExPts  = new JLabel("0", JLabel.CENTER);
	    lExPts.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));
	    lExPts.setBackground(new java.awt.Color(192, 255, 255));
	    lExPts.setOpaque(true);

	    bDir  = new JButton(" >>> ");
	    bDir.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));
	    
	    bSair  = new JButton("Sair",iconSair);
	    bSair.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));

	    bStart  = new JButton("Start");
	    bStart.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));
	    bStart.setVisible(true);

	    bStop  = new JButton("Stop");
	    bStop.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));
	    bStop.setVisible(false);

	    bReset  = new JButton("Reset");
	    bReset.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));    

        c.add(t1);
	    c.add(lBall);
        c.add(lBaixo);
	    c.add(lTitTema);
	    c.add(lEsq);
	    c.add(lDir);
	    c.add(lRaq);
	    c.add(lPts);
	    c.add(lExPts);
	    c.add(bStop);
	    c.add(bReset);
	    c.add(bSair);
	    c.add(bDir);
	    c.add(bStart);
	    
	    lBall.setBounds(790,60,20,20);
	    lTitTema.setBounds(30,35,790,25);
	    lBaixo.setBounds(30,400,790,10);
	    lEsq.setBounds(30,60,10,340);
	    lDir.setBounds(810,60,10,340);
	    
	    lRaq.setBounds(40,195,20,70);
	    lPts.setBounds(365,420,65,25);
	    lExPts.setBounds(435,420,40,25);

        bStart.setBounds(30,420,70,25);
	    bStart.addActionListener(this);
	    bStop.setBounds(30,420,70,25);
	    bStop.addActionListener(this);
	    bReset.setBounds(670,420,70,25);
	    bReset.addActionListener(this);
	    bSair.setBounds(750,420,70,25);
	    bSair.addActionListener(this);
	    
	    lRaqY = lRaq.getY();
	    lRaqX = lRaq.getX();
	    
	    lBallY = lBall.getY();
	    lBallX = lBall.getX();
	    
	    

	    setSize(865,500);
		setVisible(true);
		setResizable(true);

	//	setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//--------------------------------------------------------------------------------------------------------------------------------------
//                                                          ACTION PERFORMED
//--------------------------------------------------------------------------------------------------------------------------------------
    
	public static void main	(String args[]) //throws ParseException
    {
       Pinball pb = new Pinball();
    }
 
    public void actionPerformed(ActionEvent evt)
 {
// START    	
    	
    	if(evt.getSource() == bStart){    

        bStart.setEnabled(false);
        max = 380; 
        min = 60;
        num_Al = min + (int)(Math.random() * (max - min)); 
               
    	movBall_Down();
    }
//-------------------------------------------------------------------------------------------------------------------------
// RESET
  
    if(evt.getSource() == bReset) {
    	
    	lBall.setBounds(790,60,20,20);
    	bStart.setEnabled(true);
    }
//-------------------------------------------------------------------------------------------------------------------------
// STOP
    if(evt.getSource() == bStop) {

    	bStart.setVisible(true);
    	bStop.setVisible(false);
    }
//--------------------------------------------------------------------------------------------------------------------------------------
//                                                          SAIR
//--------------------------------------------------------------------------------------------------------------------------------------

         if(evt.getSource() == bSair)
      {
        // passando this e nao null, mensagem aparece centro da janela
        int selectedOption = JOptionPane.showConfirmDialog(this,"Deseja Sair Realmente?", "Atencao", JOptionPane.YES_NO_OPTION);
        if(selectedOption == JOptionPane.YES_OPTION){
         dispose();
        // System.exit(0);
                   }
      }

} // fim Action Performed

//--------------------------------------------------------------------------------------------------------------------------------------
//                                                          FUNCOES
//-------------------------------------------------------------------------------------------------------------------------------------- 
                     
                            //--------- movRaqUp() ---------------
            	            //
            	              public static void movRaqUp()
            	            {
                              RunMovRaq_Up u = new RunMovRaq_Up ( 60 );
                              Thread mu = new Thread( u );
                              mu.start();
           	                }
            	              //--------- movRaqDown() ---------------
              	            //
              	              public static void movRaqDown()
              	            {
              	            	RunMovRaq_Down d = new RunMovRaq_Down ( 330 );
                                Thread md = new Thread( d );
                                md.start();
             	            }
            	              //--------- movRaqRight_01() ---------------
              	            //
              	              public static void movRaqRight_01()
              	            {   
              	            	RunMovRaq_Right_01 r1 = new RunMovRaq_Right_01 (  );
                                Thread mr1 = new Thread( r1 );
                                mr1.start();
                            }
            	              //--------- movBall_Down() ---------------
              	            //
              	              public static void movBall_Down()
              	            {   
              	            	RunMovBall_Down mb = new RunMovBall_Down (  );
                                Thread mbd = new Thread( mb );
                                mbd.start();
                            }
            	              //--------- movBall_Left() ---------------
              	            //
              	              public static void movBall_Left()
              	            {   
              	            	RunMovBall_Left mvb = new RunMovBall_Left (  );
                                Thread mbl = new Thread( mvb );
                                mbl.start();
                            }
            	              //--------- verif_col() ---------------
              	            //
              	              public static void verif_col()
              	            { 
              	            	  if(lBall.getX() <= (lRaq.getX() + 20) && lBall.getY() <= (lRaq.getY() + 70) &&
              	            	    (lBall.getY() + 20) >= lRaq.getY()) 
              	            	  {
              	            	    stop_mov();
              	            	  }
             	            }
            	              //--------- stop_mov() ---------------
              	            //
              	              public static void stop_mov()
              	            {       	            	     
              	            	RunMovBall_Left.contInicial = 39;              	            	 
             	            }
//-------------------------------------------------------------------------------------------------------------------------------------
                             
            	              public void keyPressed(KeyEvent e)
                            {
                            	    int codigo = e.getKeyCode();
                            	    
//------------------------------------------- p/ RAQ BAIXO --------------------------------------------
                                    	 
                                    	 if (e.getKeyCode() == 40)
                                    {
                                             movRaqDown();
                                    }
//------------------------------------------- p/ RAQ DIREITA ------------------------------------------
                                    
                                    	 if(e.getKeyCode() == 39 )
                                    {
                                       		movRaqRight_01();
                                    }
//--------------------------------------------- p/ RAQ CIMA -------------------------------------------
							         
                                    	 if(e.getKeyCode() == 38 )
							        {
							                movRaqUp();
							        }                                    	                                    	 
//-------------------------------------------------------------------------------------------------
							}
							 
            	              public void keyReleased(KeyEvent e)
							{
                 	            	  if(e.getKeyCode() == 39 )
                                     {
            	            	         // uma tecla foi solta
            	            	         lRaq.setBounds(40,lRaq.getY(),20,70);
                                     }
							}
							
							 public void keyTyped(KeyEvent e)
							{
							    // uma tecla foi pressionada
						    }

			@Override
			public void focusGained(FocusEvent arg0) {
				// TODO Auto-generated method stub				
			}

			@Override
			public void focusLost(FocusEvent arg0) {
				// TODO Auto-generated method stub				
			}

			@Override
			public void itemStateChanged(ItemEvent arg0) {
				// TODO Auto-generated method stub				
			}
}
package Run_;

public class RunMovRaq_Right_01 implements java.lang.Runnable 
{
    // �rea de dados da Thread
   public static int contMov;
   // public static int flag=0;
    public static int limite=30;

    // inicializador da MinhaThread
    public RunMovRaq_Right_01 (  )
    {
        this.limite = limite; // enviando limite = 0
    }    
          public void run()
   	 {
    	                if (limite > 0)
   	         { 
                                 Pinball.lRaqX = Pinball.lRaqX + 2;
   	                             Pinball.lRaq.setBounds(Pinball.lRaqX,Pinball.lRaqY,20,70);
   	                             limite--;
   	                         
   	                      try {                         
                                    Thread.sleep( 1 );                                 
                              }
                          catch (InterruptedException e)
   	                      {
                                 e.printStackTrace( System.err );
                          }                         
   	         }else {   	        	      
   	        	     limite = 30;
   	        	     Pinball.lRaqX = 40;
   	        	     Pinball.lRaq.setBounds(40,Pinball.lRaqY,20,70);
   	        	   }
     }
     public static void start()
     {
    	 RunMovRaq_Right_01.start();
	 }
}
package Run_;

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.applet.*;
import java.io.*;

public class RunMovRaq_Up implements java.lang.Runnable
{
    // �rea de dados da Thread
    public static int contMov;
   // public static int flag=0;
    public static int limite;

    // inicializador da MinhaThread
    public RunMovRaq_Up ( int limite ) // limite = 60
   {
             this.limite = limite; 
             limite = 60;
             this.contMov = contMov;
             contMov = Pinball.lRaq.getY();
   }
     
      public void run()
   	 {
              if (contMov > limite)
   	         {   	         
                        	     Pinball.lRaqY = Pinball.lRaqY - 5;
               	                 Pinball.lRaq.setBounds(40,Pinball.lRaqY,20,70);
               	              
                              try {      
               	                    Thread.sleep( 0 );                                  
                              }
                                  catch (InterruptedException e)
   	                          {
                                 e.printStackTrace( System.err );
                              }
             }
     }
     public static void start() {
		                          RunMovRaq_Up.start();
	                            }
}
package Run_;

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.applet.*;
import java.io.*;

public class RunMovRaq_Down implements java.lang.Runnable 
{
    // �rea de dados da Thread
    public static int contMov;
   // public static int flag=0;
    public static int limite;

    // inicializador da MinhaThread
    public RunMovRaq_Down ( int limite )
    	 {
             this.limite = limite;
             limite = 330;
             this.contMov = contMov;
             contMov = Pinball.lRaq.getY();
         }      
      public void run()
   	 {
              if (contMov < limite)
   	         {   	              
            	  Pinball.lRaqY = Pinball.lRaqY + 5;
   	              Pinball.lRaq.setBounds(40,Pinball.lRaqY,20,70);
                          try {
                                 Thread.sleep( 0 );                                  
                              }
                          catch (InterruptedException e)
   	                          {
                                 e.printStackTrace( System.err );
                              }
             }
     }
     public static void start() {
    	                          RunMovRaq_Down.start();
	                            }

}
package Run_;

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.applet.*;
import java.io.*;

public class RunMovBall_Down implements java.lang.Runnable 
{
    // �rea de dados da Thread
    public static int contInic;
   // public static int flag=0;
    public static int limite, pt;

    // inicializador da MinhaThread
    public RunMovBall_Down (  )
    	 {
             this.limite = Pinball.num_Al;
             this.contInic = 60;
         }
     
      public void run()
   	 {    	 
    	  if (contInic <= limite)
   	      {         
    			  while( contInic <= limite ) 
    			  {    				
    				  Pinball.lBall.setBounds(790,contInic,20,20);
    				  contInic++;
    				 try {
    				        Thread.sleep( 1 );     				  
    			     }    			     
    		          catch (InterruptedException e)
    		          {
    			        e.printStackTrace( System.err );
    		          }                    }
    		}
    	  Pinball.movBall_Left();
     }
     public static void start()
     {
    	 RunMovBall_Down.start();
	 }
}
package Run_;

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.applet.*;
import java.io.*;

public class RunMovBall_Left implements java.lang.Runnable
{
    // �rea de dados da Thread
    public static int contInicial;
   // public static int flag=0;
    public static int limite;

    // inicializador da MinhaThread
    public RunMovBall_Left (  )
    	 {
             this.limite = limite; 
             this.contInicial = 790;
         }
    public void run()
   	 {
          if (contInicial > 40)
   	      {                      
             	 while( contInicial >= 40) 
    			 {
    				  Pinball.lBall.setBounds(contInicial,Pinball.num_Al,20,20);
    				  contInicial--;
    				  Pinball.verif_col();
    				    				  
    				  try {
    				          Thread.sleep( 1 ); 
      			          }    		  
    		           catch (InterruptedException e)
    		           {
    			         e.printStackTrace( System.err );
    		           }
    				}
    	     }
    	      else{
	    	         Pinball.lBall.setBounds(790,contInicial,20,20);
	              }
          }
           public static void start()
          {
    	     RunMovBall_Left.start();
	      }
}