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); } } } }
1. | FontChooser dialog | ||
2. | Oval Panel | ||
3. | Customized component | ||
4. | Ploygon Button | ||
5. | Demonstrating the Box Component | ||
6. | The MyBean JavaBean Component | ||
7. | Alias Bean |