Merge branch 'master' of https://eng-git.canterbury.ac.nz/seng302-2017/team-7 into changeStartingPositions2
This commit is contained in:
Generated
+3
@@ -0,0 +1,3 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings default="" />
|
||||
</component>
|
||||
@@ -22,11 +22,11 @@ public class Constants {
|
||||
public static final GPSCoordinate finishLineMarker2 = new GPSCoordinate(32.317257, -64.836260);
|
||||
|
||||
public static final BoatInRace[] OFFICIAL_AC35_COMPETITORS = new BoatInRace[]
|
||||
{new BoatInRace("Oracle Team USA", 30.0, Color.BLUEVIOLET, "USA"),
|
||||
{new BoatInRace("Oracle Team USA", 30.0, Color.BLUEVIOLET, "Oracle"),
|
||||
new BoatInRace("Land Rover BAR", 23.0, Color.BLACK, "BAR"),
|
||||
new BoatInRace("SoftBank Team Japan", 27.0, Color.RED, "JAP"),
|
||||
new BoatInRace("Groupama Team France", 25.0, Color.ORANGE, "FRN"),
|
||||
new BoatInRace("Artemis Racing", 22.5, Color.DARKOLIVEGREEN, "ART"),
|
||||
new BoatInRace("Emirates Team New Zealand", 62, Color.LIMEGREEN, "ENZ")};
|
||||
new BoatInRace("Emirates Team New Zealand", 62, Color.LIMEGREEN, "ETNZ")};
|
||||
|
||||
}
|
||||
|
||||
@@ -2,21 +2,28 @@ package seng302.Controllers;
|
||||
|
||||
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.SplitPane;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.util.Callback;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.geotools.referencing.GeodeticCalculator;
|
||||
import seng302.Constants;
|
||||
import seng302.GPSCoordinate;
|
||||
import seng302.Model.*;
|
||||
import seng302.RaceXMLReader;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.IOException;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
@@ -25,20 +32,30 @@ import java.util.ResourceBundle;
|
||||
/**
|
||||
* Created by fwy13 on 15/03/2017.
|
||||
*/
|
||||
public class RaceController extends Controller {
|
||||
|
||||
ResizableRaceCanvas raceMap;
|
||||
public class RaceController extends Controller{
|
||||
@FXML
|
||||
AnchorPane canvasBase;
|
||||
|
||||
ResizableRaceCanvas raceMap;
|
||||
|
||||
@FXML
|
||||
GridPane startScreen;
|
||||
@FXML
|
||||
SplitPane ongoingRacePane;
|
||||
|
||||
@FXML
|
||||
CheckBox showFPS;
|
||||
|
||||
@FXML
|
||||
public CheckBox showAnno;
|
||||
|
||||
@FXML
|
||||
Label timer;
|
||||
|
||||
@FXML
|
||||
Label FPS;
|
||||
|
||||
|
||||
@FXML
|
||||
TableView<BoatInRace> boatInfoTable;
|
||||
@FXML
|
||||
@@ -108,6 +125,7 @@ public class RaceController extends Controller {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes and runs the race, based on the user's chosen scale factor
|
||||
* Currently uses an example racecourse
|
||||
@@ -115,8 +133,22 @@ public class RaceController extends Controller {
|
||||
* @param scaleFactor
|
||||
*/
|
||||
private void startRace(int scaleFactor) {
|
||||
BoatInRace[] boats = generateAC35Competitors();
|
||||
RaceXMLReader raceXMLReader = null;
|
||||
try {
|
||||
raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SAXException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ParserConfigurationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
BoatInRace[] boats = new BoatInRace[raceXMLReader.getBoats().size()];
|
||||
boats = raceXMLReader.getBoats().toArray(boats);
|
||||
//BoatInRace[] boats = generateAC35Competitors();
|
||||
|
||||
raceMap = new ResizableRaceCanvas();
|
||||
raceMap.setMouseTransparent(true);
|
||||
raceMap.widthProperty().bind(canvasBase.widthProperty());
|
||||
raceMap.heightProperty().bind(canvasBase.heightProperty());
|
||||
raceMap.setBoats(boats);
|
||||
@@ -127,16 +159,35 @@ public class RaceController extends Controller {
|
||||
startScreen.setVisible(false);
|
||||
ongoingRacePane.setVisible(true);
|
||||
|
||||
ArrayList<Leg> legs = generateBermudaCourseLegs();
|
||||
//ArrayList<Leg> legs = generateBermudaCourseLegs();
|
||||
ArrayList<Leg> legs = raceXMLReader.getLegs();
|
||||
ConstantVelocityRace race = new ConstantVelocityRace(boats, legs, this, scaleFactor);
|
||||
|
||||
showFPS.setVisible(true);
|
||||
showFPS.selectedProperty().addListener(new ChangeListener<Boolean>() {
|
||||
public void changed(ObservableValue<? extends Boolean> ov,
|
||||
Boolean old_val, Boolean new_val) {
|
||||
if (showFPS.isSelected()){
|
||||
FPS.setVisible(true);
|
||||
} else {
|
||||
FPS.setVisible(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
(new Thread(race)).start();
|
||||
showAnno.selectedProperty().addListener(new ChangeListener<Boolean>() {
|
||||
public void changed(ObservableValue<? extends Boolean> ov,
|
||||
Boolean old_val, Boolean new_val) {
|
||||
raceMap.toggleAnno();
|
||||
}
|
||||
});
|
||||
|
||||
new Thread((race)).start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates an example race course (Bermuda 2017)
|
||||
*
|
||||
* Function for the Bermuda Race.
|
||||
* @return legs in the Bermuda Race.
|
||||
*/
|
||||
private ArrayList<Leg> generateBermudaCourseLegs() {
|
||||
@@ -175,4 +226,7 @@ public class RaceController extends Controller {
|
||||
timer.setText(time);
|
||||
}
|
||||
|
||||
public void setFrames(String fps) { FPS.setText((fps)); }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public class Boat {
|
||||
*/
|
||||
public Boat(String name, double velocity, String abbrev) {
|
||||
this.velocity = velocity;
|
||||
this.velocityProp = new SimpleStringProperty(String.valueOf(velocity));
|
||||
this.velocityProp = new SimpleStringProperty(String.valueOf(velocity* 1.94384));
|
||||
this.abbrev = abbrev;
|
||||
this.name = new SimpleStringProperty(name);
|
||||
}
|
||||
@@ -54,7 +54,7 @@ public class Boat {
|
||||
* @return Name of the boat.
|
||||
*/
|
||||
public String toString() {
|
||||
return getName().toString();
|
||||
return getName().getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package seng302.Model;
|
||||
|
||||
|
||||
import javafx.animation.AnimationTimer;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableArray;
|
||||
import javafx.collections.ObservableList;
|
||||
import org.geotools.referencing.GeodeticCalculator;
|
||||
import seng302.Controllers.RaceController;
|
||||
@@ -27,14 +30,13 @@ public abstract class Race implements Runnable {
|
||||
protected int scaleFactor;
|
||||
|
||||
private int SLEEP_TIME = 100; //time in milliseconds to pause in a paced loop
|
||||
protected int PRERACE_TIME = 100;//Integer.MAX_VALUE; //time in milliseconds to pause during pre-race
|
||||
protected int PRERACE_TIME = 10000;//Integer.MAX_VALUE; //time in milliseconds to pause during pre-race
|
||||
private boolean timerEnabled = true;
|
||||
|
||||
/**
|
||||
* Initailiser for Race
|
||||
*
|
||||
* @param boats Takes in an array of boats that are participating in the race.
|
||||
* @param legs Number of marks in order that the boats pass in order to complete the race.
|
||||
* @param legs Number of marks in order that the boats pass in order to complete the race.
|
||||
*/
|
||||
public Race(BoatInRace[] boats, ArrayList<Leg> legs, RaceController controller, int scaleFactor) {
|
||||
|
||||
@@ -50,7 +52,6 @@ public abstract class Race implements Runnable {
|
||||
|
||||
/**
|
||||
* Constructor for Race class
|
||||
*
|
||||
* @param boats boats participating in the race.
|
||||
* @param legs legs that there are in the race.
|
||||
*/
|
||||
@@ -90,33 +91,21 @@ public abstract class Race implements Runnable {
|
||||
*/
|
||||
public void run() {
|
||||
setControllerListeners();
|
||||
preRace();
|
||||
if (timerEnabled) countdownTimer();
|
||||
initialiseBoats();
|
||||
if(timerEnabled) countdownTimer();
|
||||
simulateRace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the timer
|
||||
*/
|
||||
public void disableTimer() {
|
||||
timerEnabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the boats,
|
||||
* Sets the boats' current to the first leg in the race
|
||||
*/
|
||||
private void preRace() {
|
||||
//show the boats participating.
|
||||
ArrayList<GPSCoordinate> startPositons = getSpreadStartingPositions();
|
||||
|
||||
for (int i = 0; i < startingBoats.size(); i++) {
|
||||
if (startingBoats.get(i) != null) {
|
||||
startingBoats.get(i).setCurrentLeg(legs.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prerace timer showing time until the race will begin, as a negative value
|
||||
* Countdown timer until race starts. Use PRERACE_TIME to set countdown duration.
|
||||
*/
|
||||
protected void countdownTimer() {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
@@ -129,18 +118,15 @@ public abstract class Race implements Runnable {
|
||||
long timeLoopEnded;
|
||||
|
||||
while (currentTime <= startTime) {
|
||||
if (controller != null) controller.updateMap(startingBoats);
|
||||
timeLeft = startTime - currentTime;
|
||||
if (timeLeft == 0 && controller != null) {
|
||||
updateTime("Race is starting...");
|
||||
} else {
|
||||
currentTimeInSeconds = timeLeft / 1000;
|
||||
minutes = currentTimeInSeconds / 60;
|
||||
remainingSeconds = currentTimeInSeconds % 60;
|
||||
hours = minutes / 60;
|
||||
minutes = minutes % 60;
|
||||
if (controller != null) {
|
||||
updateTime(String.format("Race clock: -%02d:%02d:%02d", hours, minutes, remainingSeconds));
|
||||
}
|
||||
currentTimeInSeconds = timeLeft / 1000;
|
||||
minutes = currentTimeInSeconds / 60;
|
||||
remainingSeconds = currentTimeInSeconds % 60;
|
||||
hours = minutes / 60;
|
||||
minutes = minutes % 60;
|
||||
if (controller != null) {
|
||||
updateTime(String.format("Time until race starts: %02d:%02d:%02d", hours, minutes, remainingSeconds));
|
||||
}
|
||||
try {
|
||||
timeLoopEnded = System.currentTimeMillis();
|
||||
@@ -153,8 +139,8 @@ public abstract class Race implements Runnable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes elapsed time in minutes and scales it, converts to hh:mm:ss format
|
||||
* @return String formatted race time, scaled
|
||||
* Takes total time elapsed and format to hour:minute:second
|
||||
* @return Formatted time as string
|
||||
*/
|
||||
protected String calcTimer() {
|
||||
long minutes;
|
||||
@@ -162,24 +148,24 @@ public abstract class Race implements Runnable {
|
||||
long remainingSeconds;
|
||||
long hours;
|
||||
|
||||
currentTimeInSeconds = totalTimeElapsed / 1000;
|
||||
long scaledTimeInSeconds = currentTimeInSeconds * scaleFactor;
|
||||
minutes = scaledTimeInSeconds / 60;
|
||||
remainingSeconds = scaledTimeInSeconds % 60;
|
||||
currentTimeInSeconds = (totalTimeElapsed / 1000) * scaleFactor;
|
||||
minutes = currentTimeInSeconds / 60;
|
||||
remainingSeconds = currentTimeInSeconds % 60;
|
||||
hours = minutes / 60;
|
||||
minutes = minutes % 60;
|
||||
return String.format("Race clock: %02d:%02d:%02d", hours, minutes, remainingSeconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the GUI race clock
|
||||
* @param time
|
||||
* Updates the calculated time to the timer label
|
||||
* @param time The calculated time from calcTimer() method
|
||||
*/
|
||||
protected void updateTime(String time) {
|
||||
protected void updateTime(String time){
|
||||
Platform.runLater(() -> {controller.setTimer(time);});
|
||||
}
|
||||
|
||||
Platform.runLater(() -> {
|
||||
controller.setTimer(time);
|
||||
});
|
||||
private void updateFPS(int fps) {
|
||||
Platform.runLater(() -> {controller.setFrames("FPS: " + fps);});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,42 +174,66 @@ public abstract class Race implements Runnable {
|
||||
*/
|
||||
private void simulateRace() {
|
||||
|
||||
long timeRaceStarted = System.currentTimeMillis();
|
||||
long timeLoopStarted;
|
||||
long timeLoopEnded;
|
||||
System.setProperty("javafx.animation.fullspeed", "true");
|
||||
|
||||
while (boatsFinished < startingBoats.size()) {
|
||||
timeLoopStarted = System.currentTimeMillis();
|
||||
totalTimeElapsed = System.currentTimeMillis() - timeRaceStarted;
|
||||
new AnimationTimer() {
|
||||
|
||||
long timeRaceStarted = System.currentTimeMillis();
|
||||
int fps = 0;
|
||||
long timeCurrent = System.currentTimeMillis();
|
||||
|
||||
for (BoatInRace boat : startingBoats) {
|
||||
if (boat != null && !boat.isFinished()) {
|
||||
updatePosition(boat, SLEEP_TIME);
|
||||
checkPosition(boat, totalTimeElapsed);
|
||||
@Override
|
||||
public void handle(long arg0) {
|
||||
|
||||
/*long timeLoopStarted;
|
||||
long timeLoopEnded;
|
||||
int fps = 0;*/
|
||||
if (controller != null) controller.updateMap(startingBoats);
|
||||
if (boatsFinished < startingBoats.size()) {
|
||||
//timeLoopStarted = System.currentTimeMillis();
|
||||
totalTimeElapsed = System.currentTimeMillis() - timeRaceStarted;
|
||||
|
||||
for (BoatInRace boat : startingBoats) {
|
||||
if (boat != null && !boat.isFinished()) {
|
||||
updatePosition(boat, SLEEP_TIME);
|
||||
checkPosition(boat, totalTimeElapsed);
|
||||
}
|
||||
}
|
||||
|
||||
//if (controller != null) controller.updateMap(startingBoats);
|
||||
if (timerEnabled)
|
||||
updateTime(calcTimer());
|
||||
}
|
||||
}
|
||||
fps++;
|
||||
if ((System.currentTimeMillis()-timeCurrent) > 1000){
|
||||
updateFPS(fps);
|
||||
fps = 0;
|
||||
timeCurrent = System.currentTimeMillis();
|
||||
}
|
||||
;
|
||||
|
||||
if (controller != null) controller.updateMap(startingBoats);
|
||||
if (timerEnabled) updateTime(calcTimer());
|
||||
try {
|
||||
timeLoopEnded = System.currentTimeMillis();
|
||||
Thread.sleep(SLEEP_TIME - (timeLoopEnded - timeLoopStarted));
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*fps++;
|
||||
try {
|
||||
timeLoopEnded = System.currentTimeMillis();
|
||||
Thread.sleep(SLEEP_TIME - (timeLoopEnded - timeLoopStarted));
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
}*/
|
||||
};
|
||||
//System.out.println("Avg fps:" + fps/(totalTimeElapsed/1000));
|
||||
}.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the position of the boat, this updates the boats current position.
|
||||
*
|
||||
* @param boat Boat that the postion is to be updated for.
|
||||
* @param boat Boat that the postion is to be updated for.
|
||||
* @param timeElapsed Time that has elapse since the start of the the race.
|
||||
* @see BoatInRace
|
||||
*/
|
||||
protected void checkPosition(BoatInRace boat, long timeElapsed) {
|
||||
if (boat.getDistanceTravelledInLeg() > boat.getCurrentLeg().getDistance()) {
|
||||
if (boat.getDistanceTravelledInLeg() > boat.getCurrentLeg().getDistance()){
|
||||
// updateController();
|
||||
//boat has passed onto new leg
|
||||
if (boat.getCurrentLeg().getName().equals("Finish")) {
|
||||
//boat has finished
|
||||
@@ -231,16 +241,13 @@ public abstract class Race implements Runnable {
|
||||
boat.setFinished(true);
|
||||
boat.setTimeFinished(timeElapsed);
|
||||
} else {
|
||||
//Calculate how much the boat overshot the marker by
|
||||
boat.setDistanceTravelledInLeg(boat.getDistanceTravelledInLeg() - boat.getCurrentLeg().getDistance());
|
||||
//Move boat on to next leg
|
||||
Leg nextLeg = legs.get(boat.getCurrentLeg().getLegNumber() + 1);
|
||||
|
||||
boat.setCurrentLeg(nextLeg);
|
||||
//Add overshoot distance into the distance travelled for the next leg
|
||||
boat.setDistanceTravelledInLeg(boat.getDistanceTravelledInLeg());
|
||||
}
|
||||
//Update the boat display table in the GUI to reflect the leg change
|
||||
FXCollections.sort(startingBoats, (a, b) -> b.getCurrentLeg().getLegNumber() - a.getCurrentLeg().getLegNumber());
|
||||
FXCollections.sort(startingBoats, (a,b) -> b.getCurrentLeg().getLegNumber() - a.getCurrentLeg().getLegNumber());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,12 +255,11 @@ public abstract class Race implements Runnable {
|
||||
* Update call for the controller.
|
||||
*/
|
||||
protected void setControllerListeners() {
|
||||
if (controller != null) controller.setInfoTable(this);
|
||||
if(controller != null) controller.setInfoTable(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boats that have started the race.
|
||||
*
|
||||
* @return ObservableList of BoatInRace class that participated in the race.
|
||||
* @see ObservableList
|
||||
* @see BoatInRace
|
||||
@@ -262,12 +268,12 @@ public abstract class Race implements Runnable {
|
||||
return startingBoats;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the boat's gps coordinates depending on time elapsed
|
||||
* @param boat
|
||||
* @param millisecondsElapsed
|
||||
* This function is a function that generates the Race and populates the events list.
|
||||
* Is automatically called by the initialiser function, so that simulateRace() does not return an empty race.
|
||||
* @see Race#simulateRace()
|
||||
*/
|
||||
|
||||
protected abstract void updatePosition(BoatInRace boat, int millisecondsElapsed);
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
package seng302.Model;
|
||||
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.transform.Rotate;
|
||||
import seng302.Constants;
|
||||
import seng302.Controllers.RaceController;
|
||||
import seng302.GPSCoordinate;
|
||||
import seng302.GraphCoordinate;
|
||||
import seng302.RaceMap;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* This creates a JavaFX Canvas that is fills it's parent.
|
||||
* Cannot be downsized.
|
||||
@@ -20,6 +27,8 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
private GraphicsContext gc;
|
||||
private RaceMap map;
|
||||
private BoatInRace[] boats;
|
||||
private RaceController controller;
|
||||
private boolean raceAnno = true;
|
||||
|
||||
/**
|
||||
* Sets the boats that are to be displayed in this race.
|
||||
@@ -30,6 +39,7 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
this.boats = boats;
|
||||
}
|
||||
|
||||
|
||||
public ResizableRaceCanvas(RaceMap map) {
|
||||
this.map = map;
|
||||
gc = this.getGraphicsContext2D();
|
||||
@@ -56,24 +66,22 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
|
||||
/**
|
||||
* Displays the mark of a race as a circle.
|
||||
*
|
||||
* @param graphCoordinate Latitude and Logintude in GraphCoordinate that it is to be displayed as.
|
||||
* @param paint Colour the mark is to be coloured.
|
||||
* @param paint Colour the mark is to be coloured.
|
||||
* @see GraphCoordinate
|
||||
* @see Color
|
||||
* @see Paint
|
||||
*/
|
||||
public void displayMark(GraphCoordinate graphCoordinate, Paint paint) {
|
||||
gc.setFill(paint);
|
||||
gc.fillOval(graphCoordinate.getX(), graphCoordinate.getY(), 15, 15);
|
||||
gc.fillOval(graphCoordinate.getX(), graphCoordinate.getY(), 25, 25);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a line on the map with rectangles on the starting and ending point of the line.
|
||||
*
|
||||
* @param graphCoordinateA Starting Point of the line in GraphCoordinate.
|
||||
* @param graphCoordinateB End Point of the line in GraphCoordinate.
|
||||
* @param paint Colour the line is to coloured.
|
||||
* @param paint Colour the line is to coloured.
|
||||
* @see GraphCoordinate
|
||||
* @see Color
|
||||
* @see Paint
|
||||
@@ -88,9 +96,8 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
|
||||
/**
|
||||
* Display a point on the Canvas
|
||||
*
|
||||
* @param graphCoordinate Coordinate that the point is to be displayed at.
|
||||
* @param paint Colour that the boat is to be coloured.
|
||||
* @param paint Colour that the boat is to be coloured.
|
||||
* @see GraphCoordinate
|
||||
* @see Paint
|
||||
* @see Color
|
||||
@@ -102,26 +109,25 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
|
||||
/**
|
||||
* Displays an arrow on the Canvas
|
||||
*
|
||||
* @param coordinate Coordinate that the arrow is to be displayed at.
|
||||
* @param angle Angle that the arrow is to be facing in degrees 0 degrees = North (Up).
|
||||
* @param angle Angle that the arrow is to be facing in degrees 0 degrees = North (Up).
|
||||
* @see GraphCoordinate
|
||||
*/
|
||||
public void displayArrow(GraphCoordinate coordinate, int angle) {
|
||||
gc.save();
|
||||
rotate(angle, coordinate.getX(), coordinate.getY());
|
||||
gc.fillPolygon(new double[]{coordinate.getX() - 12, coordinate.getX() - 6, coordinate.getX(), coordinate.getX() - 4, coordinate.getX() - 4, coordinate.getX() - 8, coordinate.getX() - 8},
|
||||
new double[]{coordinate.getY() - 5, coordinate.getY() - 20, coordinate.getY() - 5, coordinate.getY() - 5, coordinate.getY() + 20, coordinate.getY() + 20, coordinate.getY() - 5},
|
||||
rotate(angle, coordinate.getX(),coordinate.getY());
|
||||
gc.setFill(Color.BLACK);
|
||||
gc.fillPolygon(new double[]{coordinate.getX()-12, coordinate.getX()-6, coordinate.getX(), coordinate.getX()-4, coordinate.getX()-4, coordinate.getX()-8, coordinate.getX()-8},
|
||||
new double[]{coordinate.getY()-5, coordinate.getY()-20, coordinate.getY()-5, coordinate.getY()-5, coordinate.getY()+20, coordinate.getY()+20, coordinate.getY()-5},
|
||||
7);
|
||||
gc.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates things on the canvas Note: this must be called in between gc.save() and gc.restore() else they will rotate everything
|
||||
*
|
||||
* @param angle Bearing angle to rotate at in degrees
|
||||
* @param px Pivot point x of rotation.
|
||||
* @param py Pivot point y of rotation.
|
||||
* @param px Pivot point x of rotation.
|
||||
* @param py Pivot point y of rotation.
|
||||
*/
|
||||
private void rotate(double angle, double px, double py) {
|
||||
Rotate r = new Rotate(angle, px, py);
|
||||
@@ -130,14 +136,22 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
|
||||
/**
|
||||
* Display given name and speed of boat at a graph coordinate
|
||||
*
|
||||
* @param name name of the boat
|
||||
* @param speed speed of the boat
|
||||
* @param name name of the boat
|
||||
* @param speed speed of the boat
|
||||
* @param coordinate coordinate the text appears
|
||||
*/
|
||||
public void displayText(String name, double speed, GraphCoordinate coordinate) {
|
||||
String text = name + ", " + speed + " knots";
|
||||
gc.fillText(text, coordinate.getX() + 20, coordinate.getY());
|
||||
public void displayText(String name, double speed, GraphCoordinate coordinate){
|
||||
String text = String.format("%s, %2$.2f knots", name, speed);
|
||||
//System.out.println(text.length()*7);
|
||||
long xCoord = coordinate.getX()+20;
|
||||
long yCoord = coordinate.getY();
|
||||
if (xCoord+(text.length()*7) >= getWidth()){
|
||||
xCoord -= text.length()*7;
|
||||
}
|
||||
if (yCoord-(text.length()*2) <= 0){
|
||||
yCoord += 30;
|
||||
}
|
||||
gc.fillText(text, xCoord, yCoord);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,7 +165,6 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
gc.clearRect(0, 0, width, height);
|
||||
//System.out.println("Race Map Canvas Width: "+ width + ", Height:" + height);
|
||||
this.map = new RaceMap(32.278, -64.863, 32.320989, -64.821, (int) width, (int) height);
|
||||
|
||||
if (map == null) {
|
||||
return;
|
||||
}
|
||||
@@ -181,8 +194,9 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
for (BoatInRace boat : boats) {
|
||||
if (boat != null) {
|
||||
// System.out.print("Drawing Boat At: " + boat.getCurrentPosition());
|
||||
displayMark(this.map.convertGPS(boat.getCurrentPosition()), boat.getColour());
|
||||
displayText(boat.getAbbrev(), boat.getVelocity(), this.map.convertGPS(boat.getCurrentPosition()));
|
||||
displayPoint(this.map.convertGPS(boat.getCurrentPosition()), boat.getColour());
|
||||
if (raceAnno){
|
||||
displayText(boat.getAbbrev(), boat.getVelocity(), this.map.convertGPS(boat.getCurrentPosition()));}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -193,8 +207,7 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
|
||||
/**
|
||||
* Draws a boat at a certain GPSCoordinate
|
||||
*
|
||||
* @param colour Colour to colour boat.
|
||||
* @param colour Colour to colour boat.
|
||||
* @param gpsCoordinates GPScoordinate that the boat is to be drawn at.
|
||||
* @see GPSCoordinate
|
||||
* @see Color
|
||||
@@ -205,6 +218,14 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
displayPoint(graphCoordinate, colour);
|
||||
}
|
||||
|
||||
public void toggleAnno(){
|
||||
if (raceAnno){
|
||||
raceAnno = false;
|
||||
} else {
|
||||
raceAnno = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Canvas to resizable.
|
||||
*
|
||||
@@ -236,4 +257,5 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
public double prefHeight(double height) {
|
||||
return getHeight();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
package seng302;
|
||||
|
||||
import javafx.scene.paint.Color;
|
||||
import org.w3c.dom.*;
|
||||
import org.xml.sax.SAXException;
|
||||
import seng302.Model.Boat;
|
||||
import seng302.Model.BoatInRace;
|
||||
import seng302.Model.Leg;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by fwy13 on 26/03/2017.
|
||||
*/
|
||||
public class RaceXMLReader extends XMLReader{
|
||||
private ArrayList<BoatInRace> boats = new ArrayList<>();
|
||||
private Color[] colors = {Color.BLUEVIOLET, Color.BLACK, Color.RED, Color.ORANGE, Color.DARKOLIVEGREEN, Color.LIMEGREEN};//TODO make this established in xml or come up with a better system.
|
||||
private ArrayList<Leg> legs = new ArrayList<>();
|
||||
private GPSCoordinate mark, startPt1, startPt2, finishPt1, finishPt2, leewardPt1, leewardPt2, windwardPt1, windwardPt2;
|
||||
private ArrayList<GPSCoordinate> boundary = new ArrayList<>();
|
||||
|
||||
|
||||
public RaceXMLReader(String filePath) throws IOException, SAXException, ParserConfigurationException {
|
||||
this(filePath, true);
|
||||
}
|
||||
|
||||
public RaceXMLReader(String filePath, boolean read) throws IOException, SAXException, ParserConfigurationException {
|
||||
super(filePath);
|
||||
if (read) {
|
||||
read();
|
||||
}
|
||||
}
|
||||
|
||||
private void read(){
|
||||
readCourse();
|
||||
readBoats();
|
||||
readLegs();
|
||||
}
|
||||
|
||||
public void readBoats(){
|
||||
//get all boats
|
||||
NodeList nBoats = doc.getElementsByTagName("boat");
|
||||
|
||||
for (int i = 0; i < nBoats.getLength(); i++){
|
||||
String name = getTextValueOfNode((Element) nBoats.item(i), "name");
|
||||
String abbrev = getTextValueOfNode((Element) nBoats.item(i), "abbr");
|
||||
double velo = Double.parseDouble(getTextValueOfNode((Element) nBoats.item(i), "speed"));
|
||||
//System.out.println(String.format("%s, %s, %s",name, abbrev, velo));
|
||||
BoatInRace boat = new BoatInRace(name, velo, colors[i], abbrev);
|
||||
boat.setCurrentPosition(startPt1);
|
||||
boats.add(boat);
|
||||
}
|
||||
}
|
||||
|
||||
public void readLegs(){
|
||||
//get all legs
|
||||
NodeList nLegs = doc.getElementsByTagName("leg");
|
||||
|
||||
for (int i = 0; i < nLegs.getLength(); i++){
|
||||
String label = getTextValueOfNode((Element) nLegs.item(i), "name");
|
||||
NodeList start = ((Element) nLegs.item(i)).getElementsByTagName("start");
|
||||
GPSCoordinate startCoord = getCoordinates(start);
|
||||
NodeList finish = ((Element) nLegs.item(i)).getElementsByTagName("finish");
|
||||
GPSCoordinate finishCoord = getCoordinates(finish);
|
||||
//System.out.println(String.format("%s, %s, %s, %s",label, startCoord, finishCoord, i));
|
||||
legs.add(new Leg(label, startCoord, finishCoord, i));
|
||||
}
|
||||
}
|
||||
|
||||
public void readCourse(){
|
||||
NodeList nCourse = doc.getElementsByTagName("course");
|
||||
|
||||
NodeList nBounds = ((Element)nCourse.item(0)).getElementsByTagName("boundaries");
|
||||
for (int i = 0; i < nBounds.getLength(); i++){
|
||||
boundary.add(getCoordinates(nBounds, i));
|
||||
}
|
||||
|
||||
NodeList nMarks = ((Element)nCourse.item(0)).getElementsByTagName("marker");
|
||||
startPt1 = getCoordinates(nMarks, 0);
|
||||
startPt2 = getCoordinates(nMarks, 0, 1);
|
||||
mark = getCoordinates(nMarks, 1);
|
||||
windwardPt1 = getCoordinates(nMarks, 2);
|
||||
windwardPt2 = getCoordinates(nMarks, 2, 1);
|
||||
leewardPt1 = getCoordinates(nMarks, 3);
|
||||
leewardPt2 = getCoordinates(nMarks, 3, 1);
|
||||
finishPt1 = getCoordinates(nMarks, 4);
|
||||
finishPt2 = getCoordinates(nMarks, 4, 1);
|
||||
}
|
||||
|
||||
private GPSCoordinate getCoordinates(NodeList start){
|
||||
return getCoordinates(start, 0);
|
||||
}
|
||||
|
||||
private GPSCoordinate getCoordinates(NodeList start, int startIndex){
|
||||
return getCoordinates(start, startIndex, 0);
|
||||
}
|
||||
|
||||
private GPSCoordinate getCoordinates(NodeList start, int startIndex, int nodeIndex){
|
||||
NodeList nodeList = ((Element) start.item(startIndex)).getElementsByTagName("coordinate");
|
||||
Element coord = (Element) nodeList.item(nodeIndex);
|
||||
return getCoordinates(coord);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the coordinate TODO raise exception that runs when the XML is formatted wrongly.
|
||||
* @param coordNode
|
||||
* @return
|
||||
*/
|
||||
private GPSCoordinate getCoordinates(Element coordNode){
|
||||
|
||||
double startLat = Double.parseDouble(getTextValueOfNode(coordNode, "latitude"));
|
||||
double startLong = Double.parseDouble(getTextValueOfNode(coordNode, "longitude"));
|
||||
return new GPSCoordinate(startLat, startLong);
|
||||
}
|
||||
|
||||
public ArrayList<BoatInRace> getBoats() {
|
||||
return boats;
|
||||
}
|
||||
|
||||
public ArrayList<Leg> getLegs() {
|
||||
return legs;
|
||||
}
|
||||
|
||||
public GPSCoordinate getMark() {
|
||||
return mark;
|
||||
}
|
||||
|
||||
public GPSCoordinate getStartPt1() {
|
||||
return startPt1;
|
||||
}
|
||||
|
||||
public GPSCoordinate getStartPt2() {
|
||||
return startPt2;
|
||||
}
|
||||
|
||||
public GPSCoordinate getFinishPt1() {
|
||||
return finishPt1;
|
||||
}
|
||||
|
||||
public GPSCoordinate getFinishPt2() {
|
||||
return finishPt2;
|
||||
}
|
||||
|
||||
public GPSCoordinate getLeewardPt1() {
|
||||
return leewardPt1;
|
||||
}
|
||||
|
||||
public GPSCoordinate getLeewardPt2() {
|
||||
return leewardPt2;
|
||||
}
|
||||
|
||||
public GPSCoordinate getWindwardPt1() {
|
||||
return windwardPt1;
|
||||
}
|
||||
|
||||
public GPSCoordinate getWindwardPt2() {
|
||||
return windwardPt2;
|
||||
}
|
||||
|
||||
public ArrayList<GPSCoordinate> getBoundary() {
|
||||
return boundary;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package seng302;
|
||||
|
||||
import org.w3c.dom.*;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.parsers.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Created by fwy13 on 26/03/2017.
|
||||
*/
|
||||
public abstract class XMLReader {
|
||||
|
||||
protected Document doc;
|
||||
|
||||
public XMLReader(String filePath) throws ParserConfigurationException, IOException, SAXException {
|
||||
InputStream fXmlFile = getClass().getClassLoader().getResourceAsStream(filePath);
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
doc = dBuilder.parse(fXmlFile);
|
||||
doc.getDocumentElement().normalize();
|
||||
}
|
||||
|
||||
public Document getDocument(){
|
||||
return doc;
|
||||
}
|
||||
|
||||
public String getTextValueOfNode(Element n, String tagName) {
|
||||
return n.getElementsByTagName(tagName).item(0).getTextContent();
|
||||
}
|
||||
|
||||
public String getAttribute(Element n, String attr){
|
||||
return n.getAttribute(attr);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,89 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="seng302.Controllers.RaceController">
|
||||
|
||||
<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.Controllers.RaceController">
|
||||
<children>
|
||||
<GridPane fx:id="startScreen" prefHeight="600.0" prefWidth="780.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="189.0" minWidth="10.0" prefWidth="93.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="372.0" minWidth="10.0" prefWidth="184.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="394.0" minWidth="10.0" prefWidth="192.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="416.0" minWidth="10.0" prefWidth="273.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="416.0" minWidth="10.0" prefWidth="57.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="189.0" minWidth="10.0" prefWidth="93.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="372.0" minWidth="10.0" prefWidth="184.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="394.0" minWidth="10.0" prefWidth="192.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="416.0" minWidth="10.0" prefWidth="273.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="416.0" minWidth="10.0" prefWidth="57.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="241.0" minHeight="10.0" prefHeight="102.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="383.0" minHeight="10.0" prefHeight="227.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="369.0" minHeight="10.0" prefHeight="59.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="369.0" minHeight="10.0" prefHeight="38.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="178.0" minHeight="10.0" prefHeight="178.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="241.0" minHeight="10.0" prefHeight="102.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="383.0" minHeight="10.0" prefHeight="227.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="369.0" minHeight="10.0" prefHeight="59.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="369.0" minHeight="10.0" prefHeight="38.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="178.0" minHeight="10.0" prefHeight="178.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Select Your Race Scaling:" GridPane.columnIndex="1"
|
||||
GridPane.rowIndex="1">
|
||||
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Select Your Race Scaling:" GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<font>
|
||||
<Font size="23.0"/>
|
||||
<Font size="23.0" />
|
||||
</font>
|
||||
</Text>
|
||||
<Button mnemonicParsing="false" onAction="#startRace1Min" text="15x faster" GridPane.columnIndex="1"
|
||||
GridPane.rowIndex="2"/>
|
||||
<Button mnemonicParsing="false" onAction="#startRaceNoScaling" text="No scaling"
|
||||
GridPane.columnIndex="3" GridPane.rowIndex="2"/>
|
||||
<Button mnemonicParsing="false" onAction="#startRace5Min" text="3x faster" GridPane.columnIndex="2"
|
||||
GridPane.rowIndex="2"/>
|
||||
<Label alignment="CENTER" text="Race will take ~1 minute" GridPane.columnIndex="1"
|
||||
GridPane.rowIndex="3">
|
||||
<Button mnemonicParsing="false" onAction="#startRace1Min" text="15x faster" GridPane.columnIndex="1" GridPane.rowIndex="2" />
|
||||
<Button mnemonicParsing="false" onAction="#startRaceNoScaling" text="No scaling" GridPane.columnIndex="3" GridPane.rowIndex="2" />
|
||||
<Button mnemonicParsing="false" onAction="#startRace5Min" text="3x faster" GridPane.columnIndex="2" GridPane.rowIndex="2" />
|
||||
<Label alignment="CENTER" text="Race will take ~1 minute" GridPane.columnIndex="1" GridPane.rowIndex="3">
|
||||
<opaqueInsets>
|
||||
<Insets/>
|
||||
<Insets />
|
||||
</opaqueInsets>
|
||||
<font>
|
||||
<Font size="10.0"/>
|
||||
<Font size="10.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label alignment="CENTER" layoutX="99.0" layoutY="407.0" text="Race will take ~5 minutes"
|
||||
GridPane.columnIndex="2" GridPane.rowIndex="3">
|
||||
<Label alignment="CENTER" layoutX="99.0" layoutY="407.0" text="Race will take ~5 minutes" GridPane.columnIndex="2" GridPane.rowIndex="3">
|
||||
<font>
|
||||
<Font size="10.0"/>
|
||||
<Font size="10.0" />
|
||||
</font>
|
||||
<opaqueInsets>
|
||||
<Insets/>
|
||||
<Insets />
|
||||
</opaqueInsets>
|
||||
</Label>
|
||||
<Label alignment="CENTER" layoutX="279.0" layoutY="407.0" text="Race will take ~15 minutes"
|
||||
GridPane.columnIndex="3" GridPane.rowIndex="3">
|
||||
<Label alignment="CENTER" layoutX="279.0" layoutY="407.0" text="Race will take ~15 minutes" GridPane.columnIndex="3" GridPane.rowIndex="3">
|
||||
<font>
|
||||
<Font size="10.0"/>
|
||||
<Font size="10.0" />
|
||||
</font>
|
||||
<opaqueInsets>
|
||||
<Insets/>
|
||||
<Insets />
|
||||
</opaqueInsets>
|
||||
</Label>
|
||||
</children>
|
||||
</GridPane>
|
||||
<SplitPane fx:id="ongoingRacePane" dividerPositions="0.70" visible="false" AnchorPane.bottomAnchor="0.0"
|
||||
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<SplitPane fx:id="ongoingRacePane" dividerPositions="0.7" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<items>
|
||||
<AnchorPane fx:id="canvasBase" prefHeight="581.0" prefWidth="537.0">
|
||||
<children>
|
||||
<Label fx:id="timer" layoutX="45.0" layoutY="146.0" text="0:0" AnchorPane.bottomAnchor="0.0"
|
||||
AnchorPane.rightAnchor="0.0"/>
|
||||
<Label fx:id="FPS" text="FPS: 0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" />
|
||||
<Label fx:id="timer" layoutX="45.0" layoutY="146.0" text="0:0" AnchorPane.bottomAnchor="0.0" AnchorPane.rightAnchor="0.0" />
|
||||
<TitledPane fx:id="userControl" animated="false" text="User Control" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<content>
|
||||
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
|
||||
<children>
|
||||
<CheckBox fx:id="showFPS" mnemonicParsing="false" selected="true" text="Show FPS" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
<CheckBox fx:id="showAnno" mnemonicParsing="false" selected="true" text="Show Annotations" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="25.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</content>
|
||||
</TitledPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane layoutX="450.0" minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="200.0"
|
||||
GridPane.columnIndex="1">
|
||||
<AnchorPane layoutX="450.0" minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="200.0" GridPane.columnIndex="1">
|
||||
<children>
|
||||
<TableView fx:id="boatInfoTable" layoutX="-2.0" prefHeight="600.0" prefWidth="264.0"
|
||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="-2.0"
|
||||
AnchorPane.rightAnchor="-62.0" AnchorPane.topAnchor="0.0">
|
||||
<TableView fx:id="boatInfoTable" layoutX="-2.0" prefHeight="600.0" prefWidth="264.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="-2.0" AnchorPane.rightAnchor="-62.0" AnchorPane.topAnchor="0.0">
|
||||
<columns>
|
||||
<TableColumn fx:id="boatPlacingColumn" prefWidth="50.0" text="Place"/>
|
||||
<TableColumn fx:id="boatTeamColumn" prefWidth="100.0" text="Team"/>
|
||||
<TableColumn fx:id="boatMarkColumn" prefWidth="130.0" text="Mark"/>
|
||||
<TableColumn fx:id="boatSpeedColumn" prefWidth="75.0" text="Speed"/>
|
||||
<TableColumn fx:id="boatPlacingColumn" prefWidth="50.0" text="Place" />
|
||||
<TableColumn fx:id="boatTeamColumn" prefWidth="100.0" text="Team" />
|
||||
<TableColumn fx:id="boatMarkColumn" prefWidth="130.0" text="Mark" />
|
||||
<TableColumn fx:id="boatSpeedColumn" prefWidth="75.0" text="Speed" />
|
||||
</columns>
|
||||
</TableView>
|
||||
</children>
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package seng302.Model;/**
|
||||
* Created by Gondr on 26/03/2017.
|
||||
*/
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
import seng302.RaceXMLReader;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.IOException;
|
||||
|
||||
public class RaceXMLTest {
|
||||
RaceXMLReader raceXMLReader;
|
||||
|
||||
@Test
|
||||
public void canFindFile(){
|
||||
try {
|
||||
RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false);
|
||||
} catch (Exception e) {
|
||||
fail("Cannot find raceXML/bermuda_AC35.xml in the resources folder");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canReadBoats(){
|
||||
try {
|
||||
RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false);
|
||||
raceXMLReader.readBoats();
|
||||
} catch (Exception e) {
|
||||
fail("Boat Unreadable");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canReadLegs(){
|
||||
try {
|
||||
RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false);
|
||||
raceXMLReader.readLegs();
|
||||
} catch (Exception e) {
|
||||
fail("Legs Unreadable");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canReadCourse(){
|
||||
try {
|
||||
RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false);
|
||||
raceXMLReader.readCourse();
|
||||
System.out.println(raceXMLReader.getStartPt1());
|
||||
System.out.println(raceXMLReader.getStartPt2());
|
||||
System.out.println(raceXMLReader.getMark());
|
||||
System.out.println(raceXMLReader.getWindwardPt1());
|
||||
System.out.println(raceXMLReader.getWindwardPt2());
|
||||
System.out.println(raceXMLReader.getLeewardPt1());
|
||||
System.out.println(raceXMLReader.getLeewardPt2());
|
||||
System.out.println(raceXMLReader.getFinishPt1());
|
||||
System.out.println(raceXMLReader.getFinishPt2());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Course Unreadable");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user