Tyler's Java Website

Traffic Light

This application had several requirements:

  • Write an event-driven program
  • Use an IF statement
  • Create custom colors
  • Customize buttons, images, and foreground/background color
  • Add multiple images and shapes
  • Use JPanel
  • Use FlowLayout for JButtons
  • Disable buttons when appropriate
  • Use BorderLayout, NullLayout, or GridLayout
  • Organize car movement

The Code

This project was challenging, but I was able to overcome many of the obstacles that got in my way. I was happy with the result.
Here is the code for my application. Please do not steal it. You will get caught.

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferStrategy;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * Class stopLight - This is a stop light simulation.
 * 
 * @author Tyler J Persohn
 * @version 1.0
 */

public class stopLight extends JApplet implements ActionListener, Runnable {
	public stopLight() {
	}

	private JLabel title;
	private JButton GO, WAIT, STOP;
	private int carLocation = 40;
	Image car;

	private enum LightState {
		STOP, WAIT, GO, OFF;
	}

	private LightState state = LightState.OFF;
	private Canvas canvas;

	@Override
	public void init() {
		Container contentPane = getContentPane();
		contentPane.setBackground(Color.green);
		contentPane.setLayout(new BorderLayout());
		contentPane.add(createTitlePanel(), BorderLayout.NORTH);
		contentPane.add(createButtonPanel(), BorderLayout.SOUTH);
		// Because repaint sucks and flickers too much.
		canvas = new Canvas();
		getContentPane().add(canvas, BorderLayout.CENTER);
		canvas.createBufferStrategy(2); // Image buffer
		// Car Movement Logic
		car = getImage(getDocumentBase(), "car.png");
		Thread thread = new Thread(this);
		thread.start();
	}

	public JPanel createTitlePanel() {
		// Title Attributes
		JPanel titlePanel = new JPanel();
		titlePanel.setLayout(new FlowLayout());
		titlePanel.add(title = new JLabel("Traffic Light", JLabel.CENTER));
		title.setForeground(Color.YELLOW);
		titlePanel.setBackground(Color.BLACK);
		return titlePanel;
	}

	public JPanel createButtonPanel() {
		// Button Controls
		JPanel controls = new JPanel();
		controls.setLayout(new FlowLayout());
		controls.add(GO = new JButton("GO"));
		GO.addActionListener(this);
		controls.add(WAIT = new JButton("WAIT"));
		WAIT.addActionListener(this);
		controls.add(STOP = new JButton("STOP"));
		STOP.addActionListener(this);
		return controls;
	}

	public void render(Graphics g) {

		// STOP_LIGHT
		g.setColor(new Color(0x999900));
		g.fillRect(400, 45, 90, 200);

		// ROAD
		g.setColor(Color.darkGray);
		g.fillRect(125, 0, 250, 515);

		// ROAD_DIVIDER
		g.setColor(Color.YELLOW);
		for (int i = 15; i < 500; i += 35) {
			g.fillRect(250, i, 10, 20);
		}

		// CAR
		g.drawImage(car, 280, carLocation, this);

		switch (state) {

		case GO:
			// GREEN LIGHT
			g.setColor(Color.BLUE);
			g.fillOval(420, 55, 50, 50);
			// YELLOW LIGHT
			g.setColor(Color.GRAY);
			g.fillOval(420, 118, 50, 50);
			// RED LIGHT
			g.setColor(Color.GRAY);
			g.fillOval(420, 180, 50, 50);
			break;

		case WAIT:
			// GREEN LIGHT
			g.setColor(Color.GRAY);
			g.fillOval(420, 55, 50, 50);
			// YELLOW LIGHT
			g.setColor(new Color(0x7f2246));
			g.fillOval(420, 118, 50, 50);
			// RED LIGHT
			g.setColor(Color.GRAY);
			g.fillOval(420, 180, 50, 50);
			break;

		case STOP:
			// GREEN LIGHT
			g.setColor(Color.GRAY);
			g.fillOval(420, 55, 50, 50);
			// YELLOW LIGHT
			g.setColor(Color.GRAY);
			g.fillOval(420, 118, 50, 50);
			// RED LIGHT
			g.setColor(new Color(0x2e1f51));
			g.fillOval(420, 180, 50, 50);
			break;

		default:
			// GREEN LIGHT
			g.setColor(Color.GRAY);
			g.fillOval(420, 55, 50, 50);
			// YELLOW LIGHT
			g.setColor(Color.GRAY);
			g.fillOval(420, 118, 50, 50);
			// RED LIGHT
			g.setColor(Color.GRAY);
			g.fillOval(420, 180, 50, 50);
			break;
		}
	}

	@Override
	public void actionPerformed(ActionEvent event) {

		if (event.getSource() == GO) {
			state = LightState.GO;
		}
		if (event.getSource() == WAIT) {
			state = LightState.WAIT;
		}

		if (event.getSource() == STOP) {
			state = LightState.STOP;
		}

	}

	@Override
	public void run() {

		while (true) {

			try {
				Thread.sleep(100); // Frame speed ms
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			if (state == LightState.GO) {
				carLocation += 4; // car speed for go
			}
			if (state == LightState.WAIT) {
				carLocation += 1; // car speed for wait
			}
			if (carLocation > 525) { // let the car get out of frame
				carLocation = -55;  // Set car location to loop back to beginning
			}
			BufferStrategy bs = canvas.getBufferStrategy();
			Graphics2D g = (Graphics2D) bs.getDrawGraphics(); // Get graphics
			g.scale(canvas.getWidth() / 512.0, canvas.getHeight() / 512.0); // Frame resize
			render(g); // Call render
			g.dispose(); // cleanup
			bs.show(); // Pull new frame
		}

	}

}