From 3ccaa674fdbd3408d4cbea3ed9abb02c14433b9c Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Fri, 29 May 2015 13:17:53 +0200 Subject: licensing; reorganisation; javadoc; cleanup --- Week14 Route 66/nbproject/project.properties | 2 +- Week14 Route 66/src/OO14route66/Car.java | 149 ---------------- Week14 Route 66/src/OO14route66/Controller.java | 72 -------- Week14 Route 66/src/OO14route66/Direction.java | 70 -------- Week14 Route 66/src/OO14route66/KeyHandler.java | 37 ---- Week14 Route 66/src/OO14route66/Model.java | 136 --------------- Week14 Route 66/src/OO14route66/RoadView.java | 95 ----------- Week14 Route 66/src/OO14route66/Route66.java | 42 ----- Week14 Route 66/src/OO14route66/TableView.java | 65 ------- .../src/com/camilstaps/route66/Car.java | 179 +++++++++++++++++++ .../src/com/camilstaps/route66/Controller.java | 95 +++++++++++ .../src/com/camilstaps/route66/Crossing.java | 61 ------- .../src/com/camilstaps/route66/Direction.java | 89 ++++++++++ .../src/com/camilstaps/route66/Driver.java | 67 ++++++-- .../src/com/camilstaps/route66/KeyHandler.java | 39 +++++ .../src/com/camilstaps/route66/Model.java | 189 +++++++++++++++++++++ .../src/com/camilstaps/route66/RoadView.java | 127 ++++++++++++++ .../src/com/camilstaps/route66/Route66.java | 44 +++++ .../src/com/camilstaps/route66/TableView.java | 65 +++++++ .../src/com/camilstaps/route66/Week14Route66.java | 19 --- 20 files changed, 877 insertions(+), 765 deletions(-) delete mode 100644 Week14 Route 66/src/OO14route66/Car.java delete mode 100644 Week14 Route 66/src/OO14route66/Controller.java delete mode 100644 Week14 Route 66/src/OO14route66/Direction.java delete mode 100644 Week14 Route 66/src/OO14route66/KeyHandler.java delete mode 100644 Week14 Route 66/src/OO14route66/Model.java delete mode 100644 Week14 Route 66/src/OO14route66/RoadView.java delete mode 100644 Week14 Route 66/src/OO14route66/Route66.java delete mode 100644 Week14 Route 66/src/OO14route66/TableView.java create mode 100644 Week14 Route 66/src/com/camilstaps/route66/Car.java create mode 100644 Week14 Route 66/src/com/camilstaps/route66/Controller.java delete mode 100644 Week14 Route 66/src/com/camilstaps/route66/Crossing.java create mode 100644 Week14 Route 66/src/com/camilstaps/route66/Direction.java create mode 100644 Week14 Route 66/src/com/camilstaps/route66/KeyHandler.java create mode 100644 Week14 Route 66/src/com/camilstaps/route66/Model.java create mode 100644 Week14 Route 66/src/com/camilstaps/route66/RoadView.java create mode 100644 Week14 Route 66/src/com/camilstaps/route66/Route66.java create mode 100644 Week14 Route 66/src/com/camilstaps/route66/TableView.java delete mode 100644 Week14 Route 66/src/com/camilstaps/route66/Week14Route66.java diff --git a/Week14 Route 66/nbproject/project.properties b/Week14 Route 66/nbproject/project.properties index 93592ec..63a2ce2 100644 --- a/Week14 Route 66/nbproject/project.properties +++ b/Week14 Route 66/nbproject/project.properties @@ -55,7 +55,7 @@ javadoc.splitindex=true javadoc.use=true javadoc.version=false javadoc.windowtitle= -main.class=OO14route66.Route66 +main.class=com.camilstaps.route66.Route66 manifest.file=manifest.mf meta.inf.dir=${src.dir}/META-INF mkdist.disabled=false diff --git a/Week14 Route 66/src/OO14route66/Car.java b/Week14 Route 66/src/OO14route66/Car.java deleted file mode 100644 index c12291a..0000000 --- a/Week14 Route 66/src/OO14route66/Car.java +++ /dev/null @@ -1,149 +0,0 @@ -package OO14route66; - -import com.camilstaps.route66.Driver; -import java.awt.Color; -import java.awt.Graphics; -import java.util.Random; - -/** - * Class for an individual car - * - * @author Pieter Koopman, Camil Staps - */ -public class Car { - public static final int - CARWIDTH = 20, - CARLENGTH = 40, - MINCARSPACE = 5, - MINCARSPEED = 2, - MAXCARSPEED = 4; - - public static final Color[] carColours = {Color.red, Color.blue, Color.black, Color.gray, Color.green, - Color.pink, Color.orange, Color.magenta, Color.lightGray}; - - private final int speed, number; // speed and car-number - private final Direction direction; // driving direction, used by paint - private int location; // current location on the road - private final Color colour; // colour of this car - private final Random random; // here to ensure that every car gets a new - private final Driver driver; // this car's driver - private final Model model; // the model the car is in - - /** - * The constructor: - * - choose a random speed - * - set right location, direction and colour - * - create new Driver object - * - say hello to the Overviewer - * - * @param number of the car - * @param model the model the car is in - */ - public Car(int number, Model model) { - this.number = number; - random = new Random(); - speed = MINCARSPEED + random.nextInt(MAXCARSPEED - MINCARSPEED + 1); - direction = Direction.intToDirection(number); - location = RoadView.WINDOWSIZE - 2 - (number/Model.DIRECTIONS) * (CARLENGTH + MINCARSPACE); - colour = carColours[number % carColours.length]; - driver = new Driver(this, model); - this.model = model; - } - - /** - * Get the driver - * @return - */ - public Driver getDriver() { - return driver; - } - - /** - * Get the direction - * @return - */ - public Direction getDirection() { - return direction; - } - - /** - * Get the number of this car - * @return - */ - public int getNumber() { - return number; - } - - /** - * Get the current location of this car - * @return - */ - public int getLocation() { - return location; - } - - /** - * Get the location the car would move to if it would move - * @return - */ - public int getNewLocation() { - return (location + speed) % RoadView.WINDOWSIZE; - } - - /** - * Move the car one step - */ - public void step() { - location = getNewLocation(); - //System.err.println("Car "); - model.update(); - } - - public boolean isInFrontOfCrossing() { - return location < RoadView.getStartCrossing() && getNewLocation() >= RoadView.getStartCrossing(); - } - - public boolean isOnCrossing() { - return location > RoadView.getStartCrossing() && location - CARLENGTH < RoadView.getEndCrossing(); - } - - /** - * Paint this car - * @param g - */ - public void paint(Graphics g) { - int x, y, w, h; - switch (direction) { - case North: - x = RoadView.WINDOWSIZE / 2 + 1; - y = RoadView.WINDOWSIZE - location; - w = Car.CARWIDTH; - h = Car.CARLENGTH; - break; - case East: - x = location - Car.CARLENGTH; - y = RoadView.WINDOWSIZE / 2 + 1; - w = Car.CARLENGTH; - h = Car.CARWIDTH; - break; - case South: - x = RoadView.WINDOWSIZE / 2 - Car.CARWIDTH - 1; - y = location - Car.CARLENGTH; - w = Car.CARWIDTH; - h = Car.CARLENGTH; - break; - case West: - x = RoadView.WINDOWSIZE - location - 1; - y = RoadView.WINDOWSIZE / 2 - Car.CARWIDTH - 1; - w = Car.CARLENGTH; - h = Car.CARWIDTH; - break; - default: - x = y = w = h = 10; - } - g.setColor(colour); - g.fillRect(x, y, w, h); - g.setColor(Color.WHITE); - g.drawString(String.valueOf(number), x + w / 6, y + h / 2 + 4); - } -} diff --git a/Week14 Route 66/src/OO14route66/Controller.java b/Week14 Route 66/src/OO14route66/Controller.java deleted file mode 100644 index 83e6098..0000000 --- a/Week14 Route 66/src/OO14route66/Controller.java +++ /dev/null @@ -1,72 +0,0 @@ -package OO14route66; - -import com.camilstaps.route66.Driver; -import java.util.Random; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -/** - * Route66 Controller - * @author Pieter Koopman, Camil Staps - * - * The initial controller runs as a single thread - */ -public class Controller { - private int delay = 120; // average sleep time - private final Model model; // the model - private final Random random; // a random generator - - /** - * The constructor of the controller - * @param model holds the cars - */ - public Controller(Model model) { - this.model = model; - random = new Random(); - } - - /** - * Tell the drivers of all cars in the model to start driving - */ - public void run() { - ExecutorService service = Executors.newCachedThreadPool(); - for (Car car : model.getCars()) { - Driver d = car.getDriver(); - d.setDelay(delay); - service.execute(d); - } - } - - /** - * stop all cars by setting boolean run to false - */ - public void stopCars() { - for (Car car : model.getCars()) { - car.getDriver().setRunning(false); - } - } - - /** - * start all cars by setting boolean run to true - */ - public void resumeCars() { - for (Car car : model.getCars()) { - car.getDriver().setRunning(true); - } - } - - public int getDelay() { - return delay; - } - - /** - * set delay between maximum and minimum bounds - * @param d - */ - public void setDelay(int d) { - delay = Math.max(20, Math.min (2000, d)); - for (Car car : model.getCars()) { - car.getDriver().setDelay(delay); - } - } -} diff --git a/Week14 Route 66/src/OO14route66/Direction.java b/Week14 Route 66/src/OO14route66/Direction.java deleted file mode 100644 index 14d7110..0000000 --- a/Week14 Route 66/src/OO14route66/Direction.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ - -package OO14route66; - -/** - * OO1route66 initial class - * @author Pieter Koopman - * - * Enumeration class for driving directions - */ -public enum Direction -{ - North, East, South, West; - - /** - * convert integer to direction - * if number of directions is 2 only East and West are used, - * otherwise all 4 directions are used - * @param i the integer - * @return the direction - */ - public static Direction intToDirection(int i) { - if (Model.DIRECTIONS == 2) { - switch (i % 2) { - case 0: return East; - default: return West; - } - } else { - switch (i % 4) { - case 0: return North; - case 1: return East; - case 2: return South; - default: return West; - } - } - } - - /** - * Get the opposite of a direction - * @param direction - * @return - */ - public static Direction opposite(Direction direction) { - switch (direction) { - case North: return South; - case South: return North; - case East: return West; - case West: return East; - default: return direction; - } - } - - /** - * override standard toString - * @return string representation of this value - */ - @Override - public String toString() { - switch (this) { - case North: return "North"; - case East: return "East"; - case South: return "South"; - case West: return "West"; - default: return "Unknown direction"; - } - } -} diff --git a/Week14 Route 66/src/OO14route66/KeyHandler.java b/Week14 Route 66/src/OO14route66/KeyHandler.java deleted file mode 100644 index ab78676..0000000 --- a/Week14 Route 66/src/OO14route66/KeyHandler.java +++ /dev/null @@ -1,37 +0,0 @@ -package OO14route66; - -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; - -/** - * Keyboard handler of views for controller. - * Pressing keys changes the controller. - * @author pieterkoopman - */ -public class KeyHandler extends KeyAdapter { - - private Controller controller; - - public KeyHandler (Controller c) { - controller = c; - } - - /** - * on key down 'q' stop program - * on key down 's' stop the cars - * on key down '<' decrease delay - * on key down '>' increase delay - * on any other key activate the cars - * @param e the key event - */ - @Override - public void keyPressed(KeyEvent e) { - switch (e.getKeyChar()) { - case 'q': System.exit(0); - case 's': controller.stopCars(); break; - case '<': controller.setDelay(controller.getDelay() - 50); break; - case '>': controller.setDelay(controller.getDelay() + 50); break; - default : controller.resumeCars(); - } - } -} diff --git a/Week14 Route 66/src/OO14route66/Model.java b/Week14 Route 66/src/OO14route66/Model.java deleted file mode 100644 index ee9da42..0000000 --- a/Week14 Route 66/src/OO14route66/Model.java +++ /dev/null @@ -1,136 +0,0 @@ -package OO14route66; - -import java.util.ArrayList; -import java.util.Observable; -import javax.swing.JFrame; - -/** - * OO1route66 initial class - * @author Pieter Koopman - * - * The class model holds all cars in the simulation - */ -public class Model extends Observable -{ - private final Car [] cars; - public static final int - DIRECTIONS = 4, - NUMBEROFCARS = 5 * DIRECTIONS; // total number of cars in system - - private final ArrayList views; - //private final Crossing crossing = new Crossing(this, Direction.North); - - private Direction allowed; - private boolean crossingWaiting = false; - private long lastCrossingChange = 0; - private static final int MIN_CROSS_TIME = 1000; - - /** - * Constructor: create all cars - */ - public Model() { - views = new ArrayList<>(); - cars = new Car [NUMBEROFCARS]; - for (int c = 0; c < NUMBEROFCARS; c += 1) { - cars[c] = new Car(c, this); - } - } - - /** - * add the view to this model. It will be repainted upon an update - * @param view - */ - public void addView(JFrame view) { - views.add(view); - } - - public Car[] getCars() { - return cars; - } - - /** - * get a car from the model - * @param i numbers of required car - * @return the car itself (not a copy) - */ - public Car getCar(int i) { - return cars[i]; - } - - /** - * repaint all views - */ - public synchronized void update() { - for (JFrame view: views) { - view.repaint(); - } - notifyAll(); - } - - /** - * Check if a location is safe for a car to go to. This should always be - * checked by a driver before actually driving. - * @param car - * @param requested_location - * @return - */ - public synchronized boolean isSafeLocation(Car car, int requested_location) { - Car that_car = cars[car.getNumber() < DIRECTIONS ? car.getNumber() + NUMBEROFCARS - DIRECTIONS : car.getNumber() - DIRECTIONS]; - - boolean ok = !(that_car.getLocation() > requested_location && - that_car.getLocation() < requested_location + Car.CARLENGTH + Car.MINCARSPACE); - - if (car.isInFrontOfCrossing() && !isCrossingAllowed(car.getDirection())) { - ok = doCrossingRequest(); - } - - if (!ok) { - try { - wait(); - } catch (InterruptedException ex) { - } - } - - return ok; - } - - public synchronized boolean isCarsOnCrossing() { - for (Car car : cars) { - if (car.isOnCrossing()) { - return true; - } - } - return false; - } - - public synchronized void doSwitchCrossing() { - crossingWaiting = true; - while (isCarsOnCrossing()) { - try { - wait(); - } catch (InterruptedException ex) { - } - } - System.err.println("Switching"); - if (allowed == Direction.East || allowed == Direction.West) { - allowed = Direction.North; - } else { - allowed = Direction.East; - } - System.err.println("Switched to " + allowed); - crossingWaiting = false; - lastCrossingChange = System.currentTimeMillis(); - } - - public synchronized boolean isCrossingAllowed(Direction direction) { - return !crossingWaiting && (direction == allowed || Direction.opposite(direction) == allowed); - } - - public synchronized boolean doCrossingRequest() { - if (crossingWaiting || System.currentTimeMillis() - lastCrossingChange < MIN_CROSS_TIME) { - return false; - } - doSwitchCrossing(); - return true; - } -} diff --git a/Week14 Route 66/src/OO14route66/RoadView.java b/Week14 Route 66/src/OO14route66/RoadView.java deleted file mode 100644 index 4495822..0000000 --- a/Week14 Route 66/src/OO14route66/RoadView.java +++ /dev/null @@ -1,95 +0,0 @@ -package OO14route66; - -import java.awt.Color; -import java.awt.Graphics; -import javax.swing.JFrame; -import javax.swing.JPanel; - -/** - * OO13route66 animation - * @author Pieter Koopman - * - * Yields a graphical view on all cars - */ -public class RoadView extends JFrame -{ - JPanel panel; // the panel to draw the cars - public static final int WINDOWSIZE = 600; // the window size - private final Model model; // the model knows the position of cars - - /** - * A subclass of JPanel to draw the cars. - * This is a bit of a hack to ensure that this panel is painted correctly. - */ - private class CarPanel extends JPanel { - /** - * Constructor: just call the constructor of the base class - */ - public CarPanel() { - super(); - } - /** - * paint the roads and cars - * @param g Graphics to paint on - */ - @Override - public void paint (Graphics g) { - paintRoad(g); - paintCars(g); - } - } - /** - * The constructor of RoadView - * @param model - */ - RoadView(Model model) { - super("Route66 traffic simulator"); - this.model = model; - setSize(WINDOWSIZE, WINDOWSIZE); - setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); - panel = new CarPanel(); - add(panel); - } - /** - * Paint the view of the model graphically - * @param g - */ - @Override - public void paint(Graphics g) { - super.paint(g); - panel.repaint(); - } - /** - * Paint all cars - * @param g graphics to draw on - */ - private void paintCars (Graphics g) { - for (int i = 0; i < Model.NUMBEROFCARS; i += 1) { - model.getCar(i).paint(g); - } - } - - /** - * Paint the roads - * @param g graphics to draw on - */ - private void paintRoad (Graphics g) { - final int left = getStartCrossing(); - final int width = getEndCrossing() - left; - g.setColor(Color.white); // background - g.fillRect(0, 0, WINDOWSIZE, WINDOWSIZE); - g.setColor(Color.darkGray); // streets - g.fillRect(0, left, WINDOWSIZE, width); - if (Model.DIRECTIONS > 2) { // paint a crossing if there are 4 directions - g.fillRect(left, 0, width, WINDOWSIZE); - } - } - - public static int getStartCrossing() { - return (WINDOWSIZE / 2) - Car.CARWIDTH - 4; - } - - public static int getEndCrossing() { - return getStartCrossing() + 2 * Car.CARWIDTH + 8; - } -} diff --git a/Week14 Route 66/src/OO14route66/Route66.java b/Week14 Route 66/src/OO14route66/Route66.java deleted file mode 100644 index f6b3f1f..0000000 --- a/Week14 Route 66/src/OO14route66/Route66.java +++ /dev/null @@ -1,42 +0,0 @@ -package OO14route66; - -/** - * OO1route66 initial class - * @author Pieter Koopman - * Route66 class constructs model, view and controller - */ -public class Route66 -{ - Controller controller; - /** - * the main method for OO13route66 - * @param args the command line arguments - */ - public static void main(String[] args) { - Route66 r66 = new Route66(); - } - - /** - * the main constructor: - * - creates model, controller and views - */ - public Route66() { - Model model = new Model(); - - RoadView rview = new RoadView(model); - TableView tview = new TableView(model); - model.addView(tview); - model.addView(rview); - - controller = new Controller(model); - - KeyHandler keyHandler = new KeyHandler(controller); - rview.addKeyListener(keyHandler); - tview.addKeyListener(keyHandler); - - tview.setVisible(true); - rview.setVisible(true); - - controller.run(); - } -} diff --git a/Week14 Route 66/src/OO14route66/TableView.java b/Week14 Route 66/src/OO14route66/TableView.java deleted file mode 100644 index 9f2546f..0000000 --- a/Week14 Route 66/src/OO14route66/TableView.java +++ /dev/null @@ -1,65 +0,0 @@ -package OO14route66; - -import java.awt.Graphics; -import java.awt.GridLayout; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; - -/** - * OO14route66 initial class - * @author Pieter Koopman - */ -public class TableView extends JFrame -{ - JPanel panel; - public static final int WINDOWWITDH = 100 * Model.DIRECTIONS, WINDOWHEIGTH = 200; - JLabel [] textLabels; - private final Model model; // for the positions of the cars - - /** - * The constructor of TableView - * @param model containing the position of the cars to display - * makes a panel with a gridLayout and a JLabel for each car in this panel - */ - TableView(Model model) { - super("Route66 table view"); - this.model = model; - setSize(WINDOWWITDH, WINDOWHEIGTH); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - panel = new JPanel(); - panel.setLayout(new GridLayout(Model.NUMBEROFCARS / Model.DIRECTIONS + 1, Model.DIRECTIONS)); - - for (int i = 0; i < Model.DIRECTIONS; i += 1) { // make table headings - panel.add(new JLabel(Direction.intToDirection(i).toString())); - } - - textLabels = new JLabel[Model.NUMBEROFCARS]; // make car info - for (int c = 0; c < Model.NUMBEROFCARS; c += 1) { - textLabels[c] = new JLabel(label(c)); - panel.add(textLabels[c]); - } - add(panel); - } - - /** - * update the JLabel for each car - * @param g - */ - @Override - public void paint(Graphics g) { - super.paint(g); - for (int c = 0; c < Model.NUMBEROFCARS; c += 1) { - textLabels[c].setText(label(c)); - } - } - - /** - * create a label for the given car number - * @param c: car number - * @return string representing the car information - */ - private String label(int c) { - return c + ": " + model.getCar(c).getLocation(); - } -} diff --git a/Week14 Route 66/src/com/camilstaps/route66/Car.java b/Week14 Route 66/src/com/camilstaps/route66/Car.java new file mode 100644 index 0000000..b118a3c --- /dev/null +++ b/Week14 Route 66/src/com/camilstaps/route66/Car.java @@ -0,0 +1,179 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Camil Staps + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.camilstaps.route66; + +import java.awt.Color; +import java.awt.Graphics; +import java.util.Random; + +/** + * Class for an individual car + * + * @author Pieter Koopman, Camil Staps + */ +public class Car { + public static final int + CARWIDTH = 20, + CARLENGTH = 40, + MINCARSPACE = 5, + MINCARSPEED = 2, + MAXCARSPEED = 4; + + public static final Color[] carColours = {Color.red, Color.blue, Color.black, Color.gray, Color.green, + Color.pink, Color.orange, Color.magenta, Color.lightGray}; + + private final int speed, number; // speed and car-number + private final Direction direction; // driving direction, used by paint + private int location; // current location on the road + private final Color colour; // colour of this car + private final Random random; // here to ensure that every car gets a new + private final Driver driver; // this car's driver + private final Model model; // the model the car is in + + /** + * The constructor: + * - choose a random speed + * - set right location, direction and colour + * - create new Driver object + * + * @param number of the car + * @param model the model the car is in + */ + public Car(int number, Model model) { + this.number = number; + random = new Random(); + speed = MINCARSPEED + random.nextInt(MAXCARSPEED - MINCARSPEED + 1); + direction = Direction.intToDirection(number); + location = RoadView.WINDOWSIZE - 2 - (number/Model.DIRECTIONS) * (CARLENGTH + MINCARSPACE); + colour = carColours[number % carColours.length]; + this.model = model; + driver = new Driver(this, model); + } + + /** + * Get the driver + * @return + */ + public Driver getDriver() { + return driver; + } + + /** + * Get the direction + * @return + */ + public Direction getDirection() { + return direction; + } + + /** + * Get the number of this car + * @return + */ + public int getNumber() { + return number; + } + + /** + * Get the current location of this car + * @return + */ + public int getLocation() { + return location; + } + + /** + * Get the location the car would move to if it would move + * @return + */ + public int getNewLocation() { + return (location + speed) % RoadView.WINDOWSIZE; + } + + /** + * Move the car one step + */ + public void step() { + location = getNewLocation(); + //System.err.println("Car "); + model.update(); + } + + /** + * Is the car in front of the crossing? That is, is the car now not on the + * crossing but would it be there after the next step? + * @return + */ + public boolean isInFrontOfCrossing() { + return location < RoadView.getStartCrossing() && getNewLocation() >= RoadView.getStartCrossing(); + } + + /** + * Is the car on the crossing? + * @return + */ + public boolean isOnCrossing() { + return location > RoadView.getStartCrossing() && location - CARLENGTH < RoadView.getEndCrossing(); + } + + /** + * Paint this car + * @param g + */ + public void paint(Graphics g) { + int x, y, w, h; + switch (direction) { + case North: + x = RoadView.WINDOWSIZE / 2 + 1; + y = RoadView.WINDOWSIZE - location; + w = Car.CARWIDTH; + h = Car.CARLENGTH; + break; + case East: + x = location - Car.CARLENGTH; + y = RoadView.WINDOWSIZE / 2 + 1; + w = Car.CARLENGTH; + h = Car.CARWIDTH; + break; + case South: + x = RoadView.WINDOWSIZE / 2 - Car.CARWIDTH - 1; + y = location - Car.CARLENGTH; + w = Car.CARWIDTH; + h = Car.CARLENGTH; + break; + case West: + x = RoadView.WINDOWSIZE - location - 1; + y = RoadView.WINDOWSIZE / 2 - Car.CARWIDTH - 1; + w = Car.CARLENGTH; + h = Car.CARWIDTH; + break; + default: + x = y = w = h = 10; + } + g.setColor(colour); + g.fillRect(x, y, w, h); + g.setColor(Color.WHITE); + g.drawString(String.valueOf(number), x + w / 6, y + h / 2 + 4); + } +} diff --git a/Week14 Route 66/src/com/camilstaps/route66/Controller.java b/Week14 Route 66/src/com/camilstaps/route66/Controller.java new file mode 100644 index 0000000..e0eff83 --- /dev/null +++ b/Week14 Route 66/src/com/camilstaps/route66/Controller.java @@ -0,0 +1,95 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Camil Staps + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.camilstaps.route66; + +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Route66 Controller + * + * Use different threads for every driver + * + * @author Pieter Koopman, Camil Staps + */ +public class Controller { + private int delay = 120; // average sleep time + private final Model model; // the model + private final Random random; // a random generator + + /** + * The constructor of the controller + * @param model holds the cars + */ + public Controller(Model model) { + this.model = model; + random = new Random(); + } + + /** + * Tell the drivers of all cars in the model to start driving + */ + public void run() { + ExecutorService service = Executors.newCachedThreadPool(); + for (Car car : model.getCars()) { + Driver d = car.getDriver(); + d.setDelay(delay); + service.execute(d); + } + } + + /** + * Stop all cars + */ + public void stopCars() { + for (Car car : model.getCars()) { + car.getDriver().stopRunning(); + } + } + + /** + * Resume all cars + */ + public void resumeCars() { + for (Car car : model.getCars()) { + car.getDriver().resumeRunning(); + } + } + + public int getDelay() { + return delay; + } + + /** + * Set delay between maximum and minimum bounds + * @param d + */ + public void setDelay(int d) { + delay = Math.max(20, Math.min (2000, d)); + for (Car car : model.getCars()) { + car.getDriver().setDelay(delay); + } + } +} diff --git a/Week14 Route 66/src/com/camilstaps/route66/Crossing.java b/Week14 Route 66/src/com/camilstaps/route66/Crossing.java deleted file mode 100644 index 65e2527..0000000 --- a/Week14 Route 66/src/com/camilstaps/route66/Crossing.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2015 Camil Staps - */ -package com.camilstaps.route66; - -import OO14route66.Direction; -import OO14route66.Model; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * - * @author camilstaps - */ -public class Crossing { - - private final Model model; - private Direction allowed; - private boolean crossingWaiting = false; - private int requests = 0; - - public Crossing(Model model, Direction allowed) { - this.model = model; - this.allowed = allowed; - } - - public Direction getAllowed() { - return allowed; - } - - public synchronized void doSwitch() { - crossingWaiting = true; - while (!model.isCarsOnCrossing()); - System.err.println("Switching"); - if (allowed == Direction.East || allowed == Direction.West) { - allowed = Direction.North; - } else { - allowed = Direction.East; - } - requests = 0; - System.err.println("Switched to " + allowed); - crossingWaiting = false; - //notifyAll(); - } - - public boolean isAllowed(Direction direction) { - return !crossingWaiting && (direction == allowed || Direction.opposite(direction) == allowed); - } - - public boolean doRequest() { - //if (++requests >= 2) { - if (crossingWaiting) { - return false; - } - doSwitch(); - return true; - //} - //return false; - } - -} diff --git a/Week14 Route 66/src/com/camilstaps/route66/Direction.java b/Week14 Route 66/src/com/camilstaps/route66/Direction.java new file mode 100644 index 0000000..ef69caa --- /dev/null +++ b/Week14 Route 66/src/com/camilstaps/route66/Direction.java @@ -0,0 +1,89 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Camil Staps + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.camilstaps.route66; + +/** + * OO1route66 initial class + * + * Enumeration class for driving directions + * + * @author Pieter Koopman, Camil Staps + */ +public enum Direction +{ + North, East, South, West; + + /** + * convert integer to direction + * if number of directions is 2 only East and West are used, + * otherwise all 4 directions are used + * @param i the integer + * @return the direction + */ + public static Direction intToDirection(int i) { + if (Model.DIRECTIONS == 2) { + switch (i % 2) { + case 0: return East; + default: return West; + } + } else { + switch (i % 4) { + case 0: return North; + case 1: return East; + case 2: return South; + default: return West; + } + } + } + + /** + * Get the opposite of a direction + * @param direction + * @return + */ + public static Direction opposite(Direction direction) { + switch (direction) { + case North: return South; + case South: return North; + case East: return West; + case West: return East; + default: return direction; + } + } + + /** + * override standard toString + * @return string representation of this value + */ + @Override + public String toString() { + switch (this) { + case North: return "North"; + case East: return "East"; + case South: return "South"; + case West: return "West"; + default: return "Unknown direction"; + } + } +} diff --git a/Week14 Route 66/src/com/camilstaps/route66/Driver.java b/Week14 Route 66/src/com/camilstaps/route66/Driver.java index 4a323cd..ff603c8 100644 --- a/Week14 Route 66/src/com/camilstaps/route66/Driver.java +++ b/Week14 Route 66/src/com/camilstaps/route66/Driver.java @@ -1,14 +1,33 @@ /* - * Copyright (c) 2015 Camil Staps + * The MIT License (MIT) + * + * Copyright (c) 2015 Camil Staps + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ package com.camilstaps.route66; -import OO14route66.Car; -import OO14route66.Model; import java.util.Random; /** * A Driver takes care its car doesn't collide + * * @author Camil Staps */ public class Driver implements Runnable { @@ -18,7 +37,7 @@ public class Driver implements Runnable { private final Random r; - private boolean running, waitingToCross = false; + private boolean running = false; private int delay; public Driver(Car car, Model model) { @@ -28,19 +47,22 @@ public class Driver implements Runnable { } /** - * Set running to false to disable driving altogether - * @param value + * Stop running */ - public void setRunning(boolean value) { - running = value; - } - - public void setWaitingToCross(boolean value) { - waitingToCross = value; + public void stopRunning() { + running = false; } - public boolean getWaitingToCross() { - return waitingToCross; + /** + * Resume running + */ + public void resumeRunning() { + if (running == false) { + synchronized (this) { + running = true; + notifyAll(); + } + } } /** @@ -53,11 +75,20 @@ public class Driver implements Runnable { } @Override - @SuppressWarnings("empty-statement") - public void run() { + /** + * Forever wait for safety, step and pause for a pseudorandom time. + */ + public synchronized void run() { running = true; while (true) { - while (!running || !model.isSafeLocation(car, car.getNewLocation())); + do { + while (!running) { + try { + wait(); + } catch (InterruptedException ex) { + } + } + } while (!model.isSafeLocation(car, car.getNewLocation())); car.step(); @@ -74,7 +105,7 @@ public class Driver implements Runnable { if (Math.abs((System.currentTimeMillis() / 1000) % Model.NUMBEROFCARS - car.getNumber()) < 2) { bonus = -50; } - Thread.sleep(Math.abs(r.nextInt(50) + delay + bonus)); + Thread.sleep(Math.abs(r.nextInt(100) + delay + bonus)); } catch (InterruptedException ex) {} } diff --git a/Week14 Route 66/src/com/camilstaps/route66/KeyHandler.java b/Week14 Route 66/src/com/camilstaps/route66/KeyHandler.java new file mode 100644 index 0000000..eb84b6f --- /dev/null +++ b/Week14 Route 66/src/com/camilstaps/route66/KeyHandler.java @@ -0,0 +1,39 @@ +package com.camilstaps.route66; + +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +/** + * Keyboard handler of views for controller. + * + * Pressing keys changes the controller. + * + * @author Pieter Koopman, Camil Staps + */ +public class KeyHandler extends KeyAdapter { + + private final Controller controller; + + public KeyHandler (Controller c) { + controller = c; + } + + /** + * on key down 'q' stop program + * on key down 's' stop the cars + * on key down '<' decrease delay + * on key down '>' increase delay + * on any other key activate the cars + * @param e the key event + */ + @Override + public void keyPressed(KeyEvent e) { + switch (e.getKeyChar()) { + case 'q': System.exit(0); + case 's': controller.stopCars(); break; + case '<': controller.setDelay(controller.getDelay() - 50); break; + case '>': controller.setDelay(controller.getDelay() + 50); break; + default : controller.resumeCars(); + } + } +} diff --git a/Week14 Route 66/src/com/camilstaps/route66/Model.java b/Week14 Route 66/src/com/camilstaps/route66/Model.java new file mode 100644 index 0000000..6e43e29 --- /dev/null +++ b/Week14 Route 66/src/com/camilstaps/route66/Model.java @@ -0,0 +1,189 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Camil Staps + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.camilstaps.route66; + +import java.util.ArrayList; +import java.util.Observable; +import javax.swing.JFrame; + +/** + * Route 66 model with crossing + * + * The class model holds all cars in the simulation. + * + * @author Pieter Koopman, Camil Staps + */ +public class Model extends Observable { + + private final Car [] cars; + public static final int + DIRECTIONS = 4, + NUMBEROFCARS = 5 * DIRECTIONS; // total number of cars in system + + private final ArrayList views; + + /** + * Crossing attributes: + * + * allowed - which direction is currently allowed; if East is allowed, West + * is also allowed, etc. + * crossingWaiting - whether or not the crossing is waiting for cars to + * leave the crossing to switch (i.e. orange) + * lastCrossingChange - when the crossing switched the last time + * MIN_CROSS_TIME - the minimum time the crossing should wait before + * switching again after the last switch + */ + private Direction allowed = Direction.East; + private boolean crossingWaiting = false; + private long lastCrossingChange = 0; + private static final int MIN_CROSS_TIME = 1000; + + /** + * Constructor: create all cars + */ + public Model() { + views = new ArrayList<>(); + cars = new Car [NUMBEROFCARS]; + for (int c = 0; c < NUMBEROFCARS; c += 1) { + cars[c] = new Car(c, this); + } + } + + /** + * add the view to this model. It will be repainted upon an update + * @param view + */ + public void addView(JFrame view) { + views.add(view); + } + + public Car[] getCars() { + return cars; + } + + /** + * Get a car from the model + * @param i numbers of required car + * @return the car itself (not a copy) + */ + public Car getCar(int i) { + return cars[i]; + } + + /** + * Repaint all views, and notify all drivers to reconsider driving + */ + public synchronized void update() { + for (JFrame view: views) { + view.repaint(); + } + notifyAll(); + } + + /** + * Check if a location is safe for a car to go to. This should always be + * checked by a driver before actually driving. + * @param car + * @param requested_location + * @return + */ + public synchronized boolean isSafeLocation(Car car, int requested_location) { + // Check that we don't collide with the car in front of us + Car that_car = cars[car.getNumber() < DIRECTIONS ? car.getNumber() + NUMBEROFCARS - DIRECTIONS : car.getNumber() - DIRECTIONS]; + boolean ok = !(that_car.getLocation() > requested_location && + that_car.getLocation() < requested_location + Car.CARLENGTH + Car.MINCARSPACE); + + // If we have to wait for the crossing... well, do that. + if (car.isInFrontOfCrossing() && !isCrossingAllowed(car.getDirection())) { + ok = doCrossingRequest(); + } + + if (!ok) { + try { + wait(); + } catch (InterruptedException ex) {} + } + + return ok; + } + + /** + * Check if there are any cars on the crossing + * @return + */ + public synchronized boolean isCarsOnCrossing() { + for (Car car : cars) { + if (car.isOnCrossing()) { + return true; + } + } + return false; + } + + /** + * Switch the crossing + */ + public synchronized void doSwitchCrossing() { + crossingWaiting = true; + + while (isCarsOnCrossing()) { + try { + wait(); + } catch (InterruptedException ex) { + } + } + + if (allowed == Direction.East || allowed == Direction.West) { + allowed = Direction.North; + } else { + allowed = Direction.East; + } + + crossingWaiting = false; + lastCrossingChange = System.currentTimeMillis(); + } + + /** + * Check if crossing in some direction is allowed + * @param direction + * @return + */ + public synchronized boolean isCrossingAllowed(Direction direction) { + return !crossingWaiting && (direction == allowed || Direction.opposite(direction) == allowed); + } + + /** + * Try to switch the crossing + * This may return false without even trying to switch, if it's too early to + * ask (see {@link Model#MIN_CROSS_TIME}) or if a request has been made already. + * @return + */ + public synchronized boolean doCrossingRequest() { + if (crossingWaiting || System.currentTimeMillis() - lastCrossingChange < MIN_CROSS_TIME) { + return false; + } + doSwitchCrossing(); + return true; + } +} diff --git a/Week14 Route 66/src/com/camilstaps/route66/RoadView.java b/Week14 Route 66/src/com/camilstaps/route66/RoadView.java new file mode 100644 index 0000000..660d44e --- /dev/null +++ b/Week14 Route 66/src/com/camilstaps/route66/RoadView.java @@ -0,0 +1,127 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Camil Staps + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.camilstaps.route66; + +import java.awt.Color; +import java.awt.Graphics; +import javax.swing.JFrame; +import javax.swing.JPanel; + +/** + * OO13route66 animation + * + * Yields a graphical view on all cars + * + * @author Pieter Koopman, Camil Staps + */ +public class RoadView extends JFrame +{ + JPanel panel; // the panel to draw the cars + public static final int WINDOWSIZE = 600; // the window size + private final Model model; // the model knows the position of cars + + /** + * A subclass of JPanel to draw the cars. + * This is a bit of a hack to ensure that this panel is painted correctly. + */ + private class CarPanel extends JPanel { + /** + * Constructor: just call the constructor of the base class + */ + public CarPanel() { + super(); + } + /** + * paint the roads and cars + * @param g Graphics to paint on + */ + @Override + public void paint (Graphics g) { + paintRoad(g); + paintCars(g); + } + } + /** + * The constructor of RoadView + * @param model + */ + RoadView(Model model) { + super("Route66 traffic simulator"); + this.model = model; + setSize(WINDOWSIZE, WINDOWSIZE); + setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); + panel = new CarPanel(); + add(panel); + } + /** + * Paint the view of the model graphically + * @param g + */ + @Override + public void paint(Graphics g) { + super.paint(g); + panel.repaint(); + } + /** + * Paint all cars + * @param g graphics to draw on + */ + private void paintCars (Graphics g) { + for (int i = 0; i < Model.NUMBEROFCARS; i += 1) { + model.getCar(i).paint(g); + } + } + + /** + * Paint the roads + * @param g graphics to draw on + */ + private void paintRoad (Graphics g) { + final int left = getStartCrossing(); + final int width = getEndCrossing() - left; + g.setColor(Color.white); // background + g.fillRect(0, 0, WINDOWSIZE, WINDOWSIZE); + g.setColor(Color.darkGray); // streets + g.fillRect(0, left, WINDOWSIZE, width); + if (Model.DIRECTIONS > 2) { // paint a crossing if there are 4 directions + g.fillRect(left, 0, width, WINDOWSIZE); + } + } + + /** + * Get the relevant half of the coordinate where the crossing starts + * @return + */ + public static int getStartCrossing() { + return (WINDOWSIZE / 2) - Car.CARWIDTH - 4; + } + + /** + * Get the relevant half of the coordinate where the crossing ends + * @return + */ + public static int getEndCrossing() { + return getStartCrossing() + 2 * Car.CARWIDTH + 8; + } +} diff --git a/Week14 Route 66/src/com/camilstaps/route66/Route66.java b/Week14 Route 66/src/com/camilstaps/route66/Route66.java new file mode 100644 index 0000000..8f9a2e9 --- /dev/null +++ b/Week14 Route 66/src/com/camilstaps/route66/Route66.java @@ -0,0 +1,44 @@ +package com.camilstaps.route66; + +/** + * OO1route66 initial class + * + * Route66 class constructs model, view and controller + * + * @author Pieter Koopman + */ +public class Route66 +{ + Controller controller; + /** + * the main method for OO13route66 + * @param args the command line arguments + */ + public static void main(String[] args) { + Route66 r66 = new Route66(); + } + + /** + * the main constructor: + * - creates model, controller and views + */ + public Route66() { + Model model = new Model(); + + RoadView rview = new RoadView(model); + TableView tview = new TableView(model); + model.addView(tview); + model.addView(rview); + + controller = new Controller(model); + + KeyHandler keyHandler = new KeyHandler(controller); + rview.addKeyListener(keyHandler); + tview.addKeyListener(keyHandler); + + tview.setVisible(true); + rview.setVisible(true); + + controller.run(); + } +} diff --git a/Week14 Route 66/src/com/camilstaps/route66/TableView.java b/Week14 Route 66/src/com/camilstaps/route66/TableView.java new file mode 100644 index 0000000..1aa38f7 --- /dev/null +++ b/Week14 Route 66/src/com/camilstaps/route66/TableView.java @@ -0,0 +1,65 @@ +package com.camilstaps.route66; + +import java.awt.Graphics; +import java.awt.GridLayout; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; + +/** + * OO14route66 initial class + * @author Pieter Koopman + */ +public class TableView extends JFrame +{ + JPanel panel; + public static final int WINDOWWITDH = 100 * Model.DIRECTIONS, WINDOWHEIGTH = 200; + JLabel [] textLabels; + private final Model model; // for the positions of the cars + + /** + * The constructor of TableView + * @param model containing the position of the cars to display + * makes a panel with a gridLayout and a JLabel for each car in this panel + */ + TableView(Model model) { + super("Route66 table view"); + this.model = model; + setSize(WINDOWWITDH, WINDOWHEIGTH); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + panel = new JPanel(); + panel.setLayout(new GridLayout(Model.NUMBEROFCARS / Model.DIRECTIONS + 1, Model.DIRECTIONS)); + + for (int i = 0; i < Model.DIRECTIONS; i += 1) { // make table headings + panel.add(new JLabel(Direction.intToDirection(i).toString())); + } + + textLabels = new JLabel[Model.NUMBEROFCARS]; // make car info + for (int c = 0; c < Model.NUMBEROFCARS; c += 1) { + textLabels[c] = new JLabel(label(c)); + panel.add(textLabels[c]); + } + add(panel); + } + + /** + * update the JLabel for each car + * @param g + */ + @Override + public void paint(Graphics g) { + super.paint(g); + for (int c = 0; c < Model.NUMBEROFCARS; c += 1) { + textLabels[c].setText(label(c)); + } + } + + /** + * create a label for the given car number + * @param c: car number + * @return string representing the car information + */ + private String label(int c) { + return c + ": " + model.getCar(c).getLocation(); + } +} diff --git a/Week14 Route 66/src/com/camilstaps/route66/Week14Route66.java b/Week14 Route 66/src/com/camilstaps/route66/Week14Route66.java deleted file mode 100644 index 30b7bd2..0000000 --- a/Week14 Route 66/src/com/camilstaps/route66/Week14Route66.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2015 Camil Staps - */ -package com.camilstaps.route66; - -/** - * - * @author camilstaps - */ -public class Week14Route66 { - - /** - * @param args the command line arguments - */ - public static void main(String[] args) { - // TODO code application logic here - } - -} -- cgit v1.2.3