package gvps.gui; import gvps.data.objects.*; import java.awt.*; import java.awt.geom.*; import javax.swing.*; import java.awt.Color; import java.util.Vector; import java.util.Iterator; public class MapArea extends JComponent implements Runnable { private double scale = 1; private Vector buildings = new Vector(); private Vector roads; private final BasicStroke ROAD = new BasicStroke(5.0f); private final BasicStroke BUILDING = new BasicStroke(0.5f); private final Color BUILDING_INT = new Color(200, 240, 245); private Vector vehicles; private int state; private int carOffset; private Image carImage; private int refreshWait = 60; // animation speed: ~20fps private Graphics2D mapGraphics; private Image mapImage; public MapArea() { setBackground(Color.WHITE); carImage = Toolkit.getDefaultToolkit().getImage("car_icon.png"); vehicles = new Vector(); carOffset = (carImage.getWidth(this) / 2); } /* this might be useful also public MapArea(AreaMap newMap) { this.buildings = newMap.getBuildings(); carImage = Toolkit.getDefaultToolkit().getImage("car_icon.png"); vehicles = new Vector(); carOffset = (carImage.getWidth(this) / 2); drawMap(); } */ public void addVehicle(String vehicleId, Vector path, int speed){ MappedVehicle vehicle = new MappedVehicle(vehicleId, path, speed); vehicles.add(vehicle); Thread vehicleThread = new Thread(vehicle); vehicleThread.start(); } /** * Forces the current location of a vehicle with the specified vehicleID * @param vehicleId the unique identifier of the desired vehicle * @param location the new location of the vehicle */ public void forceVehicleLocation(String vehicleId, Point location){ try { getMappedVehicle(vehicleId).setLocation(location); } catch (VehicleNotFoundException e) { System.out.println(e); } } /** * Changes the predictive speed of a vehicle with the specified vehicleID. * Warning: No mutexes are used to validate the size of vehicles Vector, * resulting in possibly incorrect vehicle counts. * @param vehicleID the id of the vehicle * @param speed the new speed of the chosen vehicle */ public void setVehicleSpeed(String vehicleId, int speed) { try { getMappedVehicle(vehicleId).setSpeed(speed); } catch (VehicleNotFoundException e) { System.out.println(e); } } /** * Pauses a selected vehicles movements. */ public void pauseVehicle(String vehicleId){ } /** * Gets a MappedVehicle object based on it's vehicleId. * @param id the unique identifier of a vehicle * @throws VehicleNotFoundException if a vehicle does not exist with this id */ public MappedVehicle getMappedVehicle(String id) throws VehicleNotFoundException { boolean vehicleFound = false; int totalVehicles = vehicles.size(); int count = 0; // loop through each vehicle looking for one with the right ID while ( !vehicleFound || count < totalVehicles ){ if ( vehicles.get(count).getId().equals(id) ){ vehicleFound = true; } else { count++; } } if ( !vehicleFound ){ throw new VehicleNotFoundException("A vehicle does not exist "+ "with the id \"" + id + "\"" ); } else { return vehicles.get(count); } } public void run(){ while (true){ repaint(); try { Thread.sleep(refreshWait); } catch (InterruptedException e){ System.out.println("This thread has been broken... "+ "I have NO idea what that means"); } } } public void paint(Graphics g){ super.paint(g); /* places a "car" image at every point on the map where a car is * * supposed to be then draws that to the component */ int totalVehicles = vehicles.size(); int positionX; int positionY; g.clearRect(0,0,getWidth(),getHeight()); if ( mapImage != null){ g.drawImage(mapImage, 0, 0, this); } // if we have vehicles, loop through them, get their position, and draw them if ( totalVehicles > 0 ){ for ( int i = 0; i < totalVehicles; i++ ){ MappedVehicle currentVehicle = vehicles.get(i); // check if the current vehicle hasn't reached its destination if ( !currentVehicle.isFinished() ){ positionX = (int)currentVehicle.getLocation().getX() - carOffset; positionY = (int)currentVehicle.getLocation().getY() - carOffset; g.drawImage(carImage, positionX, positionY, this); } // else, remove it from the list of vehicles else { vehicles.remove(i); // compensate for removed vehicle i--; totalVehicles = vehicles.size(); } } } } /** * Updates the current map image in memory according to the currently * stored Map object. */ public void drawMap(){ if ( mapGraphics == null ){ mapImage = createImage(getWidth(), getHeight()); mapGraphics = (Graphics2D)mapImage.getGraphics(); } mapGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //do roads mapGraphics.setStroke(ROAD); if(roads != null) { Iterator i = roads.iterator(); while(i.hasNext()) { Road r = i.next(); mapGraphics.setColor(Color.BLACK); mapGraphics.drawPolyline(r.getX(), r.getY(), r.getX().length); } } //buildings mapGraphics.setStroke(BUILDING); if(buildings != null) { Iterator i = buildings.iterator(); while(i.hasNext()) { Polygon p = i.next(); mapGraphics.setColor(BUILDING_INT); mapGraphics.fillPolygon(p); mapGraphics.setColor(Color.BLACK); mapGraphics.drawPolygon(p); } } } public void setMap(AreaMap map) { Iterator i; i = map.getBuildings().iterator(); System.out.println(map.getBuildings().size()); while(i.hasNext()) { buildings.add(i.next().getPolygon()); } roads = map.getRoads(); System.out.println(roads.size()); drawMap(); } public void zoomIn() { if ( mapGraphics != null ){ scale+=0.01; mapGraphics.transform(AffineTransform.getScaleInstance(scale, scale)); } } public void zoomOut() { if ( mapGraphics != null ){ scale-=0.01; mapGraphics.transform(AffineTransform.getScaleInstance(scale, scale)); } } }