The TrafficLight Component
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.beans.PropertyEditorSupport;
import java.beans.SimpleBeanInfo;
import java.util.TooManyListenersException;
import java.util.Vector;
import javax.swing.JComponent;
public class TrafficLight extends JComponent {
public static String STATE_RED = "RED";
public static String STATE_YELLOW = "YELLOW";
public static String STATE_GREEN = "GREEN";
private static int DELAY = 3000;
private String defaultLightState;
private String currentLightState;
private boolean debug;
private Thread runner;
private transient ActionListener listener;
public TrafficLight() {
defaultLightState = currentLightState = STATE_RED;
setPreferredSize(new Dimension(100, 200));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Paint the outline of the traffic light
g.setColor(Color.white);
g.fillRect(2, 2, 96, 196);
// Debug
if (debug) {
System.out.println("Current light state is: " + currentLightState);
}
// Which light is on?
if (currentLightState.equals(STATE_RED)) {
g.setColor(Color.red);
g.fillOval(30, 30, 40, 40);
} else if (currentLightState.equals(STATE_YELLOW)) {
g.setColor(Color.yellow);
g.fillOval(30, 80, 40, 40);
} else if (currentLightState.equals(STATE_GREEN)) {
g.setColor(Color.green);
g.fillOval(30, 130, 40, 40);
}
}
public String getCurrentLightState() {
return currentLightState;
}
public void setCurrentLightState(String currentLightState) {
this.currentLightState = currentLightState;
if (currentLightState != STATE_YELLOW) {
if (debug) {
System.out.println("Firing action event");
}
ActionEvent ae = new ActionEvent(this,
ActionEvent.ACTION_PERFORMED, currentLightState);
fireActionPerformed(ae);
}
repaint();
}
public void setDefaultLightState(String defaultLightState) {
this.defaultLightState = defaultLightState;
currentLightState = defaultLightState;
repaint();
}
public String getDefaultLightState() {
return defaultLightState;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
public boolean isDebug() {
return debug;
}
public void initiate() {
if (debug) {
System.out.println("Initiate traffic light cycle!");
}
startCycle();
}
private void startCycle() {
if (runner == null) {
Runnable runnable = new Runnable() {
public void run() {
if (debug) {
System.out.println("Started cycle");
}
while (runner != null) {
try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {
}
if (currentLightState.equals(STATE_RED)) {
setCurrentLightState(STATE_GREEN);
} else if (currentLightState.equals(STATE_GREEN)) {
setCurrentLightState(STATE_YELLOW);
} else {
setCurrentLightState(STATE_RED);
}
if (currentLightState.equals(defaultLightState)) {
runner = null;
}
}
}
};
runner = new Thread(runnable);
runner.start();
}
}
public void lightChange(ActionEvent x) {
String command = x.getActionCommand();
if (debug) {
System.out.println("Received event from traffic light: "
+ defaultLightState + " command: go to " + command);
}
if (command.equals(STATE_RED)) {
if (!currentLightState.equals(STATE_GREEN)) {
currentLightState = STATE_GREEN;
repaint();
}
} else if (command.equals(STATE_GREEN)) {
if (!currentLightState.equals(STATE_RED)) {
currentLightState = STATE_YELLOW;
repaint();
try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {
}
currentLightState = STATE_RED;
repaint();
}
}
}
public synchronized void removeActionListener(ActionListener l) {
if (debug) {
System.out.println("Deregistering listener");
}
if (listener == l) {
listener = null;
}
}
public synchronized void addActionListener(ActionListener l)
throws TooManyListenersException {
if (debug) {
System.out.println("Registering listener");
}
if (listener == null) {
listener = l;
} else {
throw new TooManyListenersException();
}
}
protected void fireActionPerformed(ActionEvent e) {
if (debug) {
System.out.println("Firing action event");
}
if (listener != null) {
listener.actionPerformed(e);
}
}
}
class LightColorEditor extends PropertyEditorSupport {
public String[] getTags() {
String values[] = { TrafficLight.STATE_RED, TrafficLight.STATE_YELLOW,
TrafficLight.STATE_GREEN };
return values;
}
}
class TrafficLightBeanInfo extends SimpleBeanInfo {
public PropertyDescriptor[] getPropertyDescriptors() {
try {
PropertyDescriptor pd1 = new PropertyDescriptor("debug",
TrafficLight.class);
PropertyDescriptor pd2 = new PropertyDescriptor(
"defaultLightState", TrafficLight.class);
pd2.setPropertyEditorClass(LightColorEditor.class);
PropertyDescriptor result[] = { pd1, pd2 };
return result;
} catch (IntrospectionException e) {
System.err.println("Unexpected exception: " + e);
return null;
}
}
}
class MyBean {
private transient Vector actionListeners;
public synchronized void removeActionListener(ActionListener l) {
if (actionListeners != null && actionListeners.contains(l)) {
Vector v = (Vector) actionListeners.clone();
v.removeElement(l);
actionListeners = v;
}
}
public synchronized void addActionListener(ActionListener l) {
Vector v = (actionListeners == null) ? new Vector(2)
: (Vector) actionListeners.clone();
if (!v.contains(l)) {
v.addElement(l);
actionListeners = v;
}
}
protected void fireActionPerformed(ActionEvent e) {
if (actionListeners != null) {
Vector listeners = actionListeners;
int count = listeners.size();
for (int i = 0; i < count; i++) {
((ActionListener) listeners.elementAt(i)).actionPerformed(e);
}
}
}
}
Related examples in the same category