From d39aacba830ca64c023dc61edf6181112d8bd5b1 Mon Sep 17 00:00:00 2001 From: zyt10 Date: Fri, 24 Mar 2017 11:34:34 +1300 Subject: [PATCH 1/4] RaceController now uses new parsers & deleted OldApp and OldFileParser #story[377] --- doc/examples/teams.xml | 12 +- src/main/java/seng302/App.java | 3 - .../seng302/controllers/RaceController.java | 45 +++--- src/main/java/seng302/models/OldApp.java | 105 -------------- .../java/seng302/models/OldFileParser.java | 132 ------------------ src/test/java/seng302/OldFileParserTest.java | 53 ------- 6 files changed, 24 insertions(+), 326 deletions(-) delete mode 100644 src/main/java/seng302/models/OldApp.java delete mode 100644 src/main/java/seng302/models/OldFileParser.java delete mode 100644 src/test/java/seng302/OldFileParserTest.java diff --git a/doc/examples/teams.xml b/doc/examples/teams.xml index 21908ccf..ed8cfcf1 100644 --- a/doc/examples/teams.xml +++ b/doc/examples/teams.xml @@ -4,31 +4,31 @@ Oracle Team USA USA - 10.0 + 30.9 Artemis Racing ART - 10.0 + 59.3 Emirates Team New Zealand NZL - 10.0 + 51.5 Land Rover BAR BAR - 10.0 + 29.9 SoftBank Team Japan JAP - 10.0 + 99.6 Groupama Team France FRC - 10 + 45.6 \ No newline at end of file diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index b2dd4250..b88f607b 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -14,9 +14,6 @@ public class App extends Application primaryStage.setTitle("RaceVision"); primaryStage.setScene(new Scene(root)); -// seng302.models.OldApp.main(); // Run this to show how positions are updated -// seng302.controllers.RaceController.initializeRace(); - primaryStage.show(); } diff --git a/src/main/java/seng302/controllers/RaceController.java b/src/main/java/seng302/controllers/RaceController.java index e8471426..ae1bfb1e 100644 --- a/src/main/java/seng302/controllers/RaceController.java +++ b/src/main/java/seng302/controllers/RaceController.java @@ -1,15 +1,14 @@ package seng302.controllers; import seng302.models.Boat; -import seng302.models.OldFileParser; import seng302.models.Race; +import seng302.models.parsers.ConfigParser; import seng302.models.parsers.CourseParser; +import seng302.models.parsers.TeamsParser; -import java.io.FileNotFoundException; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collections; -import java.util.Map; import java.util.Random; /** @@ -21,11 +20,11 @@ public class RaceController { Race race = null; public void initializeRace() { - String raceConfigFile; - raceConfigFile = "doc/examples/config.json"; + String raceConfigFile = "doc/examples/config.xml"; + String teamsConfigFile = "doc/examples/teams.xml"; try { - race = createRace(raceConfigFile); + race = createRace(raceConfigFile, teamsConfigFile); } catch (Exception e) { System.out.println("There was an error creating the race."); } @@ -37,36 +36,28 @@ public class RaceController { } } - public Race createRace(String configFile) throws Exception { + public Race createRace(String configFile, String teamsConfigFile) throws Exception { Race race = new Race(); - OldFileParser fp; // Read team names from file - try{ - fp = new OldFileParser(configFile); - } - catch (FileNotFoundException e){ - System.out.println("Config file does not exist"); - return null; - } + TeamsParser tp = new TeamsParser(teamsConfigFile); + + // Read course from file + ConfigParser config = new ConfigParser(configFile); ArrayList boatNames = new ArrayList<>(); - ArrayList> teams = fp.getTeams(); + ArrayList teams = tp.getBoats(); //get race size - int numberOfBoats = (int) fp.getRaceSize(); - int boatsAdded = 0; + int numberOfBoats = teams.size(); //get time scale - double timeScale = fp.getTimeScale(); + double timeScale = config.getTimeScale(); race.setTimeScale(timeScale); - for (Map team : teams) { - if (boatsAdded < numberOfBoats){ - boatNames.add((String) team.get("team-name")); - race.addBoat(new Boat(team.get("team-name").toString(), (Double) (team.get("velocity")))); - } - boatsAdded++; + for (Boat boat : teams) { + boatNames.add(boat.getTeamName()); + race.addBoat(boat); } // Shuffle team names @@ -77,8 +68,8 @@ public class RaceController { return null; } - CourseParser cp = new CourseParser("doc/examples/course.xml"); - race.addCourse(cp.getCourse()); + CourseParser course = new CourseParser("doc/examples/course.xml"); + race.addCourse(course.getCourse()); return race; } diff --git a/src/main/java/seng302/models/OldApp.java b/src/main/java/seng302/models/OldApp.java deleted file mode 100644 index aed658be..00000000 --- a/src/main/java/seng302/models/OldApp.java +++ /dev/null @@ -1,105 +0,0 @@ -package seng302.models; - -import seng302.models.mark.SingleMark; - -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Map; -import java.util.Random; -import java.io.FileNotFoundException; - -public class OldApp { - - /** - * Builds a race object for the AC35 course - * - * @return a Race object for the AC35 course - */ - public static Race createRace(String configFile) throws Exception { - Race race = new Race(); - OldFileParser fp; - - // Read team names from file - try{ - fp = new OldFileParser(configFile); - } - catch (FileNotFoundException e){ - System.out.println("Config file does not exist"); - return null; - } - - ArrayList boatNames = new ArrayList<>(); - ArrayList> teams = fp.getTeams(); - - //get race size - int numberOfBoats = (int) fp.getRaceSize(); - - //get time scale - double timeScale = fp.getTimeScale(); - race.setTimeScale(timeScale); - - for (Map team : teams) { - boatNames.add((String) team.get("team-name")); - } - - // Shuffle team names - long seed = System.nanoTime(); - Collections.shuffle(boatNames, new Random(seed)); - - if (numberOfBoats > Array.getLength(boatNames.toArray())) { - 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")))); - } - - // Add marks to race in order -// race.addMark(new SingleMark("Start", 32.296038,-64.854401 )); -// race.addMark(new SingleMark("Mid SingleMark", 32.292881,-64.843231 )); -// race.addMark(new SingleMark("Leeward Gate", 32.283808,-64.850012 )); -// race.addMark(new SingleMark("Windward Gate", 32.309908,-64.833665 )); -// race.addMark(new SingleMark("Finish", 32.318439,-64.837367 )); - - return race; - } - - public static void main() { - Race race = null; - String raceConfigFile; - - raceConfigFile = "doc/examples/config.json"; - - - try { - race = createRace(raceConfigFile); - } catch (Exception e) { - System.out.println("There was an error creating the race."); - } - - // If race was created - if (race != null) { - //race.displayStartingBoats(); - - System.out.println("\n\n"); - System.out.println("######################"); - System.out.println("# Live Race Updates "); - System.out.println("######################"); - - race.startRace(); - - System.out.println("\n\n"); - System.out.println("######################"); - System.out.println("# Race Results "); - System.out.println("######################"); - - //race.showRaceMarkerResults(); - //race.displayFinishingOrder(); - - } else { - System.out.println("There was an error creating the race. Exiting."); - } - } -} \ No newline at end of file diff --git a/src/main/java/seng302/models/OldFileParser.java b/src/main/java/seng302/models/OldFileParser.java deleted file mode 100644 index e9447b8e..00000000 --- a/src/main/java/seng302/models/OldFileParser.java +++ /dev/null @@ -1,132 +0,0 @@ -package seng302.models; - -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; - -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Map; - - -/** - * Read team name from a given Json file. So that user can extract information - * efficiently from external files. - */ - -public class OldFileParser { - - private String filePath; - private JSONObject content; - - /** - * used to construct an instance of file parser - * - * @param filePath a string like path to show location of desired file to - * be parsed - */ - public OldFileParser(String filePath) throws Exception { - this.filePath = filePath; - this.readFile(); - } - - /** - * Reads content from a given file, and return the content as JSONObject. - * Throws FileNotFoundException, if the given file cannot be found. - */ - private void readFile() throws FileNotFoundException { - JSONParser parser = new JSONParser(); - try { - this.content = (JSONObject) parser.parse(new FileReader(filePath)); - - } catch (FileNotFoundException e) { - throw e; - } catch (IOException e) { - e.printStackTrace(); - } catch (ParseException e) { - e.printStackTrace(); - } - } - - /** - * Gets time scale setting parameter. - * - * @return long time scale. -1 if parameter is invalid (eg. scale is - * negative number, or containing non numeric character) or cannot be found. - */ - @SuppressWarnings("unchecked") - public double getTimeScale() { - try { - double timeScale = (double) this.content.get("time-scale"); - return timeScale >= 0 ? timeScale : -1; - } catch (Exception e) { - e.printStackTrace(); - return 1; - } - } - - /** - * Gets race name in the setting file. - * - * @return a string of race name. null if race name is invalid or cannot - * be found. - */ - @SuppressWarnings("unchecked") - public String getRaceName() { - try { - return (String) this.content.get("race-name"); - } catch (Exception e) { - return null; - } - } - - /** - * Gets an array of teams who participate the race. - * - * @return an ArrayList containing strings of team names. null if teams - * setting is invalid or there is no team. - */ - @SuppressWarnings("unchecked") - public ArrayList> getTeams() { - try { - return (ArrayList>) this.content.get("teams"); - } catch (Exception e) { - return null; - } - } - - /** - * Gets the total number of teams. - * - * @return the number of teams. 0 if no teams or anything goes wrong. - */ - @SuppressWarnings("unchecked") - public long getTotalNumberOfTeams() { - ArrayList> teams = getTeams(); - try { - return teams.size(); - } catch (Exception e) { - return 0; - } - } - - /** - * Gets the number of boats that would compete during a race. Returns the - * total number of race size if parameter is invalid or cannot be found. - * - * @return an int of the race size. - */ - @SuppressWarnings("unchecked") - public long getRaceSize() { - long totalTeams = this.getTotalNumberOfTeams(); - try { - long raceSize = (long) this.content.get("race-size"); - return raceSize >= 0 && raceSize <= totalTeams ? raceSize : totalTeams; - } catch (Exception e) { - e.printStackTrace(); - return totalTeams; - } - } -} \ No newline at end of file diff --git a/src/test/java/seng302/OldFileParserTest.java b/src/test/java/seng302/OldFileParserTest.java deleted file mode 100644 index fa919106..00000000 --- a/src/test/java/seng302/OldFileParserTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package seng302; - -import org.junit.Test; -import seng302.models.OldFileParser; - -import java.io.FileNotFoundException; - -import static org.junit.Assert.assertEquals; - -/** - * Unit test for FileParser class - * Created by Haoming on 5/03/17. - */ -public class OldFileParserTest { - - /** - * test if it fails from reading non existed file - */ - @Test(expected = FileNotFoundException.class) - public void readNonExistedFile() throws Exception { - OldFileParser fileParser = new OldFileParser("test/java/seng302/non-existed.json"); - } - - /** - * test a valid json file with valid content. - */ - @Test - public void readValidFile() throws Exception { - OldFileParser fileParser = new OldFileParser("src/test/java/seng302/valid.json"); - - assertEquals("AC35", fileParser.getRaceName()); - - assertEquals("Oracle Team USA", fileParser.getTeams().get(0).get("team-name")); - assertEquals(20.9, fileParser.getTeams().get(0).get("velocity")); - assertEquals(2, fileParser.getRaceSize()); - assertEquals(6, fileParser.getTotalNumberOfTeams()); - } - - /** - * test an invalid json file within wrong type value and misnamed - * variable name. - */ - @Test - public void readInvalidFile() throws Exception { - OldFileParser fileParser = new OldFileParser("src/test/java/seng302/invalid.json"); - - assertEquals(null, fileParser.getRaceName()); - assertEquals(null, fileParser.getTeams()); - //assertEquals(-1, fileParser.getTimeScale()); - assertEquals(null, fileParser.getTeams()); - } - -} \ No newline at end of file From 50ab481b18b20a3b094540ccf5ea2f72f5dbd587 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 24 Mar 2017 11:51:07 +1300 Subject: [PATCH 2/4] added knots beside boat name #story[447] --- src/main/java/seng302/controllers/BoatPositionController.java | 2 +- src/main/java/seng302/controllers/CanvasController.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seng302/controllers/BoatPositionController.java b/src/main/java/seng302/controllers/BoatPositionController.java index 4a82e28a..4e95ae81 100644 --- a/src/main/java/seng302/controllers/BoatPositionController.java +++ b/src/main/java/seng302/controllers/BoatPositionController.java @@ -39,7 +39,7 @@ public class BoatPositionController { positionVbox.getChildren().removeAll(); for (Boat boat: boatOrder){ - positionVbox.getChildren().add(new Text(boat.getTeamName() + " " + boat.getVelocity())); + positionVbox.getChildren().add(new Text(boat.getTeamName() + " " + boat.getSpeedInKnots() + " Knots")); } } diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index 63126939..e1d81cef 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -271,7 +271,7 @@ public class CanvasController { gc.setFill(color); gc.setLineWidth(3); gc.setFontSmoothingType(FontSmoothingType.GRAY); - gc.fillText(name + ", " + speed + " knots",x+15,y+15); + gc.fillText(name + ", " + speed + " knots", x+15, y+15); gc.fillOval(x, y, diameter, diameter); } From e8b1720fee7e30d03c4d1ef4755e35036d06f0ee Mon Sep 17 00:00:00 2001 From: zyt10 Date: Fri, 24 Mar 2017 12:15:39 +1300 Subject: [PATCH 3/4] Created a toggle checkbox to show and hide all annotation #story[477] --- .../seng302/controllers/CanvasController.java | 179 ++++++++++-------- src/main/resources/RaceView.fxml | 4 +- 2 files changed, 99 insertions(+), 84 deletions(-) diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index 15b69ae3..a491d8da 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -3,10 +3,13 @@ package seng302.controllers; import javafx.animation.*; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; +import javafx.scene.control.CheckBox; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; @@ -36,6 +39,16 @@ import java.util.List; public class CanvasController { @FXML private Canvas canvas; + @FXML + private AnchorPane contentAnchorPane; + @FXML + private Text windArrowText, windDirectionText; + @FXML + private Pane raceTimer; + @FXML + private BoatPositionController teamPositionsController; + @FXML + private CheckBox toggleAnnotation; private Race race; private GraphicsContext gc; @@ -46,86 +59,11 @@ public class CanvasController { 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; - - @FXML - BoatPositionController teamPositionsController; - private Animation.Status raceStatus = Animation.Status.PAUSED; private final int SCALE = 16000; - /** - * 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; - } + private boolean annotationCheck = true; /** * Initialize the controller @@ -196,12 +134,86 @@ public class CanvasController { loadRaceResultView(); }); + toggleAnnotation.selectedProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) { + annotationCheck = !annotationCheck; + } + }); + //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); } + /** + * 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; + } + /** * Generates time line for each boat, and stores time time into timelineInfos hash map */ @@ -258,6 +270,8 @@ public class CanvasController { * @param lat * @param lon * @param color + * @param name + * @param speed */ private void drawBoat(double lat, double lon, Color color, String name, double speed) { // Latitude @@ -266,12 +280,15 @@ public class CanvasController { double diameter = 9; - // Set boat text - gc.setFont(new Font(14)); gc.setFill(color); - gc.setLineWidth(3); - gc.setFontSmoothingType(FontSmoothingType.GRAY); - gc.fillText(name + ", " + speed + " knots", x+15, y+15); + + if (annotationCheck) { + // Set boat text + gc.setFont(new Font(14)); + gc.setLineWidth(3); + gc.setFontSmoothingType(FontSmoothingType.GRAY); + gc.fillText(name + ", " + speed + " knots", x + 15, y + 15); + } gc.fillOval(x, y, diameter, diameter); } diff --git a/src/main/resources/RaceView.fxml b/src/main/resources/RaceView.fxml index 9534d08d..9c8b7add 100644 --- a/src/main/resources/RaceView.fxml +++ b/src/main/resources/RaceView.fxml @@ -25,12 +25,9 @@