I am new to threads and I am trying to make a space invaders game using threads. Right now, ignoring the fact that I do not have the right images, the game will not work and I believe its due to threads. Could someone give me some tips on how to reorganize my code so that the thread do what I need them to do (bullets and ships go at different speeds). Also if you see any flaws or things to fix in the code feel free to yell at me for it. Thanks much :D

Java Code:
/**
 * 
 */
package edu.truman.msat;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;

import javax.swing.JComponent;

/**
 * @author owner2
 *
 */
public class SceneComponent extends JComponent implements KeyListener, Runnable
//Should implement runnable. Each bullet should have a thread as well as each ship. 
//They should each have a run. Which will tell this class how it will move. 
{
	public static int NUMBER_OF_SHIPS_TO_KILL = 24;
	private static final int SHIP_WIDTH = 12;
	private static final int SHIP_HEIGHT = 12;
	public static final int BORDER_RIGHT = 30;
    public static final int BORDER_LEFT = 5;
    private static final int FRAME_WIDTH = 500;
	private static final int FRAME_HEIGHT = 500;
	private static final int GROUND = 290;
	private int ROUND = 1;
	
	private boolean inRound;
	private boolean inGame;
	private String message;
	private int deaths;
	private int alienX = 150;
	private int alienY = 5;
	private Tank tank;
	private ArrayList<Bullet> bullets;
	private ArrayList<Thread> bulletThreads;
	private ArrayList<Ship> ships;
	private ArrayList<Thread> shipThreads;
	
	public SceneComponent()
	{
		bullets = new ArrayList<Bullet>();
		ships = new ArrayList<Ship>();
		addKeyListener(this);
		deaths = 0;
	}
	
	public int getRound()
	{
		return ROUND;
	}
	
	public void add(Tank tank)
	{
		this.tank = tank;
	}
	
	public void add(Bullet bullet)
	{
		if (bullets.size() <= 3)
		{
			bullets.add(bullet);
			System.out.println("Bullet Added");
			new Thread(bullet).start();
		}
	}

	public void add(Ship ship)
	{
		ships.add(ship);
		System.out.println("Ship added");
	}
	
	public void paintComponent(Graphics g)
	{
		tank.draw(g);
		for (Bullet b : bullets)
		{
			if (b.isVisible())
			{
				b.draw(g);
			}
		}
		for (Ship s : ships)
		{
			if (s.isVisible())
			{
				s.draw(g);
			}
		}
	}

	public void keyPressed(KeyEvent e) 
	{
		int keyPressed = e.getKeyCode();
		if (keyPressed == KeyEvent.VK_LEFT)
		{
			tank.translate(-10);
			repaint();
		}
		else if (keyPressed == KeyEvent.VK_RIGHT)
		{
			tank.translate(10);
			repaint();
		}
		
		else if (keyPressed == KeyEvent.VK_SPACE)
		{
			this.add(new Bullet(tank.getX(), tank.getY()));
			System.out.println("B");
			System.out.println(bullets.size());
		}
		
	}
	
	public void tick()
	{
		//This should call one instance of the bullet moving and the ships moving
		//It should move the ships and the bullets and also check EACH TIME for all collisons
	
       System.out.println("ticked");
		if (inGame)
		{
		if (NUMBER_OF_SHIPS_TO_KILL == deaths) //FIRST
		{
			inRound = false;
			ROUND++;
			message = "ROUND "+ ROUND;
		}
		
		if (inRound)
		{
			System.out.println("In round");
			
		for (Bullet b : bullets)
		{
			System.out.println("First for");
			if (b.isVisible())
			{
				System.out.println("First if");
				for(Ship s : ships)
				{
					System.out.println("Second for");
					if (b.isVisible() && s.isVisible())
					{
						System.out.println("Second if");
						if ((b.getX() >= (s.getX()) && 
		                        s.getX() <= (s.getX() + SHIP_WIDTH) &&
		                        s.getY() >= (s.getY()) &&
		                        s.getY() <= (s.getY()+SHIP_HEIGHT)))
						{
							//First make the image of the alien an explosion. Then draw it.
							deaths++;
							s.die();
							ships.remove(s);
							b.die();
							bullets.remove(b);
						}
					}
				}
			}
		
			int y = b.getY();
			y -= 4;
			if (y > 0)
			{
				System.out.println("Bullet is killed by screen");
				b.die();
				bullets.remove(b);
				repaint();
			}
			else 
			{
				b.translate(4);
				repaint();
				System.out.println("Bullet moved a tiny bit");
			}
		}
	
		for (Ship s: ships)
		{
			System.out.println("Ship for");
			System.out.println(ships.size());
			if (s.getX()  >= FRAME_WIDTH - BORDER_RIGHT && !s.movingLeft()) 
			{
				System.out.println("Ship if");
				for (Ship j: ships)
			    {
			    	j.setMovingLeft(true);
			    	j.translate(0, 5);
			    	repaint();
			    }
			 }
			System.out.println(ships.size());
			if (s.getX() <= BORDER_LEFT && s.movingLeft()) 
			{
				System.out.println("Second if");
				for (Ship j: ships)
				{
					j.setMovingLeft(false);
					j.translate(0, 5);
					repaint();
				}
			} 
		}
			for (Ship s: ships)
			{
				System.out.println("Ships moving");
				if(s.movingLeft())
				{
					System.out.println("Left");
					for (Ship j: ships)
					{
						j.translate(ROUND * -5, 0);
						repaint();
					}
				}
				else
				{
					System.out.println("Right");
					for (Ship j: ships)
					{
						j.translate(ROUND * 5, 0);
						repaint();
					}
				}
			}
			
			for (Ship s: ships)
			{
				if(s.getY() > GROUND - SHIP_HEIGHT)
				{
					System.out.println("Ending Game");
					inGame = false;
					inRound = false;
					message = "Game Over";
				}
			}
		}
		if (inRound = false)
		{
			this.newRound();
			deaths = 0;
		}
	}
	}
	public void newRound()
	{
		for (int i=0; i < 4; i++) 
		{
            for (int j=0; j < 6; j++) 
            {
                Ship ship = new Ship(alienX + 18*j, alienY + 18*i);
                ships.add(ship);
                repaint();
            }
		}
		inGame = true;
		inRound = true;
	}
	
	public void run()
	{
		System.out.println("Run is called!");
		for(Bullet b: bullets)
		{
			new Thread(b).start();
			System.out.println("Bullet Thread is started");
		}
		for(Ship s: ships)
		{
			new Thread(s).start();
		}
			
		newRound();
		while(inGame)
		{
			repaint();
			this.tick();
		}
		endGame();
	}
	
	public void endGame()
	{
		
		for(Thread t: bulletThreads)
		{
			t.interrupt();
		}
		for(Thread t: shipThreads)
		{
			t.interrupt();
		}
		Graphics g = this.getGraphics();

        g.setColor(Color.black);
        g.fillRect(0, 0, FRAME_WIDTH, FRAME_HEIGHT);

        g.setColor(new Color(0, 32, 48));
        g.fillRect(50, FRAME_WIDTH/2 - 30, FRAME_WIDTH-100, 50);
        g.setColor(Color.white);
        g.drawRect(50, FRAME_WIDTH/2 - 30, FRAME_WIDTH-100, 50);

        Font small = new Font("Helvetica", Font.BOLD, 14);
        FontMetrics metr = this.getFontMetrics(small);

        g.setColor(Color.white);
        g.setFont(small);
        g.drawString(message, (FRAME_WIDTH - metr.stringWidth(message))/2, 
            FRAME_WIDTH/2);
	}

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

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

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;

import edu.truman.msat.Bullet;
import edu.truman.msat.SceneComponent;
import edu.truman.msat.Tank;

public class MSAT  //This class sets up the frame and makes it look all nice.
{
	public static final int FRAME_WIDTH = 500;
    public static final int FRAME_HEIGHT = 500;
    public static final int GROUND = 290;
    public static final int STARTING_X = 270;
    public static final int BOMB_HEIGHT = 5;
    public static final int SHIP_HEIGHT = 12;
    public static final int SHIP_WIDTH = 12;
    public static final int BORDER_RIGHT = 30;
    public static final int BORDER_LEFT = 5;
    public static final int GO_DOWN = 15;
    public static final int NUMBER_OF_ALIENS_TO_DESTROY = 24;
    public static final int CHANCE = 5;
    public static final int DELAY = 17;
    public static final int TANK_WIDTH = 15;
    public static final int TANK_HEIGHT = 10;
    
    
    public static void main(String[] args) //should just call run on scene.  
    {
    	JFrame frame = new JFrame();
    	frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
    	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	final SceneComponent scene = new SceneComponent();
    	JButton pauseButton = new JButton("Pause");
    	JButton resumeButton = new JButton("Resume");
    	JButton startButton = new JButton("Start");
    	JButton newGameButton = new JButton("New Game");
    	pauseButton.addActionListener(new
    			ActionListener() {
    				public void actionPerformed(ActionEvent event)
    				{
    					//pause threads
    					//GIVE FOCUS TO KEYLISTENER
    				}
    			});
    	resumeButton.addActionListener(new
    			ActionListener() {
    				public void actionPerformed(ActionEvent event)
    				{
    					//resume threads
    					//GIVE FOCUS TO KEYLISTENER
    				}
    			});
    	startButton.addActionListener(new
    			ActionListener() {
    				public void actionPerformed(ActionEvent event)
    				{
    					//Starts game;
    					//GIVE FOCUS TO KEYLISTENER
    				}
    			});
    	newGameButton.addActionListener(new
    			ActionListener() {
    				public void actionPerformed(ActionEvent event)
    				{
    					//Starts a new game
    					//GIVE FOCUS TO KEYLISTENER
    				}
    			});
    	Toolkit tk = Toolkit.getDefaultToolkit(); //This will help us to change background(see AnimateEx)
    	scene.setFocusable(true);
    	scene.requestFocus();
    	Tank tank = new Tank(STARTING_X, GROUND - 10, TANK_WIDTH, TANK_HEIGHT);
    	scene.add(tank);
    	frame.add(scene);
    	frame.setBackground(Color.black);
    	frame.setVisible(true);
    	new Thread(scene).start();
    }
    
}

package edu.truman.msat;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

/**
 * 
 */

/**
 * @author owner2
 *
 */
public class Bullet implements Runnable
{
	private final int H_SPACE = 6;
	private final int V_SPACE = 1;
	private int x;
	private int y;
	private int width;
	private int height;
	private BufferedImage img = null;
	private Thread t;
	private boolean visible;
	
	public Bullet(int x, int y)
	{
		try{ //SET THE IMAGE TO THE ACTUAL BULLET IMAGE
    		img = ImageIO.read(new File("/Users/owner2/Documents/School/CS 260/tank.bmp"));
    	} catch (IOException e){System.out.println("Can't find file");}
		this.x = x + H_SPACE;
		this.y = y - V_SPACE;
		visible = true;
	}
	
	public void draw(Graphics g)
	{
		g.drawImage(img, x, y, null);
	}
	
	public void run()
	{
		try
		{
			Thread.sleep(5);
			System.out.println("BULLET THREAD IS WORKING!");
		}
		catch (InterruptedException e)
		{
			System.out.println("Bullet thread is dead.");
		}
	}
	
	public void translate(int dy)
	{
		y -= dy;
	}
	
	public void die() 
	 {
        visible = false;
    }

    public boolean isVisible() 
    {
        return visible;
    }

    public void setVisible(boolean visible) 
    {
        this.visible = visible;
    }
	
	public int getX()
	{
		return x;
	}
	
	public int getY()
	{
		return y;
	}
	
	public void setY(int y)
	{
		this.y = y;
	}
	
}

package edu.truman.msat;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Ship implements Runnable
{
	private boolean visible;
	private BufferedImage image;
	private int x;
	private int y;
	private boolean dying;
	private boolean movingLeft;
	private long i = 0;
	
	public Ship(int x, int y)
	{
		this.x = x;
		this.y = y;
		try{ //SET THE IMAGE TO THE ACTUAL SHIP IMAGE
    		image = ImageIO.read(new File("/Users/owner2/Documents/School/CS 260/tank.bmp"));
    	} catch (IOException e){System.out.println("Can't find file");}
		movingLeft = false;
	}
	public void draw(Graphics g)
	{
		g.drawImage(image, x, y, null);
	}
	
	public void run()
	{
		try
		{
			Thread.sleep(50);
		}
		catch (InterruptedException e)
		{
			System.out.println("Ship thread is dead.");
		}
	}
	
	public void die() 
	 {
        visible = false;
    }

    public boolean isVisible() 
    {
        return visible;
    }

    public void setVisible(boolean visible) 
    {
        this.visible = visible;
    }

    public void setImage(BufferedImage image) 
    {
        this.image = image;
    }

    public Image getImage() 
    {
        return image;
    }

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

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

    public int getX()
    {
        return x;
    }

    public void setDying(boolean dying) 
    {
        this.dying = dying;
    }

    public boolean isDying() 
    {
        return this.dying;
    }
    
    public boolean movingLeft()
    {
    	//System.out.println("Moving left called");
    	//i++;
    	//System.out.println(i);
    	return movingLeft;
    }
    
    public void setMovingLeft(Boolean b)
    {
    	movingLeft = b;
    }
    
    public void translate(int dx, int dy)
    {
    	x += dx;
    	y += dy;
    }
}