001package myproject.model.swing; 002 003import java.awt.Color; 004import java.awt.Graphics; 005import java.util.ArrayList; 006import java.util.List; 007import myproject.model.AnimatorBuilder; 008import myproject.model.Car; 009import myproject.model.Light; 010import myproject.model.MP; 011import myproject.model.Road; 012import myproject.util.Animator; 013import myproject.util.SwingAnimator; 014import myproject.util.SwingAnimatorPainter; 015 016/** 017 * A class for building Animators. 018 */ 019public class SwingAnimatorBuilder implements AnimatorBuilder { 020 MyPainter painter; 021 public SwingAnimatorBuilder() { 022 painter = new MyPainter(); 023 } 024 public Animator getAnimator() { 025 if (painter == null) { throw new IllegalStateException(); } 026 Animator returnValue = new SwingAnimator(painter, "Traffic Simulator", 027 VP.displayWidth, VP.displayHeight, VP.displayDelay); 028 painter = null; 029 return returnValue; 030 } 031 private static double skipInit = VP.gap; 032 private static double skipRoad = VP.gap + MP.roadLength; 033 private static double skipCar = VP.gap + VP.elementWidth; 034 private static double skipRoadCar = skipRoad + skipCar; 035 public void addLight(Light d, int i, int j) { 036 double x = skipInit + skipRoad + j*skipRoadCar; 037 double y = skipInit + skipRoad + i*skipRoadCar; 038 Translator t = new TranslatorWE(x, y, MP.carLength, VP.elementWidth, VP.scaleFactor); 039 painter.addLight(d,t); 040 } 041 public void addHorizontalRoad(Road l, int i, int j, boolean eastToWest) { 042 double x = skipInit + j*skipRoadCar; 043 double y = skipInit + skipRoad + i*skipRoadCar; 044 Translator t = eastToWest ? new TranslatorEW(x, y, MP.roadLength, VP.elementWidth, VP.scaleFactor) 045 : new TranslatorWE(x, y, MP.roadLength, VP.elementWidth, VP.scaleFactor); 046 painter.addRoad(l,t); 047 } 048 public void addVerticalRoad(Road l, int i, int j, boolean southToNorth) { 049 double x = skipInit + skipRoad + j*skipRoadCar; 050 double y = skipInit + i*skipRoadCar; 051 Translator t = southToNorth ? new TranslatorSN(x, y, MP.roadLength, VP.elementWidth, VP.scaleFactor) 052 : new TranslatorNS(x, y, MP.roadLength, VP.elementWidth, VP.scaleFactor); 053 painter.addRoad(l,t); 054 } 055 056 057 /** Class for drawing the Model. */ 058 private static class MyPainter implements SwingAnimatorPainter { 059 060 /** Pair of a model element <code>x</code> and a translator <code>t</code>. */ 061 private static class Element<T> { 062 T x; 063 Translator t; 064 Element(T x, Translator t) { 065 this.x = x; 066 this.t = t; 067 } 068 } 069 070 private List<Element<Road>> roadElements; 071 private List<Element<Light>> lightElements; 072 MyPainter() { 073 roadElements = new ArrayList<Element<Road>>(); 074 lightElements = new ArrayList<Element<Light>>(); 075 } 076 void addLight(Light x, Translator t) { 077 lightElements.add(new Element<Light>(x,t)); 078 } 079 void addRoad(Road x, Translator t) { 080 roadElements.add(new Element<Road>(x,t)); 081 } 082 083 public void paint(Graphics g) { 084 // This method is called by the swing thread, so may be called 085 // at any time during execution... 086 087 // First draw the background elements 088 for (Element<Light> e : lightElements) { 089 if (e.x.getState()) { 090 g.setColor(Color.BLUE); 091 } else { 092 g.setColor(Color.YELLOW); 093 } 094 XGraphics.fillOval(g, e.t, 0, 0, MP.carLength, VP.elementWidth); 095 } 096 g.setColor(Color.BLACK); 097 for (Element<Road> e : roadElements) { 098 XGraphics.fillRect(g, e.t, 0, 0, MP.roadLength, VP.elementWidth); 099 } 100 101 // Then draw the foreground elements 102 for (Element<Road> e : roadElements) { 103 // iterate through a copy because e.x.getCars() may change during iteration... 104 for (Car d : e.x.getCars().toArray(new Car[0])) { 105 g.setColor(d.getColor()); 106 XGraphics.fillOval(g, e.t, d.getPosition(), 0, MP.carLength, VP.elementWidth); 107 } 108 } 109 } 110 } 111} 112