diff --git a/doc/examples/config.json b/doc/examples/config.json index 8a3f3ac2..80c3b3e4 100644 --- a/doc/examples/config.json +++ b/doc/examples/config.json @@ -9,7 +9,7 @@ }, { "team-name": "Artemis Racing", - "velocity": 10.3 + "velocity": 59.3 }, { "team-name": "Emirates Team New Zealand", @@ -17,7 +17,7 @@ }, { "team-name": "Groupama Team France", - "velocity": 9.9 + "velocity": 29.9 }, { "team-name": "Land Rover BAR", diff --git a/doc/examples/config.xml b/doc/examples/config.xml index 05c20921..4a1b0770 100644 --- a/doc/examples/config.xml +++ b/doc/examples/config.xml @@ -3,6 +3,7 @@ AC35 6 - 2.0 + 1.0 + 135 diff --git a/doc/examples/course.xml b/doc/examples/course.xml index 49e17923..f8bfa00e 100644 --- a/doc/examples/course.xml +++ b/doc/examples/course.xml @@ -6,57 +6,57 @@ Start Start1 - 32.296038 - -64.854401 + 32.296577 + -64.854304 Start2 - 32.293834 - -64.855195 + 32.293771 + -64.855242 Mid Mark - 32.292881 - -64.843231 + 32.293039 + -64.843983 Leeward Gate Leeward Gate1 - 32.283808 - -64.850012 + 32.284680 + -64.850045 Leeward Gate2 - 32.283216 - -64.847686 + 32.280164 + -64.847591 Windward Gate Windward Gate1 - 32.309908 - -64.833665 + 32.309693 + -64.835249 Windward Gate2 - 32.309158 - -64.830834 + 32.308046 + -64.831785 Finish Finish1 - 32.318439 - -64.837367 + 32.317379 + -64.839291 Finish2 - 32.318303 - -64.834974 + 32.317257 + -64.836260 diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index db1e823e..b2dd4250 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -10,7 +10,7 @@ public class App extends Application { @Override public void start(Stage primaryStage) throws Exception { - Parent root = FXMLLoader.load(getClass().getResource("/RaceView.fxml")); + Parent root = FXMLLoader.load(getClass().getResource("/MainView.fxml")); primaryStage.setTitle("RaceVision"); primaryStage.setScene(new Scene(root)); diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index e3663035..96476e41 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -1,18 +1,18 @@ package seng302.controllers; -import javafx.animation.AnimationTimer; -import javafx.animation.KeyFrame; -import javafx.animation.KeyValue; -import javafx.animation.Timeline; +import javafx.animation.*; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; -import javafx.scene.control.TextArea; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.Pane; import javafx.scene.paint.Color; +import javafx.scene.text.Text; import javafx.util.Duration; import seng302.models.Boat; import seng302.models.Event; @@ -22,13 +22,13 @@ import seng302.models.mark.GateMark; import seng302.models.mark.Mark; import seng302.models.mark.MarkType; import seng302.models.mark.SingleMark; +import seng302.models.parsers.ConfigParser; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import static java.lang.Math.abs; - /** * Created by ptg19 on 15/03/17. * Modified by Haoming Yin (hyi25) on 20/3/2017. @@ -42,13 +42,94 @@ public class CanvasController { private Race race; private GraphicsContext gc; private HashMap timelineInfos; - private final double VIEW_CORNER_LAT = 32.280808; - private final double VIEW_CORNER_LON = -64.858401; + private AnchorPane raceResults; + private final double ORIGIN_LAT = 32.320504; + private final double ORIGIN_LON = -64.857063; + + @FXML + private AnchorPane contentAnchorPane; + @FXML + private Text windArrowText, windDirectionText; + + @FXML Pane raceTimer; + + private Animation.Status raceStatus = Animation.Status.PAUSED; + + /** + * Display the list of boats in the order they finished the race + */ + private void loadRaceResultView() { + FXMLLoader loader = new FXMLLoader(getClass().getResource("/FinishView.fxml")); + loader.setController(new RaceResultController(race)); + + try { + contentAnchorPane.getChildren().removeAll(); + contentAnchorPane.getChildren().clear(); + contentAnchorPane.getChildren().addAll((Pane) loader.load()); + + } catch (javafx.fxml.LoadException e) { + System.err.println(e.getCause()); + } catch (IOException e) { + System.err.println(e); + } + } + + /** + * Load the race timer + */ + private void loadTimerView(){ + FXMLLoader loader = new FXMLLoader(getClass().getResource("/raceTimer.fxml")); + loader.setController(new RaceTimerController(race)); + + try{ + raceTimer.getChildren().clear(); + raceTimer.getChildren().removeAll(); + raceTimer.getChildren().addAll((Pane) loader.load()); + } + catch(javafx.fxml.LoadException e){ + System.out.println(e); + } + catch(IOException e){ + System.out.println(e); + } + } + + /** + * Play each boats timeline + */ + private void playTimelines(){ + for (TimelineInfo timelineInfo : timelineInfos.values()){ + Timeline timeline = timelineInfo.getTimeline(); + + if (timeline.getStatus() == Animation.Status.PAUSED){ + timeline.play(); + } + } + raceStatus = Animation.Status.RUNNING; + } + + /** + * Pause each boats timeline + */ + private void pauseTimelines(){ + for (TimelineInfo timelineInfo : timelineInfos.values()){ + Timeline timeline = timelineInfo.getTimeline(); + + if (timeline.getStatus() == Animation.Status.RUNNING){ + timeline.pause(); + } + } + raceStatus = Animation.Status.PAUSED; + } + + /** + * Initialize the controller + */ public void initialize() { gc = canvas.getGraphicsContext2D(); - gc.scale(22, 22); + gc.scale(15, 15); RaceController raceController = new RaceController(); raceController.initializeRace(); race = raceController.getRace(); @@ -62,17 +143,53 @@ public class CanvasController { drawCourse(); drawBoats(); + // If race has started, draw the boats and play the timeline + if (race.getRaceTime() > 1){ + playTimelines(); + + } + // Race has not started, pause the timelines + else if (race.getRaceTime() < 1 || raceStatus == Animation.Status.RUNNING){ + pauseTimelines(); + } + } }; generateTimeline(); - // starts the timer and reads events from each boat's time line timer.start(); + + loadTimerView(); + + Double maxDuration = 0.0; + Timeline maxTimeline = null; + for (TimelineInfo timelineInfo : timelineInfos.values()) { + Timeline timeline = timelineInfo.getTimeline(); + System.out.println(); + + if (timeline.getTotalDuration().toMillis() >= maxDuration) { + maxDuration = timeline.getTotalDuration().toMillis(); + maxTimeline = timeline; + } + + // Timelines are paused by default timeline.play(); + timeline.pause(); + raceStatus = Animation.Status.RUNNING; } + + maxTimeline.setOnFinished(event -> { + race.setRaceFinished(); + loadRaceResultView(); + }); + + //set wind direction!!!!!!! can't find another place to put my code --haoming + double windDirection = new ConfigParser("doc/examples/config.xml").getWindDirection(); + windDirectionText.setText(String.format("%.1f°", windDirection)); + windArrowText.setRotate(windDirection); } /** @@ -97,13 +214,22 @@ public class CanvasController { // iterates all events and convert each event to keyFrame, then add them into a list for (Event event : events) { - keyFrames.add( - new KeyFrame(Duration.seconds(event.getTime() / 60 / 60 / 5), - onFinished, - new KeyValue(x, event.getThisMark().getLatitude()), - new KeyValue(y, event.getThisMark().getLongitude()) - ) - ); + if (event.getIsFinishingEvent()) { + keyFrames.add( + new KeyFrame(Duration.seconds(event.getTime() / 60 / 60 / 5), + event1 -> race.setBoatFinished(boat), + new KeyValue(x, event.getThisMark().getLatitude()), + new KeyValue(y, event.getThisMark().getLongitude()) + ) + ); + } else { + keyFrames.add( + new KeyFrame(Duration.seconds(event.getTime() / 60 / 60 / 5), + new KeyValue(x, event.getThisMark().getLatitude()), + new KeyValue(y, event.getThisMark().getLongitude()) + ) + ); + } } // uses the lists generated above to create a Timeline for the boat. @@ -121,22 +247,6 @@ public class CanvasController { } } - /** - * @return the distance between the two marks - */ - public double getDistanceBetweenMarks(Mark mark1, Mark mark2) { - double earth_radius = 6378.137; - double dLat = mark2.getLatitude() * Math.PI / 180 - mark1.getLatitude() * Math.PI / 180; - double dLon = mark2.getLongitude() * Math.PI / 180 - mark1.getLongitude() * Math.PI / 180; - - double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(mark1.getLatitude() * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2); - - double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - double d = earth_radius * c; - - return d * 1000; - } - /** * Draws a boat with given (x, y) position in the given color * @@ -146,13 +256,11 @@ public class CanvasController { */ private void drawBoat(double lat, double lon, Color color) { // Latitude - //Double x = (MAP_WIDTH / 360.0) * (180 + lon); - //Double y = (MAP_HEIGHT / 180.0) * (80 - lat); - - double x = (lat - VIEW_CORNER_LAT) * 1000; // to prevent negative longitude - double y = (lon - VIEW_CORNER_LON) * 1000; // to prevent negative latitude + double x = (lon - ORIGIN_LON) * 1000; + double y = (ORIGIN_LAT - lat) * 1000; double diameter = 0.5; + gc.setFill(color); gc.fillOval(x, y, diameter, diameter); } @@ -163,7 +271,7 @@ public class CanvasController { private void drawCourse() { for (Mark mark : race.getCourse()) { if (mark.getMarkType() == MarkType.SINGLE_MARK) { - drawSingleMark((SingleMark) mark); + drawSingleMark((SingleMark) mark, Color.BLACK); } else if (mark.getMarkType() == MarkType.GATE_MARK) { drawGateMark((GateMark) mark); } @@ -175,12 +283,12 @@ public class CanvasController { * * @param singleMark */ - private void drawSingleMark(SingleMark singleMark) { - double x = (singleMark.getLatitude() - VIEW_CORNER_LAT) * 1000; // to prevent negative longitude - double y = (singleMark.getLongitude() - VIEW_CORNER_LON) * 1000; // to prevent negative latitude + private void drawSingleMark(SingleMark singleMark, Color color) { + double x = (singleMark.getLongitude() - ORIGIN_LON) * 1000; + double y = (ORIGIN_LAT - singleMark.getLatitude()) * 1000; - gc.setFill(Color.BLACK); - gc.fillOval(x, y, 0.5, 0.5); + gc.setFill(color); + gc.fillRect(x,y,0.5,0.5); } /** @@ -189,7 +297,35 @@ public class CanvasController { * @param gateMark */ private void drawGateMark(GateMark gateMark) { - drawSingleMark(gateMark.getSingleMark1()); - drawSingleMark(gateMark.getSingleMark2()); + Color color = Color.BLUE; + + if (gateMark.getName().equals("Start")){ + color = Color.RED; + } + + if (gateMark.getName().equals("Finish")){ + color = Color.GREEN; + } + + drawSingleMark(gateMark.getSingleMark1(), color); + drawSingleMark(gateMark.getSingleMark2(), color); + + GraphicsContext gc = canvas.getGraphicsContext2D(); + + gc.setStroke(color); + + // Convert lat/lon to x,y + double x1 = (gateMark.getSingleMark1().getLongitude()- ORIGIN_LON) * 1000; + double y1 = (ORIGIN_LAT - gateMark.getSingleMark1().getLatitude()) * 1000; + + double x2 = (gateMark.getSingleMark2().getLongitude() - ORIGIN_LON) * 1000; + double y2 = (ORIGIN_LAT - gateMark.getSingleMark2().getLatitude()) * 1000; + + gc.setLineWidth(0.07); + gc.strokeLine(x1, y1, x2, y2); } -} + + public Race getRace(){ + return this.race; + } +} \ No newline at end of file diff --git a/src/main/java/seng302/controllers/Controller.java b/src/main/java/seng302/controllers/Controller.java deleted file mode 100644 index 41fb6dc2..00000000 --- a/src/main/java/seng302/controllers/Controller.java +++ /dev/null @@ -1,18 +0,0 @@ -package seng302.controllers; - -import javafx.fxml.FXML; -import javafx.scene.Parent; -import javafx.scene.layout.AnchorPane; - -/** - * Created by ptg19 on 20/03/17. - */ -public class Controller { - @FXML private AnchorPane window; - @FXML private Parent raceView; - @FXML private RaceController raceViewController; - - //^ this is automatic fxml linking based off http://blog.buildpath.de/fxml-composition-how-to-get-the-controller-of-an-included-fxml-view-nested-controllers/ - // From googling it's probably better to just add a child however you did that in your 301 michael, it kinda depends on how we are going to - // make an event for changing the screen. -} diff --git a/src/main/java/seng302/controllers/MasterViewController.java b/src/main/java/seng302/controllers/MasterViewController.java new file mode 100644 index 00000000..72de0419 --- /dev/null +++ b/src/main/java/seng302/controllers/MasterViewController.java @@ -0,0 +1,38 @@ +package seng302.controllers; + +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.fxml.Initializable; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.Pane; + +import java.io.IOException; +import java.net.URL; +import java.util.ResourceBundle; + +/** + * Created by michaelrausch on 21/03/17. + */ +public class MasterViewController implements Initializable { + @FXML + private AnchorPane contentPane; + + private void setContentPane(String jfxUrl){ + try{ + contentPane.getChildren().removeAll(); + contentPane.getChildren().clear(); + contentPane.getChildren().addAll((Pane) FXMLLoader.load(getClass().getResource(jfxUrl))); + } + catch(javafx.fxml.LoadException e){ + System.err.println(e.getCause()); + } + catch(IOException e){ + System.err.println(e); + } + } + + @Override + public void initialize(URL location, ResourceBundle resources) { + setContentPane("/RaceView.fxml"); + } +} diff --git a/src/main/java/seng302/controllers/RaceController.java b/src/main/java/seng302/controllers/RaceController.java index 11f3a318..e8471426 100644 --- a/src/main/java/seng302/controllers/RaceController.java +++ b/src/main/java/seng302/controllers/RaceController.java @@ -2,9 +2,8 @@ package seng302.controllers; import seng302.models.Boat; import seng302.models.OldFileParser; -import seng302.models.parsers.*; -import seng302.models.mark.*; import seng302.models.Race; +import seng302.models.parsers.CourseParser; import java.io.FileNotFoundException; import java.lang.reflect.Array; @@ -20,6 +19,7 @@ import java.util.Random; */ public class RaceController { Race race = null; + public void initializeRace() { String raceConfigFile; raceConfigFile = "doc/examples/config.json"; @@ -55,13 +55,18 @@ public class RaceController { //get race size int numberOfBoats = (int) fp.getRaceSize(); + int boatsAdded = 0; //get time scale double timeScale = fp.getTimeScale(); race.setTimeScale(timeScale); for (Map team : teams) { - boatNames.add((String) team.get("team-name")); + if (boatsAdded < numberOfBoats){ + boatNames.add((String) team.get("team-name")); + race.addBoat(new Boat(team.get("team-name").toString(), (Double) (team.get("velocity")))); + } + boatsAdded++; } // Shuffle team names @@ -72,11 +77,6 @@ public class RaceController { return null; } - // Add boats to the race - for (int i = 0; i < numberOfBoats; i++) { - race.addBoat(new Boat(boatNames.get(i), (Double) (teams.get(i).get("velocity")))); - } - CourseParser cp = new CourseParser("doc/examples/course.xml"); race.addCourse(cp.getCourse()); diff --git a/src/main/java/seng302/controllers/RaceResultController.java b/src/main/java/seng302/controllers/RaceResultController.java new file mode 100644 index 00000000..7378fa68 --- /dev/null +++ b/src/main/java/seng302/controllers/RaceResultController.java @@ -0,0 +1,37 @@ +package seng302.controllers; + +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.VBox; +import javafx.scene.text.Text; +import seng302.models.Race; + +import java.net.URL; +import java.util.ResourceBundle; + +/** + * Created by ptg19 on 20/03/17. + */ +public class RaceResultController implements Initializable{ + @FXML private AnchorPane window; + @FXML private VBox resultsVBox; + private Race race; + + RaceResultController(Race race){ + this.race = race; + } + + @Override + public void initialize(URL location, ResourceBundle resources) { + int boatPosition = this.race.getFinishedBoats().length; + + for (int i = this.race.getFinishedBoats().length - 1; i >= 0; i--){ + resultsVBox.getChildren().add(0, new Text(boatPosition + ": " + this.race.getFinishedBoats()[i].getTeamName())); + boatPosition--; + } + + + + } +} diff --git a/src/main/java/seng302/controllers/RaceTimerController.java b/src/main/java/seng302/controllers/RaceTimerController.java new file mode 100644 index 00000000..9c1d1130 --- /dev/null +++ b/src/main/java/seng302/controllers/RaceTimerController.java @@ -0,0 +1,78 @@ +package seng302.controllers; + +import javafx.animation.KeyFrame; +import javafx.animation.Timeline; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.text.Text; +import javafx.util.Duration; +import seng302.models.Race; + +import java.net.URL; +import java.util.ResourceBundle; + +public class RaceTimerController implements Initializable{ + private Timeline timeline; + private Race race; + + @FXML + private Text timerLabel; + + /** + * Convert seconds to a string of the format mm:ss + * @param time the time in seconds + * @return a formatted string + */ + public String convertTimeToMinutesSeconds(int time){ + if (time < 0){ + return String.format("-%02d:%02d", (time * -1) / 60, (time * -1)% 60); + } + return String.format("%02d:%02d", time / 60, time % 60); + } + + /** + * Controller to control the race timer + * @param race the race the timer is timing + */ + public RaceTimerController(Race race){ + this.race = race; + } + + @Override + public void initialize(URL location, ResourceBundle resources) { + timeline = new Timeline(); + timeline.setCycleCount(Timeline.INDEFINITE); + + // Run timer update every second + timeline.getKeyFrames().add( + new KeyFrame(Duration.seconds(1), + event -> { + // Stop timer if race is finished + if (this.race.isRaceFinished()){ + this.timeline.stop(); + } + else{ + timerLabel.setText(convertTimeToMinutesSeconds(race.getRaceTime())); + this.race.incrementRaceTime(); + } + }) + ); + + // Start the timer + timeline.playFromStart(); + } + + /** + * Stop the race timer + */ + public void stop(){ + timeline.stop(); + } + + /** + * Start the race timer + */ + public void start(){ + timeline.play(); + } +} diff --git a/src/main/java/seng302/models/Event.java b/src/main/java/seng302/models/Event.java index 51eb814c..00a2b8bd 100644 --- a/src/main/java/seng302/models/Event.java +++ b/src/main/java/seng302/models/Event.java @@ -1,7 +1,6 @@ package seng302.models; import seng302.models.mark.Mark; -import seng302.models.mark.SingleMark; import java.text.SimpleDateFormat; import java.util.Date; @@ -40,7 +39,7 @@ public class Event { * @param eventTime, what time the event happens * @param eventBoat, the boat that the event belongs to */ - public Event(Double eventTime, Boat eventBoat, SingleMark mark1) { + public Event(Double eventTime, Boat eventBoat, Mark mark1) { this.time = eventTime; this.boat = eventBoat; this.mark1 = mark1; diff --git a/src/main/java/seng302/models/Race.java b/src/main/java/seng302/models/Race.java index ab036664..2ad111e8 100644 --- a/src/main/java/seng302/models/Race.java +++ b/src/main/java/seng302/models/Race.java @@ -15,6 +15,8 @@ public class Race { private List course; // Marks in the race private long startTime = 0; private double timeScale = 1; + private boolean raceFinished = false; // Race is finished + private int raceTime = -10; // Current time in the race /** * Race class containing the boats and legs in the race @@ -104,7 +106,7 @@ public class Race { // There are no more marks after this event else{ - Event event = new Event(time, boat, course.get(i), course.get(i)); + Event event = new Event(time, boat, course.get(i)); events.get(boat).add(event); } } @@ -121,15 +123,74 @@ public class Race { generateEvents(); } + /** + * Set the race course + * @param course a list of marks in the course + */ public void addCourse(List course) { this.course = course; } + /** + * Get a list of marks in the course + * @return + */ public List getCourse() { return course; } + /** + * Get a map of the events in the race + * @return + */ public HashMap getEvents() { return events; } + + /** + * Set a boat as finished + * @param boat The boat that has finished the race + */ + public void setBoatFinished(Boat boat){ + System.out.println(boat.getTeamName() + " finished"); + this.finishingOrder.add(boat); + } + + /** + * Set the race as finished + */ + public void setRaceFinished(){ + this.raceFinished = true; + } + + /** + * Return whether or not the race is finished + * @return true if the race is finished + */ + public boolean isRaceFinished(){ + return this.raceFinished; + } + + /** + * Set the race time + * @param raceTime the race time in seconds + */ + public void setRaceTime(int raceTime){ + this.raceTime = raceTime; + } + + /** + * Return the race time + * @return the race time in seconds + */ + public int getRaceTime(){ + return this.raceTime; + } + + /** + * Increment the race time by one second + */ + public void incrementRaceTime(){ + this.raceTime ++; + } } \ No newline at end of file diff --git a/src/main/java/seng302/models/mark/GateMark.java b/src/main/java/seng302/models/mark/GateMark.java index 208d2416..edf4f4ec 100644 --- a/src/main/java/seng302/models/mark/GateMark.java +++ b/src/main/java/seng302/models/mark/GateMark.java @@ -37,4 +37,12 @@ public class GateMark extends Mark { public void setSingleMark2(SingleMark singleMark2) { this.singleMark2 = singleMark2; } + + public double getLatitude(){ + return (this.getSingleMark1().getLatitude() + this.getSingleMark2().getLatitude()) / 2; + } + + public double getLongitude(){ + return (this.getSingleMark1().getLongitude() + this.getSingleMark2().getLongitude()) / 2; + } } diff --git a/src/main/java/seng302/models/parsers/ConfigParser.java b/src/main/java/seng302/models/parsers/ConfigParser.java new file mode 100644 index 00000000..74d0986a --- /dev/null +++ b/src/main/java/seng302/models/parsers/ConfigParser.java @@ -0,0 +1,80 @@ +package seng302.models.parsers; + + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import java.util.DoubleSummaryStatistics; + +public class ConfigParser extends FileParser { + + private Document doc; + + public ConfigParser(String path) { + super(path); + this.doc = this.parseFile(); + } + + /** + * Gets wind direction from config file. + * + * @return a double type degree, or 0 if no value or invalid value is found + */ + public double getWindDirection() { + return getDoubleByTagName("wind-direction", 0.0); + } + + /** + * Gets a non negative time scale for the race + * + * @return a double type scale, or 0 if no scale or invalid scale is found + */ + public double getTimeScale() { + return getDoubleByTagName("time-scale", 1.0); + } + + /** + * Gets a double type number by given tag name found in xml file + * + * @param tagName a string of tag name + * @param defaultVal value returned if no value or invalid value is found + * @return value found + */ + public double getDoubleByTagName(String tagName, double defaultVal) { + double val = defaultVal; + try { + Node node = this.doc.getElementsByTagName(tagName).item(0); + if (node.getNodeType() == Node.ELEMENT_NODE) { + Element element = (Element) node; + val = Double.valueOf(element.getTextContent()); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + return val; + } + } + + /** + * Gets a string by given tag name found in xml file + * + * @param tagName a string of tag name + * @param defaultVal a string returned if no value or invalid value is found + * @return string found + */ + public String getStringByTagName(String tagName, String defaultVal) { + String string = defaultVal; + try { + Node node = this.doc.getElementsByTagName(tagName).item(0); + if (node.getNodeType() == Node.ELEMENT_NODE) { + Element element = (Element) node; + string = element.getTextContent(); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + return string; + } + } +} diff --git a/src/main/resources/FinishView.fxml b/src/main/resources/FinishView.fxml index 3e743bab..debdea26 100644 --- a/src/main/resources/FinishView.fxml +++ b/src/main/resources/FinishView.fxml @@ -1,37 +1,53 @@ + - - + - - + + - - - + + + + - + + + + - - + + + + + + + + + + + + + + diff --git a/src/main/resources/MainView.fxml b/src/main/resources/MainView.fxml index e69d850e..9c1ea80f 100644 --- a/src/main/resources/MainView.fxml +++ b/src/main/resources/MainView.fxml @@ -4,9 +4,8 @@ - - + - + diff --git a/src/main/resources/RaceView.fxml b/src/main/resources/RaceView.fxml index 1ac0d054..c56e4edb 100644 --- a/src/main/resources/RaceView.fxml +++ b/src/main/resources/RaceView.fxml @@ -1,5 +1,7 @@ + + @@ -9,26 +11,34 @@ - - - - -