From 044d786043d6fff89a1b21e41aaa4b4b51675319 Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Fri, 19 May 2017 01:00:05 +1200 Subject: [PATCH 1/8] Added Refactors that the Audit suggested - Created AC35RaceStatus class - Deleted wait loop into a Thread.sleep() - Deleted Entirely commented out class.... - Deleted duplicate draw that appeared again #story[873] --- .../src/main/java/seng302/AC35RaceStatus.java | 170 +++++++++++++ .../seng302/Model/ConstantVelocityRace.java | 208 ---------------- .../seng302/Model/ResizableRaceCanvas.java | 1 - .../main/java/seng302/VisualiserInput.java | 235 +++--------------- 4 files changed, 210 insertions(+), 404 deletions(-) create mode 100644 visualiser/src/main/java/seng302/AC35RaceStatus.java delete mode 100644 visualiser/src/main/java/seng302/Model/ConstantVelocityRace.java diff --git a/visualiser/src/main/java/seng302/AC35RaceStatus.java b/visualiser/src/main/java/seng302/AC35RaceStatus.java new file mode 100644 index 00000000..3b915c19 --- /dev/null +++ b/visualiser/src/main/java/seng302/AC35RaceStatus.java @@ -0,0 +1,170 @@ +package seng302; + +import javafx.application.Platform; +import org.xml.sax.SAXException; +import seng302.Mock.BoatXMLReader; +import seng302.Mock.RegattaXMLReader; +import seng302.Mock.StreamedCourseXMLException; +import seng302.Mock.StreamedCourseXMLReader; +import seng302.Networking.Messages.*; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by Gondr on 18/05/2017. + */ +public class AC35RaceStatus { + private final VisualiserInput visualiserInput; + protected AverageWind averageWind; + protected final Map boatLocation = new HashMap<>(); + protected final Map boatStatusMap = new HashMap<>(); + protected final Map markRoundingMap = new HashMap<>(); + protected CourseWinds courseWinds; + protected RaceMessage raceMessage; + protected RaceStartStatus raceStartStatus; + protected RaceStatus raceStatus; + + public AC35RaceStatus(VisualiserInput visualiserInput){ + this.visualiserInput = visualiserInput; + averageWind = null; + courseWinds = null; + raceMessage = null; + raceStartStatus = null; + raceStatus = null; + } + + public void update(AC35Data message){ + //Checks which message is being received and does what is needed for that message. + //Heartbeat. + switch(message.getType()) { + case HEARTBEAT: + Heartbeat heartbeat = (Heartbeat) message; + + //Check that the heartbeat number is greater than the previous value, and then set the last heartbeat time. + if (heartbeat.getSequenceNumber() > visualiserInput.getLastHeartbeatSequenceNum()) { + visualiserInput.setLastHeartbeatTime(System.currentTimeMillis()); + visualiserInput.setLastHeartbeatSequenceNum(heartbeat.getSequenceNumber()); + //System.out.println("HeartBeat Message! " + lastHeartbeatSequenceNum); + } + break; + case RACESTATUS: + RaceStatus raceStatus = (RaceStatus) message; + + //System.out.println("Race Status Message"); + this.raceStatus = raceStatus; + for (BoatStatus boatStatus : this.raceStatus.getBoatStatuses()) { + this.boatStatusMap.put(boatStatus.getSourceID(), boatStatus); + } + visualiserInput.setCourseWindDirection(raceStatus.getScaledWindDirection() + 180); + break; + case DISPLAYTEXTMESSAGE: + //System.out.println("Display Text Message"); + //No decoder for this. + break; + case XMLMESSAGE: + XMLMessage xmlMessage = (XMLMessage) message; + + //System.out.println("XML Message!"); + + Platform.runLater(() -> { + if (xmlMessage.getXmlMsgSubType() == XMLMessage.XMLTypeRegatta) { + //System.out.println("Setting Regatta"); + try { + visualiserInput.getCourse().setRegattaXMLReader(new RegattaXMLReader(xmlMessage.getXmlMessage())); + + } + //TODO REFACTOR should put all of these exceptions behind a RegattaXMLReaderException. + catch (IOException | SAXException | ParserConfigurationException e) { + System.err.println("Error creating RegattaXMLReader: " + e.getMessage()); + //Continue to the next loop iteration/message. + } + + } else if (xmlMessage.getXmlMsgSubType() == XMLMessage.XMLTypeRace) { + //System.out.println("Setting Course"); + try { + visualiserInput.getCourse().setStreamedCourseXMLReader(new StreamedCourseXMLReader(xmlMessage.getXmlMessage())); + } + //TODO REFACTOR should put all of these exceptions behind a StreamedCourseXMLReaderException. + catch (IOException | SAXException | ParserConfigurationException | StreamedCourseXMLException e) { + System.err.println("Error creating StreamedCourseXMLReader: " + e.getMessage()); + //Continue to the next loop iteration/message. + } + + } else if (xmlMessage.getXmlMsgSubType() == XMLMessage.XMLTypeBoat) { + //System.out.println("Setting Boats"); + try { + visualiserInput.getCourse().setBoatXMLReader(new BoatXMLReader(xmlMessage.getXmlMessage())); + } + //TODO REFACTOR should put all of these exceptions behind a BoatXMLReaderException. + catch (IOException | SAXException | ParserConfigurationException e) { + System.err.println("Error creating BoatXMLReader: " + e.getMessage()); + //Continue to the next loop iteration/message. + } + + } + }); + break; + case RACESTARTSTATUS: + //System.out.println("Race Start Status Message"); + break; + case YACHTEVENTCODE: + //System.out.println("Yacht Event Code!"); + //No decoder for this. + break; + case YACHTACTIONCODE: + //System.out.println("Yacht Action Code!"); + //No decoder for this. + break; + case CHATTERTEXT: + //System.out.println("Chatter Text Message!"); + //No decoder for this. + break; + case BOATLOCATION: + BoatLocation location = (BoatLocation) message; + + //System.out.println("Boat Location!"); + if (this.boatLocation.containsKey(location.getSourceID())) { + //If our boatlocation map already contains a boat location message for this boat, check that the new message is actually for a later timestamp (i.e., newer). + if (location.getTime() > this.boatLocation.get(location.getSourceID()).getTime()) { + //If it is, replace the old message. + this.boatLocation.put(location.getSourceID(), location); + } + } else { + //If the map _doesn't_ already contain a message for this boat, insert the message. + this.boatLocation.put(location.getSourceID(), location); + } + break; + case MARKROUNDING: + MarkRounding markRounding = (MarkRounding) message; + + //System.out.println("Mark Rounding Message!"); + + if (this.markRoundingMap.containsKey(markRounding.getSourceID())) { + //If our markRoundingMap already contains a mark rounding message for this boat, check that the new message is actually for a later timestamp (i.e., newer). + if (markRounding.getTime() > this.markRoundingMap.get(markRounding.getSourceID()).getTime()) { + //If it is, replace the old message. + this.markRoundingMap.put(markRounding.getSourceID(), markRounding); + } + } else { + //If the map _doesn't_ already contain a message for this boat, insert the message. + this.markRoundingMap.put(markRounding.getSourceID(), markRounding); + } + break; + case COURSEWIND: + //System.out.println("Course Wind Message!"); + this.courseWinds = (CourseWinds) message; + break; + case AVGWIND: + //System.out.println("Average Wind Message!"); + this.averageWind = (AverageWind) message; + break; + default: + System.out.println("Broken Message!"); + break; + } + } + +} diff --git a/visualiser/src/main/java/seng302/Model/ConstantVelocityRace.java b/visualiser/src/main/java/seng302/Model/ConstantVelocityRace.java deleted file mode 100644 index 79b76dbc..00000000 --- a/visualiser/src/main/java/seng302/Model/ConstantVelocityRace.java +++ /dev/null @@ -1,208 +0,0 @@ -//package seng302.Model; -// -//import org.geotools.referencing.GeodeticCalculator; -//import seng302.Constants; -//import seng302.Controllers.RaceController; -//import seng302.GPSCoordinate; -//import seng302.RaceDataSource; -// -//import java.awt.geom.Point2D; -//import java.util.ArrayList; -//import java.util.Arrays; -//import java.util.List; -//import java.util.Random; -// -///** -// * Created by cbt24 on 6/03/17. -// * -// * @deprecated -// */ -//public class ConstantVelocityRace extends Race { -// -// private int dnfChance = 0; //%percentage chance a boat fails at each checkpoint -// -// /** -// * Initializer for a constant velocity race without standard data source -// * -// * @param startingBoats in race -// * @param legs in race -// * @param controller for graphics -// * @param scaleFactor of timer -// */ -// public ConstantVelocityRace(List startingBoats, List legs, RaceController controller, int scaleFactor) { -// super(startingBoats, legs, controller, scaleFactor); -// } -// -// /** -// * Initializer for legacy tests -// * -// * @param startingBoats in race -// * @param legs in race -// * @param controller for graphics -// * @param scaleFactor of timer -// * -// * @deprecated Please use {@link #ConstantVelocityRace(List, List, RaceController, int) } for future tests. -// */ -// public ConstantVelocityRace(BoatInRace[] startingBoats, List legs, RaceController controller, int scaleFactor) { -// super(Arrays.asList(startingBoats), legs, controller, scaleFactor); -// } -// -// /** -// * Initializer for constant velocity race with standard data source -// * @param raceData for race -// * @param controller for graphics -// * @param scaleFactor of timer -// */ -// public ConstantVelocityRace(RaceDataSource raceData, RaceController controller, int scaleFactor) { -// super(raceData, controller, scaleFactor); -// } -// -// public void initialiseBoats() { -// Leg officialStart = legs.get(0); -// String name = officialStart.getName(); -// CompoundMark endMarker = officialStart.getEndCompoundMark(); -// -// BoatInRace.setTrackPointTimeInterval(BoatInRace.getBaseTrackPointTimeInterval() / scaleFactor); -// -// ArrayList startMarkers = getSpreadStartingPositions(); -// for (int i = 0; i < startingBoats.size(); i++) { -// BoatInRace boat = startingBoats.get(i); -// if (boat != null) { -// boat.setScaledVelocity(boat.getVelocity() * scaleFactor); -// Leg startLeg = new Leg(name, 0); -// boat.setCurrentPosition(startMarkers.get(i).getAverageGPSCoordinate()); -// startLeg.setStartCompoundMark(startMarkers.get(i)); -// startLeg.setEndCompoundMark(endMarker); -// startLeg.calculateDistance(); -// boat.setCurrentLeg(startLeg); -// boat.setHeading(boat.calculateHeading()); -// } -// } -// } -// -// /** -// * Creates a list of starting positions for the different boats, so they do not appear cramped at the start line -// * -// * @return list of starting positions -// */ -// public ArrayList getSpreadStartingPositions() { -// -// int nBoats = startingBoats.size(); -// CompoundMark marker = legs.get(0).getStartCompoundMark(); -// -// GeodeticCalculator initialCalc = new GeodeticCalculator(); -// initialCalc.setStartingGeographicPoint(marker.getMark1().getLongitude(), marker.getMark1().getLatitude()); -// initialCalc.setDestinationGeographicPoint(marker.getMark2().getLongitude(), marker.getMark2().getLatitude()); -// -// double azimuth = initialCalc.getAzimuth(); -// double distanceBetweenMarkers = initialCalc.getOrthodromicDistance(); -// double distanceBetweenBoats = distanceBetweenMarkers / (nBoats + 1); -// -// GeodeticCalculator positionCalc = new GeodeticCalculator(); -// positionCalc.setStartingGeographicPoint(marker.getMark1().getLongitude(), marker.getMark1().getLatitude()); -// ArrayList positions = new ArrayList<>(); -// -// for (int i = 0; i < nBoats; i++) { -// positionCalc.setDirection(azimuth, distanceBetweenBoats); -// Point2D position = positionCalc.getDestinationGeographicPoint(); -// positions.add(new CompoundMark(new GPSCoordinate(position.getY(), position.getX()))); -// -// positionCalc = new GeodeticCalculator(); -// positionCalc.setStartingGeographicPoint(position); -// } -// return positions; -// } -// -// /** -// * Sets the chance each boat has of failing at a gate or marker -// * @param chance percentage chance a boat has of failing per checkpoint. -// */ -// protected void setDnfChance(int chance) { -// if (chance >= 0 && chance <= 100) { -// dnfChance = chance; -// } -// } -// -// protected boolean doNotFinish() { -// Random rand = new Random(); -// return rand.nextInt(100) < dnfChance; -// } -// -// /** -// * Calculates the distance a boat has travelled and updates its current position according to this value. -// * -// * @param boat to be updated -// * @param millisecondsElapsed since last update -// */ -// protected void updatePosition(BoatInRace boat, int millisecondsElapsed) { -// -// //distanceTravelled = velocity (nm p hr) * time taken to update loop -// double distanceTravelled = (boat.getScaledVelocity() * millisecondsElapsed) / 3600000; -// -// double totalDistanceTravelled = distanceTravelled + boat.getDistanceTravelledInLeg(); -// -// boolean finish = boat.getCurrentLeg().getName().equals("Finish"); -// if (!finish) { -// boat.setHeading(boat.calculateHeading()); -// //update boat's distance travelled -// boat.setDistanceTravelledInLeg(totalDistanceTravelled); -// //Calculate boat's new position by adding the distance travelled onto the start point of the leg -// boat.setCurrentPosition(calculatePosition(boat.getCurrentLeg().getStartCompoundMark().getAverageGPSCoordinate(), -// totalDistanceTravelled, boat.calculateAzimuth())); -// } -// } -// -// protected void checkPosition(BoatInRace boat, long timeElapsed) { -// if (boat.getDistanceTravelledInLeg() > boat.getCurrentLeg().getDistance()) { -// //boat has passed onto new leg -// if (boat.getCurrentLeg().getName().equals("Finish")) { -// //boat has finished -// boatsFinished++; -// boat.setFinished(true); -// boat.setTimeFinished(timeElapsed); -// } else if (doNotFinish()) { -// boatsFinished++; -// boat.setFinished(true); -// boat.setCurrentLeg(new Leg("DNF", -1)); -// boat.setVelocity(0); -// boat.setScaledVelocity(0); -// } 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 -// updatePositions(); -// } -// } -// -// /** -// * Calculates the boats next GPS position based on its distance travelled and heading -// * -// * @param oldCoordinates GPS coordinates of the boat's starting position -// * @param distanceTravelled distance in nautical miles -// * @param azimuth boat's current direction. Value between -180 and 180 -// * @return The boat's new coordinate -// */ -// public static GPSCoordinate calculatePosition(GPSCoordinate oldCoordinates, double distanceTravelled, double azimuth) { -// -// //Find new coordinate using current heading and distance -// -// GeodeticCalculator geodeticCalculator = new GeodeticCalculator(); -// //Load start point into calculator -// Point2D startPoint = new Point2D.Double(oldCoordinates.getLongitude(), oldCoordinates.getLatitude()); -// geodeticCalculator.setStartingGeographicPoint(startPoint); -// //load direction and distance tranvelled into calculator -// geodeticCalculator.setDirection(azimuth, distanceTravelled * Constants.NMToMetersConversion); -// //get new point -// Point2D endPoint = geodeticCalculator.getDestinationGeographicPoint(); -// -// return new GPSCoordinate(endPoint.getY(), endPoint.getX()); -// } -// -//} \ No newline at end of file diff --git a/visualiser/src/main/java/seng302/Model/ResizableRaceCanvas.java b/visualiser/src/main/java/seng302/Model/ResizableRaceCanvas.java index b4815d22..6839abcf 100644 --- a/visualiser/src/main/java/seng302/Model/ResizableRaceCanvas.java +++ b/visualiser/src/main/java/seng302/Model/ResizableRaceCanvas.java @@ -191,7 +191,6 @@ public class ResizableRaceCanvas extends ResizableCanvas { */ public void update() { this.draw(); - this.updateBoats(); } /** diff --git a/visualiser/src/main/java/seng302/VisualiserInput.java b/visualiser/src/main/java/seng302/VisualiserInput.java index 66547b8a..16627f75 100644 --- a/visualiser/src/main/java/seng302/VisualiserInput.java +++ b/visualiser/src/main/java/seng302/VisualiserInput.java @@ -1,20 +1,15 @@ package seng302; -import javafx.application.Platform; -import org.xml.sax.SAXException; import seng302.Mock.*; import seng302.Networking.BinaryMessageDecoder; import seng302.Networking.Exceptions.InvalidMessageException; import seng302.Networking.Messages.*; -import javax.xml.parsers.ParserConfigurationException; import java.io.DataInputStream; import java.io.IOException; import java.net.Socket; import java.nio.ByteBuffer; import java.util.Arrays; -import java.util.HashMap; import java.util.Map; -import java.util.concurrent.ArrayBlockingQueue; import static seng302.Networking.Utils.ByteConverter.bytesToShort; @@ -34,23 +29,7 @@ public class VisualiserInput implements Runnable { ///Object to store parsed course data. //TODO comment? private StreamedCourse course; - ///The last RaceStatus message received. - private RaceStatus raceStatus; - - ///A map of the last BoatStatus message received, for each boat. - private final Map boatStatusMap = new HashMap<>(); - - ///A map of the last BoatLocation message received, for each boat. - private final Map boatLocationMap = new HashMap<>(); - - ///The last AverageWind message received. - private AverageWind averageWind; - - ///The last CourseWinds message received. - private CourseWinds courseWinds; - - ///A map of the last MarkRounding message received, for each boat. - private final Map markRoundingMap = new HashMap<>(); + private final AC35RaceStatus ac35RaceStatus; ///InputStream (from the socket). private DataInputStream inStream; @@ -66,7 +45,7 @@ public class VisualiserInput implements Runnable { //We wrap a DataInputStream around the socket's InputStream because it has the stream.readFully(buffer) function, which is a blocking read until the buffer has been filled. this.inStream = new DataInputStream(connectionSocket.getInputStream()); this.course = course; - + this.ac35RaceStatus = new AC35RaceStatus(this); this.lastHeartbeatTime = System.currentTimeMillis(); } @@ -85,7 +64,7 @@ public class VisualiserInput implements Runnable { * @return The most recent location message. */ public BoatLocation getBoatLocationMessage(int sourceID) { - return boatLocationMap.get(sourceID); + return ac35RaceStatus.boatLocation.get(sourceID); } /** @@ -102,7 +81,7 @@ public class VisualiserInput implements Runnable { * @return Map of boat locations. */ public Map getBoatLocationMap() { - return boatLocationMap; + return ac35RaceStatus.boatLocation; } /** @@ -110,7 +89,7 @@ public class VisualiserInput implements Runnable { * @return The status of the race. */ public RaceStatus getRaceStatus() { - return raceStatus; + return ac35RaceStatus.raceStatus; } /** @@ -118,7 +97,7 @@ public class VisualiserInput implements Runnable { * @return Map of boat statuses. */ public Map getBoatStatusMap() { - return boatStatusMap; + return ac35RaceStatus.boatStatusMap; } /** @@ -126,7 +105,7 @@ public class VisualiserInput implements Runnable { * @return Average wind in the race. */ public AverageWind getAverageWind() { - return averageWind; + return ac35RaceStatus.averageWind; } /** @@ -134,7 +113,7 @@ public class VisualiserInput implements Runnable { * @return Winds that are in the course. */ public CourseWinds getCourseWinds() { - return courseWinds; + return ac35RaceStatus.courseWinds; } @@ -143,16 +122,40 @@ public class VisualiserInput implements Runnable { * @return Map of mark roundings. */ public Map getMarkRoundingMap() { - return markRoundingMap; + return ac35RaceStatus.markRoundingMap; } /** * Sets the wind direction for the current course. */ - private void setCourseWindDirection(double direction) { + protected void setCourseWindDirection(double direction) { this.course.setWindDirection(direction); } + /** + * Sets last time the heartbeat was read + * @param lastHeartbeatTime time that the heart beat was read (in ms) + */ + public void setLastHeartbeatTime(long lastHeartbeatTime) { + this.lastHeartbeatTime = lastHeartbeatTime; + } + + /** + * gets the last sequencenumber of the heartbeat + * @return the last heartbeat sequence number + */ + public long getLastHeartbeatSequenceNum() { + return lastHeartbeatSequenceNum; + } + + /** + * Sets the last heartbeat squence number + * @param lastHeartbeatSequenceNum sequence number of heartbeat + */ + public void setLastHeartbeatSequenceNum(long lastHeartbeatSequenceNum) { + this.lastHeartbeatSequenceNum = lastHeartbeatSequenceNum; + } + /** * Reads and returns the next message as an array of bytes from the socket. Use getNextMessage() to get the actual message object instead. * @return Encoded binary message bytes. @@ -230,13 +233,10 @@ public class VisualiserInput implements Runnable { } catch (IOException e) { System.err.println("Unable to reconnect."); - - //Wait 500ms. Ugly hack, should refactor. - long waitPeriod = 500; - long waitTimeStart = System.currentTimeMillis() + waitPeriod; - - while (System.currentTimeMillis() < waitTimeStart){ - //Nothing. Busyloop. + try { + Thread.sleep(500); + } catch (InterruptedException e1) { + e1.printStackTrace(); } //Swallow the exception. @@ -256,169 +256,14 @@ public class VisualiserInput implements Runnable { try { inStream.reset(); } catch (IOException e1) { - e1.printStackTrace(); + //swallow the exception } //Continue to the next loop iteration/message. continue; - }/* - - //Add it to message queue. - this.messagesReceivedQueue.add(message);*/ - - - //Checks which message is being received and does what is needed for that message. - //Heartbeat. - if (message instanceof Heartbeat) { - Heartbeat heartbeat = (Heartbeat) message; - - //Check that the heartbeat number is greater than the previous value, and then set the last heartbeat time. - if (heartbeat.getSequenceNumber() > this.lastHeartbeatSequenceNum) { - lastHeartbeatTime = System.currentTimeMillis(); - lastHeartbeatSequenceNum = heartbeat.getSequenceNumber(); - //System.out.println("HeartBeat Message! " + lastHeartbeatSequenceNum); - } - } - //RaceStatus. - else if (message instanceof RaceStatus) { - RaceStatus raceStatus = (RaceStatus) message; - - //System.out.println("Race Status Message"); - this.raceStatus = raceStatus; - for (BoatStatus boatStatus: this.raceStatus.getBoatStatuses()) { - this.boatStatusMap.put(boatStatus.getSourceID(), boatStatus); - } - setCourseWindDirection(raceStatus.getScaledWindDirection() + 180); - } - //DisplayTextMessage. - /*else if (message instanceof DisplayTextMessage) { - //System.out.println("Display Text Message"); - //No decoder for this. - }*/ - //XMLMessage. - else if (message instanceof XMLMessage) { - XMLMessage xmlMessage = (XMLMessage) message; - - //System.out.println("XML Message!"); - - Platform.runLater(()-> { - if (xmlMessage.getXmlMsgSubType() == XMLMessage.XMLTypeRegatta) { - //System.out.println("Setting Regatta"); - try { - course.setRegattaXMLReader(new RegattaXMLReader(xmlMessage.getXmlMessage())); - - } - //TODO REFACTOR should put all of these exceptions behind a RegattaXMLReaderException. - catch (IOException | SAXException | ParserConfigurationException e) { - System.err.println("Error creating RegattaXMLReader: " + e.getMessage()); - //Continue to the next loop iteration/message. - } - - } else if (xmlMessage.getXmlMsgSubType() == XMLMessage.XMLTypeRace) { - //System.out.println("Setting Course"); - try { - course.setStreamedCourseXMLReader(new StreamedCourseXMLReader(xmlMessage.getXmlMessage())); - } - //TODO REFACTOR should put all of these exceptions behind a StreamedCourseXMLReaderException. - catch (IOException | SAXException | ParserConfigurationException | StreamedCourseXMLException e) { - System.err.println("Error creating StreamedCourseXMLReader: " + e.getMessage()); - //Continue to the next loop iteration/message. - } - - } else if (xmlMessage.getXmlMsgSubType() == XMLMessage.XMLTypeBoat) { - //System.out.println("Setting Boats"); - try { - course.setBoatXMLReader(new BoatXMLReader(xmlMessage.getXmlMessage())); - } - //TODO REFACTOR should put all of these exceptions behind a BoatXMLReaderException. - catch (IOException | SAXException | ParserConfigurationException e) { - System.err.println("Error creating BoatXMLReader: " + e.getMessage()); - //Continue to the next loop iteration/message. - } - - } - }); - } - //RaceStartStatus. - else if (message instanceof RaceStartStatus) { - - //System.out.println("Race Start Status Message"); } - //YachtEventCode. - /*else if (message instanceof YachtEventCode) { - YachtEventCode yachtEventCode = (YachtEventCode) message; - - //System.out.println("Yacht Event Code!"); - //No decoder for this. - - }*/ - //YachtActionCode. - /*else if (message instanceof YachtActionCode) { - YachtActionCode yachtActionCode = (YachtActionCode) message; - - //System.out.println("Yacht Action Code!"); - //No decoder for this. - - }*/ - //ChatterText. - /*else if (message instanceof ChatterText) { - ChatterText chatterText = (ChatterText) message; - - //System.out.println("Chatter Text Message!"); - //No decoder for this. - - }*/ - //BoatLocation. - else if (message instanceof BoatLocation) { - BoatLocation boatLocation = (BoatLocation) message; - - //System.out.println("Boat Location!"); - if (this.boatLocationMap.containsKey(boatLocation.getSourceID())) { - //If our boatlocation map already contains a boat location message for this boat, check that the new message is actually for a later timestamp (i.e., newer). - if (boatLocation.getTime() > this.boatLocationMap.get(boatLocation.getSourceID()).getTime()){ - //If it is, replace the old message. - this.boatLocationMap.put(boatLocation.getSourceID(), boatLocation); - } - }else{ - //If the map _doesn't_ already contain a message for this boat, insert the message. - this.boatLocationMap.put(boatLocation.getSourceID(), boatLocation); - } - } - //MarkRounding. - else if (message instanceof MarkRounding) { - MarkRounding markRounding = (MarkRounding) message; - - //System.out.println("Mark Rounding Message!"); - - if (this.markRoundingMap.containsKey(markRounding.getSourceID())) { - //If our markRoundingMap already contains a mark rounding message for this boat, check that the new message is actually for a later timestamp (i.e., newer). - if (markRounding.getTime() > this.markRoundingMap.get(markRounding.getSourceID()).getTime()){ - //If it is, replace the old message. - this.markRoundingMap.put(markRounding.getSourceID(), markRounding); - } - }else{ - //If the map _doesn't_ already contain a message for this boat, insert the message. - this.markRoundingMap.put(markRounding.getSourceID(), markRounding); - } - - } - //CourseWinds. - else if (message instanceof CourseWinds) { - //System.out.println("Course Wind Message!"); - this.courseWinds = (CourseWinds) message; + ac35RaceStatus.update(message); - } - //AverageWind. - else if (message instanceof AverageWind) { - - //System.out.println("Average Wind Message!"); - this.averageWind = (AverageWind) message; - - } - //Unrecognised message. - else { - System.out.println("Broken Message!"); - } } } From dc7aa359d7a1b9cb7bc04b9c9bee9c7b208a447e Mon Sep 17 00:00:00 2001 From: hba56 Date: Wed, 24 May 2017 17:59:02 +1200 Subject: [PATCH 2/8] boat time now saves #story[878] --- .../src/main/java/seng302/Controllers/RaceController.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/visualiser/src/main/java/seng302/Controllers/RaceController.java b/visualiser/src/main/java/seng302/Controllers/RaceController.java index 43d12f64..df6318f6 100644 --- a/visualiser/src/main/java/seng302/Controllers/RaceController.java +++ b/visualiser/src/main/java/seng302/Controllers/RaceController.java @@ -7,23 +7,17 @@ import javafx.fxml.FXML; import javafx.scene.chart.LineChart; import javafx.scene.chart.NumberAxis; import javafx.scene.chart.XYChart; -import javafx.geometry.Pos; import javafx.scene.control.*; import javafx.scene.layout.GridPane; -import javafx.scene.paint.Color; import javafx.scene.layout.Pane; import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; -import javafx.scene.paint.Paint; import seng302.Mock.StreamedRace; import seng302.Model.*; import seng302.VisualiserInput; import java.net.URL; import java.util.*; -import java.util.ArrayList; -import java.util.Locale; -import java.util.ResourceBundle; /** * Created by fwy13 on 15/03/2017. @@ -374,6 +368,7 @@ public class RaceController extends Controller { presetAnno.add(showAbbrev.isSelected()); presetAnno.add(showSpeed.isSelected()); presetAnno.add(showBoatPath.isSelected()); + presetAnno.add(showTime.isSelected()); }); //listener to show saved annotation showSetAnno.setOnAction(event -> { @@ -382,6 +377,7 @@ public class RaceController extends Controller { showAbbrev.setSelected(presetAnno.get(1)); showSpeed.setSelected(presetAnno.get(2)); showBoatPath.setSelected(presetAnno.get(3)); + showTime.setSelected(presetAnno.get(4)); raceMap.update(); } }); From debc5d9c3883a37f9277619633a6699d2ef3b853 Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Wed, 24 May 2017 22:24:37 +1200 Subject: [PATCH 3/8] Added adjustments that PO requested - hide will not deselect all checkboxes - visible will now show all checkboxes that were deselected when hidden - partial will now select abbreviation and speed only - when another checkbox is selected/deselected from partial,hidden or important it will immediately jump to visible radio button. #story[877] --- .../seng302/Controllers/RaceController.java | 130 ++++++++++++++++-- .../seng302/Model/ResizableRaceCanvas.java | 26 +--- 2 files changed, 123 insertions(+), 33 deletions(-) diff --git a/visualiser/src/main/java/seng302/Controllers/RaceController.java b/visualiser/src/main/java/seng302/Controllers/RaceController.java index de66ea24..fec6217a 100644 --- a/visualiser/src/main/java/seng302/Controllers/RaceController.java +++ b/visualiser/src/main/java/seng302/Controllers/RaceController.java @@ -11,6 +11,8 @@ import seng302.VisualiserInput; import java.net.URL; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import java.util.ResourceBundle; /** @@ -21,9 +23,25 @@ public class RaceController extends Controller { //user saved data for annotation display private ArrayList presetAnno; + private Map importantAnno; + private Map annoShownBeforeHide; + private int buttonChecked;//button currently checked allows the checkboxes to know whether or not to put it's state in history (if not hidden then store) + private int prevBtnChecked;//button to keep track of previous pressed button incase we want to check a checkbox straight from hidden we do not wish for all previous to come on. + + private static String nameCheckAnno = "name"; + private static String abbrevCheckAnno = "abbrev"; + private static String speedCheckAnno = "speed"; + private static String pathCheckAnno = "path"; + + private static int noBtn = 0; + private static int hideBtn = 1; + private static int showBtn = 2; + private static int partialBtn = 3; + private static int importantBtn = 4; private ResizableRaceCanvas raceMap; private ResizableRaceMap raceBoundaries; + private ToggleGroup annotationGroup; @FXML SplitPane race; @FXML CheckBox showFPS; @FXML CheckBox showBoatPath; @@ -86,7 +104,7 @@ public class RaceController extends Controller { } }); //adds all radios buttons for annotations to a group - ToggleGroup annotationGroup = new ToggleGroup(); + annotationGroup = new ToggleGroup(); hideAnnoRBTN.setToggleGroup(annotationGroup); showAnnoRBTN.setToggleGroup(annotationGroup); partialAnnoRBTN.setToggleGroup(annotationGroup); @@ -165,31 +183,103 @@ public class RaceController extends Controller { }); } + private void storeCurrentAnnotationState(){ + annoShownBeforeHide.put(nameCheckAnno, showName.isSelected()); + annoShownBeforeHide.put(abbrevCheckAnno, showAbbrev.isSelected()); + annoShownBeforeHide.put(pathCheckAnno, showBoatPath.isSelected()); + annoShownBeforeHide.put(speedCheckAnno, showSpeed.isSelected()); + } + /** * Set up boat annotations */ private void initializeAnnotations() { presetAnno = new ArrayList<>(); + + importantAnno = new HashMap<>(); + importantAnno.put(nameCheckAnno, false); + importantAnno.put(abbrevCheckAnno, false); + importantAnno.put(pathCheckAnno, false); + importantAnno.put(speedCheckAnno, false); + + annoShownBeforeHide = new HashMap<>(); + annoShownBeforeHide.put(nameCheckAnno, true); + annoShownBeforeHide.put(abbrevCheckAnno, true); + annoShownBeforeHide.put(pathCheckAnno, true); + annoShownBeforeHide.put(speedCheckAnno, true); //listener for show name in annotation showName.selectedProperty().addListener((ov, old_val, new_val) -> { - raceMap.toggleAnnoName(); + if (old_val != new_val) { + raceMap.toggleAnnoName(); + } + if (buttonChecked != hideBtn) { + //if we are checking the box straight out of hide instead of using the radio buttons + if (prevBtnChecked == hideBtn && buttonChecked != showBtn){ + storeCurrentAnnotationState(); + } else { + annoShownBeforeHide.put(nameCheckAnno, showName.isSelected()); + } + if (buttonChecked == noBtn) { + annotationGroup.selectToggle(showAnnoRBTN); + } + } raceMap.update(); + prevBtnChecked = noBtn; }); //listener for show abbreviation for annotation showAbbrev.selectedProperty().addListener((ov, old_val, new_val) -> { - raceMap.toggleAnnoAbbrev(); + if (old_val != new_val) { + raceMap.toggleAnnoAbbrev(); + } + if (buttonChecked != hideBtn) { + if (prevBtnChecked == hideBtn && buttonChecked != showBtn){ + storeCurrentAnnotationState(); + } else { + annoShownBeforeHide.put(abbrevCheckAnno, showAbbrev.isSelected()); + } + if (buttonChecked == noBtn) { + annotationGroup.selectToggle(showAnnoRBTN); + } + } raceMap.update(); + prevBtnChecked = noBtn; }); //listener for show boat path for annotation showBoatPath.selectedProperty().addListener((ov, old_val, new_val) -> { - raceMap.toggleBoatPath(); + if (old_val != new_val) { + raceMap.toggleBoatPath(); + } + if (buttonChecked != hideBtn) { + if (prevBtnChecked == hideBtn && buttonChecked != showBtn){ + storeCurrentAnnotationState(); + } else { + annoShownBeforeHide.put(pathCheckAnno, showBoatPath.isSelected()); + } + if (buttonChecked == noBtn) { + annotationGroup.selectToggle(showAnnoRBTN); + } + } raceMap.update(); + prevBtnChecked = noBtn; }); //listener to show speed for annotation showSpeed.selectedProperty().addListener((ov, old_val, new_val) -> { - raceMap.toggleAnnoSpeed(); + if (old_val != new_val) { + raceMap.toggleAnnoSpeed(); + } + if (buttonChecked != hideBtn) { + if (prevBtnChecked == hideBtn && buttonChecked != showBtn){ + storeCurrentAnnotationState(); + } else { + annoShownBeforeHide.put(speedCheckAnno, showSpeed.isSelected()); + } + if (buttonChecked == noBtn) { + annotationGroup.selectToggle(showAnnoRBTN); + } + } raceMap.update(); + prevBtnChecked = noBtn; }); //listener to save currently selected annotation saveAnno.setOnAction(event -> { @@ -201,33 +291,55 @@ public class RaceController extends Controller { }); //listener for hiding hideAnnoRBTN.selectedProperty().addListener((ov, old_val, new_val) ->{ - raceMap.hideAnnotations(); + buttonChecked = hideBtn; + //raceMap.hideAnnotations(); + showName.setSelected(false); + showAbbrev.setSelected(false); + showBoatPath.setSelected(false); + showSpeed.setSelected(false); + annotationGroup.selectToggle(hideAnnoRBTN); raceMap.update(); + buttonChecked = noBtn; + prevBtnChecked = hideBtn; }); //listener for showing all annotations showAnnoRBTN.selectedProperty().addListener((ov, old_val, new_val) ->{ - raceMap.showAnnotations(); + buttonChecked = showBtn; + showName.setSelected(annoShownBeforeHide.get(nameCheckAnno)); + showAbbrev.setSelected(annoShownBeforeHide.get(abbrevCheckAnno)); + showBoatPath.setSelected(annoShownBeforeHide.get(pathCheckAnno)); + showSpeed.setSelected(annoShownBeforeHide.get(speedCheckAnno)); raceMap.update(); + buttonChecked = noBtn; + prevBtnChecked = showBtn; }); //listener for showing all important partialAnnoRBTN.selectedProperty().addListener((ov, old_val, new_val) ->{ + buttonChecked = partialBtn; showName.setSelected(false); showAbbrev.setSelected(true); showSpeed.setSelected(true); showBoatPath.setSelected(false); - raceMap.showAnnotations(); + //partialAnnoRBTN.setSelected(true);//as the others will set the show button back to visible then we need to make it so that this is rechecked. + annotationGroup.selectToggle(partialAnnoRBTN); raceMap.update(); + buttonChecked = noBtn; + prevBtnChecked = partialBtn; }); //listener for showing all important importantAnnoRBTN.selectedProperty().addListener((ov, old_val, new_val) ->{ + buttonChecked = importantBtn; if (presetAnno.size() > 0) { showName.setSelected(presetAnno.get(0)); showAbbrev.setSelected(presetAnno.get(1)); showSpeed.setSelected(presetAnno.get(2)); showBoatPath.setSelected(presetAnno.get(3)); - raceMap.showAnnotations(); + annotationGroup.selectToggle(importantAnnoRBTN); raceMap.update(); } + buttonChecked = noBtn; + prevBtnChecked = importantBtn; }); + annotationGroup.selectToggle(showAnnoRBTN); } } diff --git a/visualiser/src/main/java/seng302/Model/ResizableRaceCanvas.java b/visualiser/src/main/java/seng302/Model/ResizableRaceCanvas.java index 0b87a734..3df5055c 100644 --- a/visualiser/src/main/java/seng302/Model/ResizableRaceCanvas.java +++ b/visualiser/src/main/java/seng302/Model/ResizableRaceCanvas.java @@ -23,7 +23,6 @@ public class ResizableRaceCanvas extends ResizableCanvas { private RaceMap map; private List boats; private List boatMarkers; - private boolean raceAnno = true; private boolean annoName = true; private boolean annoAbbrev = true; private boolean annoSpeed = true; @@ -240,26 +239,6 @@ public class ResizableRaceCanvas extends ResizableCanvas { } } - /** - * Toggle the raceAnno value - */ - public void toggleAnnotations() { - raceAnno = !raceAnno; - } - - /** - * Shows the race Annotations - */ - public void showAnnotations(){ - raceAnno = true; - } - - /** - * Hides the Race ANnotations - */ - public void hideAnnotations(){ - raceAnno = false; - } /** * Toggle name display in annotation @@ -309,8 +288,7 @@ public class ResizableRaceCanvas extends ResizableCanvas { displayBoat(boat, 0, colours.get(currentColour)); } - if (raceAnno) - displayText(boat.toString(), boat.getAbbrev(), boat.getVelocity(), this.map.convertGPS(boat.getCurrentPosition())); + displayText(boat.toString(), boat.getAbbrev(), boat.getVelocity(), this.map.convertGPS(boat.getCurrentPosition())); //TODO this needs to be fixed. drawTrack(boat, colours.get(currentColour)); currentColour = (currentColour + 1) % colours.size(); @@ -324,7 +302,7 @@ public class ResizableRaceCanvas extends ResizableCanvas { * @see seng302.Model.TrackPoint */ private void drawTrack(Boat boat, Color colour) { - if (annoPath && raceAnno) { + if (annoPath) { for (TrackPoint point : boat.getTrack()) { GraphCoordinate scaledCoordinate = this.map.convertGPS(point.getCoordinate()); gc.setFill(new Color(colour.getRed(), colour.getGreen(), colour.getBlue(), point.getAlpha())); From e3c3def1848b99bdb0ad7473376e07645920349b Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Wed, 24 May 2017 22:29:51 +1200 Subject: [PATCH 4/8] Fixed capitalisation that was pointed out by Erika in the Tests - LegTest.java ORIGIN_Compound_MARKER is now ORIGIN_COMPOUND_MARKER #story[877] --- mock/src/test/java/seng302/Model/LegTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mock/src/test/java/seng302/Model/LegTest.java b/mock/src/test/java/seng302/Model/LegTest.java index cae7b203..3bf1ffc8 100644 --- a/mock/src/test/java/seng302/Model/LegTest.java +++ b/mock/src/test/java/seng302/Model/LegTest.java @@ -14,7 +14,7 @@ import static junit.framework.TestCase.assertEquals; */ public class LegTest { - private Marker ORIGIN_Compound_MARKER = new Marker(new GPSCoordinate(0, 0)); + private Marker ORIGIN_COMPOUND_MARKER = new Marker(new GPSCoordinate(0, 0)); @Test public void calculateDistanceHandles5nmNorth() { @@ -23,7 +23,7 @@ public class LegTest { calc.setDirection(0, 5 * Constants.NMToMetersConversion); Marker endMarker = getEndMarker(calc.getDestinationGeographicPoint()); - Leg test = new Leg("Test", ORIGIN_Compound_MARKER, endMarker, 0); + Leg test = new Leg("Test", ORIGIN_COMPOUND_MARKER, endMarker, 0); assertEquals(test.getDistance(), 5, 1e-8); } @@ -34,7 +34,7 @@ public class LegTest { calc.setDirection(90, 12 * Constants.NMToMetersConversion); Marker endMarker = getEndMarker(calc.getDestinationGeographicPoint()); - Leg test = new Leg("Test", ORIGIN_Compound_MARKER, endMarker, 0); + Leg test = new Leg("Test", ORIGIN_COMPOUND_MARKER, endMarker, 0); assertEquals(test.getDistance(), 12, 1e-8); } @@ -45,7 +45,7 @@ public class LegTest { calc.setDirection(180, 0.5 * Constants.NMToMetersConversion); Marker endMarker = getEndMarker(calc.getDestinationGeographicPoint()); - Leg test = new Leg("Test", ORIGIN_Compound_MARKER, endMarker, 0); + Leg test = new Leg("Test", ORIGIN_COMPOUND_MARKER, endMarker, 0); assertEquals(test.getDistance(), 0.5, 1e-8); } @@ -56,14 +56,14 @@ public class LegTest { calc.setDirection(-90, 0.1 * Constants.NMToMetersConversion); Marker endMarker = getEndMarker(calc.getDestinationGeographicPoint()); - Leg test = new Leg("Test", ORIGIN_Compound_MARKER, endMarker, 0); + Leg test = new Leg("Test", ORIGIN_COMPOUND_MARKER, endMarker, 0); assertEquals(test.getDistance(), 0.1, 1e-8); } @Test public void calculateDistanceHandlesZeroDifference() { - Leg test = new Leg("Test", ORIGIN_Compound_MARKER, ORIGIN_Compound_MARKER, 0); + Leg test = new Leg("Test", ORIGIN_COMPOUND_MARKER, ORIGIN_COMPOUND_MARKER, 0); assertEquals(test.getDistance(), 0, 1e-8); } From ba5e74ab9c61067c16ffbff3dd0d1b5837689b6f Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Wed, 24 May 2017 23:13:59 +1200 Subject: [PATCH 5/8] Merge with master complete - merged with master #story[877] --- mock/src/test/java/seng302/Model/LegTest.java | 12 +++---- .../seng302/Controllers/RaceController.java | 34 ++++++++++++++----- .../src/main/resources/scenes/race.fxml | 16 ++++----- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/mock/src/test/java/seng302/Model/LegTest.java b/mock/src/test/java/seng302/Model/LegTest.java index 06ac325b..cb8d70d4 100644 --- a/mock/src/test/java/seng302/Model/LegTest.java +++ b/mock/src/test/java/seng302/Model/LegTest.java @@ -14,7 +14,7 @@ import static junit.framework.TestCase.assertEquals; */ public class LegTest { - private CompoundMark ORIGIN_Compound_MARKER = new CompoundMark(new Mark(1, "test mark1", new GPSCoordinate(0, 0))); + private CompoundMark ORIGIN_COMPOUND_MARKER = new CompoundMark(new Mark(1, "test mark1", new GPSCoordinate(0, 0))); @Test public void calculateDistanceHandles5nmNorth() { @@ -23,7 +23,7 @@ public class LegTest { calc.setDirection(0, 5 * Constants.NMToMetersConversion); CompoundMark endMarker = getEndMarker(calc.getDestinationGeographicPoint()); - Leg test = new Leg("Test", ORIGIN_Compound_MARKER, endMarker, 0); + Leg test = new Leg("Test", ORIGIN_COMPOUND_MARKER, endMarker, 0); assertEquals(test.getDistanceNauticalMiles(), 5, 1e-8); } @@ -34,7 +34,7 @@ public class LegTest { calc.setDirection(90, 12 * Constants.NMToMetersConversion); CompoundMark endMarker = getEndMarker(calc.getDestinationGeographicPoint()); - Leg test = new Leg("Test", ORIGIN_Compound_MARKER, endMarker, 0); + Leg test = new Leg("Test", ORIGIN_COMPOUND_MARKER, endMarker, 0); assertEquals(test.getDistanceNauticalMiles(), 12, 1e-8); } @@ -45,7 +45,7 @@ public class LegTest { calc.setDirection(180, 0.5 * Constants.NMToMetersConversion); CompoundMark endMarker = getEndMarker(calc.getDestinationGeographicPoint()); - Leg test = new Leg("Test", ORIGIN_Compound_MARKER, endMarker, 0); + Leg test = new Leg("Test", ORIGIN_COMPOUND_MARKER, endMarker, 0); assertEquals(test.getDistanceNauticalMiles(), 0.5, 1e-8); } @@ -56,14 +56,14 @@ public class LegTest { calc.setDirection(-90, 0.1 * Constants.NMToMetersConversion); CompoundMark endMarker = getEndMarker(calc.getDestinationGeographicPoint()); - Leg test = new Leg("Test", ORIGIN_Compound_MARKER, endMarker, 0); + Leg test = new Leg("Test", ORIGIN_COMPOUND_MARKER, endMarker, 0); assertEquals(test.getDistanceNauticalMiles(), 0.1, 1e-8); } @Test public void calculateDistanceHandlesZeroDifference() { - Leg test = new Leg("Test", ORIGIN_Compound_MARKER, ORIGIN_Compound_MARKER, 0); + Leg test = new Leg("Test", ORIGIN_COMPOUND_MARKER, ORIGIN_COMPOUND_MARKER, 0); assertEquals(test.getDistanceNauticalMiles(), 0, 1e-8); } diff --git a/visualiser/src/main/java/seng302/Controllers/RaceController.java b/visualiser/src/main/java/seng302/Controllers/RaceController.java index 67485626..3082b325 100644 --- a/visualiser/src/main/java/seng302/Controllers/RaceController.java +++ b/visualiser/src/main/java/seng302/Controllers/RaceController.java @@ -17,10 +17,7 @@ import seng302.Model.*; import seng302.VisualiserInput; import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.ResourceBundle; +import java.util.*; /** * Created by fwy13 on 15/03/2017. @@ -39,6 +36,7 @@ public class RaceController extends Controller { private static String abbrevCheckAnno = "abbrev"; private static String speedCheckAnno = "speed"; private static String pathCheckAnno = "path"; + private static String timeCheckAnno = "time"; private static int noBtn = 0; private static int hideBtn = 1; @@ -63,13 +61,13 @@ public class RaceController extends Controller { @FXML StackPane arrowPane; @FXML CheckBox showFPS; @FXML CheckBox showBoatPath; - @FXML Label timer; - @FXML Label FPS; - @FXML Label timeZone; @FXML CheckBox showName; @FXML CheckBox showAbbrev; @FXML CheckBox showSpeed; @FXML CheckBox showTime; + @FXML Label timer; + @FXML Label FPS; + @FXML Label timeZone; @FXML Button saveAnno; @FXML TableView boatInfoTable; @FXML TableColumn boatPlacingColumn; @@ -357,6 +355,7 @@ public class RaceController extends Controller { annoShownBeforeHide.put(abbrevCheckAnno, showAbbrev.isSelected()); annoShownBeforeHide.put(pathCheckAnno, showBoatPath.isSelected()); annoShownBeforeHide.put(speedCheckAnno, showSpeed.isSelected()); + annoShownBeforeHide.put(timeCheckAnno, showTime.isSelected()); } /** @@ -370,12 +369,14 @@ public class RaceController extends Controller { importantAnno.put(abbrevCheckAnno, false); importantAnno.put(pathCheckAnno, false); importantAnno.put(speedCheckAnno, false); + importantAnno.put(timeCheckAnno, true); annoShownBeforeHide = new HashMap<>(); annoShownBeforeHide.put(nameCheckAnno, true); annoShownBeforeHide.put(abbrevCheckAnno, true); annoShownBeforeHide.put(pathCheckAnno, true); annoShownBeforeHide.put(speedCheckAnno, true); + annoShownBeforeHide.put(timeCheckAnno, true); //listener for show name in annotation showName.selectedProperty().addListener((ov, old_val, new_val) -> { if (old_val != new_val) { @@ -451,7 +452,20 @@ public class RaceController extends Controller { prevBtnChecked = noBtn; }); showTime.selectedProperty().addListener((ov, old_val, new_val) -> { - raceMap.toggleAnnoTime(); + if (old_val != new_val) { + raceMap.toggleAnnoTime(); + } + if (buttonChecked != hideBtn) { + if (prevBtnChecked == hideBtn && buttonChecked != showBtn){ + storeCurrentAnnotationState(); + } else { + annoShownBeforeHide.put(timeCheckAnno, showTime.isSelected()); + } + if (buttonChecked == noBtn) { + annotationGroup.selectToggle(showAnnoRBTN); + } + } + prevBtnChecked = noBtn; raceMap.update(); }); //listener to save currently selected annotation @@ -471,6 +485,7 @@ public class RaceController extends Controller { showAbbrev.setSelected(false); showBoatPath.setSelected(false); showSpeed.setSelected(false); + showTime.setSelected(false); annotationGroup.selectToggle(hideAnnoRBTN); raceMap.update(); buttonChecked = noBtn; @@ -483,6 +498,7 @@ public class RaceController extends Controller { showAbbrev.setSelected(annoShownBeforeHide.get(abbrevCheckAnno)); showBoatPath.setSelected(annoShownBeforeHide.get(pathCheckAnno)); showSpeed.setSelected(annoShownBeforeHide.get(speedCheckAnno)); + showTime.setSelected(annoShownBeforeHide.get(timeCheckAnno)); raceMap.update(); buttonChecked = noBtn; prevBtnChecked = showBtn; @@ -494,7 +510,7 @@ public class RaceController extends Controller { showAbbrev.setSelected(true); showSpeed.setSelected(true); showBoatPath.setSelected(false); - //partialAnnoRBTN.setSelected(true);//as the others will set the show button back to visible then we need to make it so that this is rechecked. + showTime.setSelected(false); annotationGroup.selectToggle(partialAnnoRBTN); raceMap.update(); buttonChecked = noBtn; diff --git a/visualiser/src/main/resources/scenes/race.fxml b/visualiser/src/main/resources/scenes/race.fxml index 8a661e1e..900b731d 100644 --- a/visualiser/src/main/resources/scenes/race.fxml +++ b/visualiser/src/main/resources/scenes/race.fxml @@ -32,14 +32,14 @@ - - -