From 07234ee33a6ad89a532f9daf09f5d17d2ab5ef5d Mon Sep 17 00:00:00 2001 From: Zhi You Tan Date: Thu, 4 May 2017 04:16:16 +1200 Subject: [PATCH] Updated start screen team list to show position in race. Created Yacht class to replace Boat class. Removed Boat class from XMLParser. Removed unused BoatParser.java. #story[572] --- .../java/seng302/controllers/Controller.java | 40 ++++-- src/main/java/seng302/models/Boat.java | 31 ----- src/main/java/seng302/models/Yacht.java | 114 ++++++++++++++++++ .../seng302/models/parsers/BoatsParser.java | 77 ------------ .../seng302/models/parsers/StreamParser.java | 53 ++++++-- .../seng302/models/parsers/XMLParser.java | 73 ++++++----- src/main/resources/views/MainView.fxml | 10 +- 7 files changed, 229 insertions(+), 169 deletions(-) create mode 100644 src/main/java/seng302/models/Yacht.java delete mode 100644 src/main/java/seng302/models/parsers/BoatsParser.java diff --git a/src/main/java/seng302/controllers/Controller.java b/src/main/java/seng302/controllers/Controller.java index b5c5d384..97ee324e 100644 --- a/src/main/java/seng302/controllers/Controller.java +++ b/src/main/java/seng302/controllers/Controller.java @@ -14,6 +14,7 @@ import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; +import seng302.models.Yacht; import seng302.models.parsers.StreamParser; import seng302.models.parsers.XMLParser; @@ -34,16 +35,20 @@ public class Controller implements Initializable { @FXML private Button switchToRaceViewButton; @FXML - private TableView teamList; + private TableView teamList; @FXML - private TableColumn boatNameCol; + private TableColumn boatNameCol; @FXML - private TableColumn shortNameCol; + private TableColumn shortNameCol; @FXML - private TableColumn countryCol; + private TableColumn countryCol; + @FXML + private TableColumn posCol; @FXML private Label realTime; + private XMLParser xmlParser; + private void setContentPane(String jfxUrl){ try{ contentPane.getChildren().removeAll(); @@ -70,7 +75,7 @@ public class Controller implements Initializable { */ public void startStream() { if (StreamParser.isStreamStatus()) { - XMLParser xmlParser = StreamParser.getXmlObject(); + xmlParser = StreamParser.getXmlObject(); streamButton.setVisible(false); realTime.setVisible(true); timeTillLive.setVisible(true); @@ -125,19 +130,32 @@ public class Controller implements Initializable { } private void updateTeamList() { - ObservableList data = FXCollections.observableArrayList(); + ObservableList data = FXCollections.observableArrayList(); teamList.setItems(data); boatNameCol.setCellValueFactory( - new PropertyValueFactory<>("BoatName") + new PropertyValueFactory<>("boatName") ); shortNameCol.setCellValueFactory( - new PropertyValueFactory<>("ShortName") + new PropertyValueFactory<>("shortName") ); countryCol.setCellValueFactory( - new PropertyValueFactory<>("Country") + new PropertyValueFactory<>("country") ); - for (XMLParser.BoatXMLObject.Boat boat : StreamParser.getBoats()) { - data.add(boat); + posCol.setCellValueFactory( + new PropertyValueFactory<>("position") + ); + if (StreamParser.isRaceStarted()) { + data.addAll(StreamParser.getBoatsPos().values()); + } else { + for (Yacht boat : StreamParser.getBoats().values()) { + boat.setPosition("-"); + data.add(boat); + } } + teamList.refresh(); + +// posCol.setSortType(TableColumn.SortType.ASCENDING); +// teamList.getSortOrder().add(posCol); +// posCol.setSortable(false); } } diff --git a/src/main/java/seng302/models/Boat.java b/src/main/java/seng302/models/Boat.java index dc3aa7b7..d275091f 100644 --- a/src/main/java/seng302/models/Boat.java +++ b/src/main/java/seng302/models/Boat.java @@ -21,10 +21,6 @@ public class Boat { private int markLastPast; private String shortName; private int id; - // new attributes to boat - private int sourceID; - private String boatName; - private String country; public Boat(String teamName) { this.teamName = teamName; @@ -49,21 +45,6 @@ public class Boat { this.id = id; } - /** - * New instance created by BoatsParser. - * - * @param sourceID source ID of the boat - * @param boatName full name of the boat - * @param shortName short name of the boat - * @param country country of the boat - */ - public Boat(int sourceID, String boatName, String shortName, String country) { - this.sourceID = sourceID; - this.boatName = boatName; - this.shortName = shortName; - this.country = country; - } - /** * Returns the name of the team sailing the boat * @@ -159,16 +140,4 @@ public class Boat { public int getId() { return id; } - - public int getSourceID() { - return sourceID; - } - - public String getBoatName() { - return boatName; - } - - public String getCountry() { - return country; - } } \ No newline at end of file diff --git a/src/main/java/seng302/models/Yacht.java b/src/main/java/seng302/models/Yacht.java new file mode 100644 index 00000000..9a8959c1 --- /dev/null +++ b/src/main/java/seng302/models/Yacht.java @@ -0,0 +1,114 @@ +package seng302.models; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +/** + * Yacht class for the racing boat. + * + * Class created to store more variables (eg. boat statuses) compared to the XMLParser boat class, + * also done outside Boat class because some old variables are not used anymore. + */ +public class Yacht { + private String boatType; + private Integer sourceID; + private String hullID; //matches HullNum in the XML spec. + private String shortName; + private String boatName; + private String country; + // Boat status + private Integer boatStatus; + private Integer legNumber; + private Integer penaltiesAwarded; + private Integer penaltiesServed; + private Long estimateTimeAtNextMark; + private Long estimateTimeAtFinish; + private String position; + + public Yacht(String boatType, Integer sourceID, String hullID, String shortName, String boatName, String country) { + this.boatType = boatType; + this.sourceID = sourceID; + this.hullID = hullID; + this.shortName = shortName; + this.boatName = boatName; + this.country = country; + } + + public String getBoatType() { + return boatType; + } + public Integer getSourceID() { + return sourceID; + } + public String getHullID() { + return hullID; + } + public String getShortName() { + return shortName; + } + public String getBoatName() { + return boatName; + } + public String getCountry() { + return country; + } + + public Integer getBoatStatus() { + return boatStatus; + } + + public void setBoatStatus(Integer boatStatus) { + this.boatStatus = boatStatus; + } + + public Integer getLegNumber() { + return legNumber; + } + + public void setLegNumber(Integer legNumber) { + this.legNumber = legNumber; + } + + public Integer getPenaltiesAwarded() { + return penaltiesAwarded; + } + + public void setPenaltiesAwarded(Integer penaltiesAwarded) { + this.penaltiesAwarded = penaltiesAwarded; + } + + public Integer getPenaltiesServed() { + return penaltiesServed; + } + + public void setPenaltiesServed(Integer penaltiesServed) { + this.penaltiesServed = penaltiesServed; + } + + public Long getEstimateTimeAtNextMark() { +// DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); +// return format.format(estimateTimeAtNextMark); + return estimateTimeAtNextMark; + } + + public void setEstimateTimeAtNextMark(Long estimateTimeAtNextMark) { + this.estimateTimeAtNextMark = estimateTimeAtNextMark; + } + + public String getEstimateTimeAtFinish() { + DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); + return format.format(estimateTimeAtFinish); + } + + public void setEstimateTimeAtFinish(Long estimateTimeAtFinish) { + this.estimateTimeAtFinish = estimateTimeAtFinish; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } +} diff --git a/src/main/java/seng302/models/parsers/BoatsParser.java b/src/main/java/seng302/models/parsers/BoatsParser.java deleted file mode 100644 index 8180bde8..00000000 --- a/src/main/java/seng302/models/parsers/BoatsParser.java +++ /dev/null @@ -1,77 +0,0 @@ -package seng302.models.parsers; - -import org.w3c.dom.*; -import org.xml.sax.InputSource; -import seng302.models.Boat; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import java.io.InputStream; -import java.io.StringBufferInputStream; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.List; -import java.util.NoSuchElementException; - -/** - * Created by ryan_ on 30/04/2017. - */ -public class BoatsParser extends FileParser { - private Document doc; - - public BoatsParser(String xmlString) { - this.doc = this.parseFile(xmlString); - } - - /** - * Create a boat instance from a given node if 'Type' is 'Yacht' - * - * @param node a boat node - * @return an instance of Boat - */ - private Boat parseBoat(Node node) { - try { - if (node.getNodeType() == Node.ELEMENT_NODE) { - Element element = (Element) node; - if (element.getAttribute("Type").equals("Yacht")) { - String sourceID = element.getAttribute("SourceID"); - String boatName = element.getAttribute("BoatName"); - String shortName = element.getAttribute("ShortName"); - String stoweName = element.getAttribute("StoweName"); - String country = element.getAttribute("Country"); - Boat boat = new Boat(Integer.parseInt(sourceID), boatName, shortName, country); - return boat; - } - } else { - throw new NoSuchElementException("Cannot generate a boat by given node"); - } - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - /** - * Returns a list of boats from the xml. - * - * @return a list of boats - */ - public List getBoats() { - ArrayList boats = new ArrayList<>(); - - try { - NodeList nodes = this.doc.getElementsByTagName("Boat"); - for (int i = 0; i < nodes.getLength(); i++) { - Node node = nodes.item(i); - Boat boat = parseBoat(node); - if (!(boat == null)) { - boats.add(boat); - } - } - return boats; - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } -} diff --git a/src/main/java/seng302/models/parsers/StreamParser.java b/src/main/java/seng302/models/parsers/StreamParser.java index 4fb9e314..642fc608 100644 --- a/src/main/java/seng302/models/parsers/StreamParser.java +++ b/src/main/java/seng302/models/parsers/StreamParser.java @@ -5,6 +5,7 @@ import javafx.geometry.Point3D; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import seng302.models.Yacht; import seng302.models.parsers.packets.BoatPositionPacket; import seng302.models.parsers.packets.StreamPacket; @@ -37,7 +38,8 @@ public class StreamParser extends Thread{ private static boolean raceFinished = false; private static boolean streamStatus = false; private static long timeSinceStart = -1; - private static List boats = new ArrayList<>(); + private static Map boats = new HashMap<>(); + private static Map boatsPos = new TreeMap<>(); private static double windDirection = 0; private static String currentTimeString; @@ -201,17 +203,33 @@ public class StreamParser extends Thread{ long windSpeed = bytesToLong(Arrays.copyOfRange(payload,20,22)); int noBoats = payload[22]; int raceType = payload[23]; - ArrayList boatStatuses = new ArrayList<>(); +// ArrayList boatStatuses = new ArrayList<>(); + boatsPos = new TreeMap<>(); for (int i = 0; i < noBoats; i++){ Long boatStatusSourceID = bytesToLong(Arrays.copyOfRange(payload,24 + (i * 20),28+ (i * 20))); - String boatStatus = "SourceID: " + boatStatusSourceID; - boatStatus += "\nBoat Status: " + (int)payload[28 + (i * 20)]; - boatStatus += "\nLegNumber: " + (int)payload[29 + (i * 20)]; - boatStatus += "\nPenaltiesAwarded: " + (int)payload[29 + (i * 20)]; - boatStatus += "\nPenaltiesServed: " + (int)payload[30 + (i * 20)]; - boatStatus += "\nEstTimeAtNextMark: " + bytesToLong(Arrays.copyOfRange(payload,31 + (i * 20),37+ (i * 20))); - boatStatus += "\nEstTimeAtFinish: " + bytesToLong(Arrays.copyOfRange(payload,37 + (i * 20),43+ (i * 20))); - boatStatuses.add(boatStatus); + Yacht boat = boats.get((int)(long) boatStatusSourceID); + boat.setBoatStatus((int)payload[28 + (i * 20)]); + boat.setLegNumber((int)payload[29 + (i * 20)]); + boat.setPenaltiesAwarded((int)payload[29 + (i * 20)]); + boat.setPenaltiesServed((int)payload[30 + (i * 20)]); + Long estTimeAtNextMark = bytesToLong(Arrays.copyOfRange(payload,31 + (i * 20),37+ (i * 20))); + boat.setEstimateTimeAtNextMark(estTimeAtNextMark); + Long estTimeAtFinish = bytesToLong(Arrays.copyOfRange(payload,37 + (i * 20),43+ (i * 20))); + boat.setEstimateTimeAtFinish(estTimeAtFinish); + boatsPos.put(estTimeAtFinish, boat); +// String boatStatus = "SourceID: " + boatStatusSourceID; +// boatStatus += "\nBoat Status: " + (int)payload[28 + (i * 20)]; +// boatStatus += "\nLegNumber: " + (int)payload[29 + (i * 20)]; +// boatStatus += "\nPenaltiesAwarded: " + (int)payload[29 + (i * 20)]; +// boatStatus += "\nPenaltiesServed: " + (int)payload[30 + (i * 20)]; +// boatStatus += "\nEstTimeAtNextMark: " + bytesToLong(Arrays.copyOfRange(payload,31 + (i * 20),37+ (i * 20))); +// boatStatus += "\nEstTimeAtFinish: " + bytesToLong(Arrays.copyOfRange(payload,37 + (i * 20),43+ (i * 20))); +// boatStatuses.add(boatStatus); + } + int pos = 1; + for (Yacht yacht : boatsPos.values()) { + yacht.setPosition(String.valueOf(pos)); + pos++; } } @@ -478,11 +496,11 @@ public class StreamParser extends Thread{ } /** - * return list of boats from the server + * return a map of boats with sourceID and the boat * - * @return list of boats + * @return map of boats */ - public static List getBoats() { + public static Map getBoats() { return boats; } @@ -513,5 +531,14 @@ public class StreamParser extends Thread{ public static String getCurrentTimeString() { return currentTimeString; } + + /** + * used in boat position since tree map can sort position efficiently. + * + * @return a map of time to finish and boat. + */ + public static Map getBoatsPos() { + return boatsPos; + } } diff --git a/src/main/java/seng302/models/parsers/XMLParser.java b/src/main/java/seng302/models/parsers/XMLParser.java index e9f28a00..f8d30460 100644 --- a/src/main/java/seng302/models/parsers/XMLParser.java +++ b/src/main/java/seng302/models/parsers/XMLParser.java @@ -4,9 +4,12 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import seng302.models.Yacht; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Class to create an XML object from the XML Packet Messages. @@ -392,9 +395,9 @@ public class XMLParser { private ArrayList zoneLimits;// will only contain 5 elements. Limits 1-5 //Boats - ArrayList boats; + ArrayList boats; //Competing boats - List competingBoats = new ArrayList<>(); + Map competingBoats = new HashMap<>(); /** * Constructor for a BoatXMLObject. @@ -427,10 +430,16 @@ public class XMLParser { for (int i = 0; i < boatsList.getLength(); i++) { Node currentBoat = boatsList.item(i); if (currentBoat.getNodeName().equals("Boat")) { - Boat boat = new Boat(currentBoat); +// Boat boat = new Boat(currentBoat); + Yacht boat = new Yacht(getNodeAttributeString(currentBoat, "Type"), + getNodeAttributeInt(currentBoat, "SourceID"), + getNodeAttributeString(currentBoat, "HullNum"), + getNodeAttributeString(currentBoat, "ShortName"), + getNodeAttributeString(currentBoat, "BoatName"), + getNodeAttributeString(currentBoat, "Country")); this.boats.add(boat); if (boat.getBoatType().equals("Yacht")) { - competingBoats.add(boat); + competingBoats.put(boat.getSourceID(), boat); } } //System.out.println(this.getBoats()); @@ -446,37 +455,37 @@ public class XMLParser { public Double getMarkZoneSize() { return markZoneSize; } public Double getCourseZoneSize() { return courseZoneSize; } public ArrayList getZoneLimits() { return zoneLimits; } - public ArrayList getBoats() { return boats; } - public List getCompetingBoats() { + public ArrayList getBoats() { return boats; } + public Map getCompetingBoats() { return competingBoats; } - public class Boat { - - private String boatType; - private Integer sourceID; - private String hullID; //matches HullNum in the XML spec. - private String shortName; - private String boatName; - private String country; - - Boat(Node boatNode) { - this.boatType = getNodeAttributeString(boatNode, "Type"); - this.sourceID = getNodeAttributeInt(boatNode, "SourceID"); - this.hullID = getNodeAttributeString(boatNode, "HullNum"); - this.shortName = getNodeAttributeString(boatNode, "ShortName"); - this.boatName = getNodeAttributeString(boatNode, "BoatName"); - this.country = getNodeAttributeString(boatNode, "Country"); - } - - public String getBoatType() { return boatType; } - public Integer getSourceID() { return sourceID; } - public String getHullID() { return hullID; } - public String getShortName() { return shortName; } - public String getBoatName() { return boatName; } - public String getCountry() { return country; } - - } +// public class Boat { +// +// private String boatType; +// private Integer sourceID; +// private String hullID; //matches HullNum in the XML spec. +// private String shortName; +// private String boatName; +// private String country; +// +// Boat(Node boatNode) { +// this.boatType = getNodeAttributeString(boatNode, "Type"); +// this.sourceID = getNodeAttributeInt(boatNode, "SourceID"); +// this.hullID = getNodeAttributeString(boatNode, "HullNum"); +// this.shortName = getNodeAttributeString(boatNode, "ShortName"); +// this.boatName = getNodeAttributeString(boatNode, "BoatName"); +// this.country = getNodeAttributeString(boatNode, "Country"); +// } +// +// public String getBoatType() { return boatType; } +// public Integer getSourceID() { return sourceID; } +// public String getHullID() { return hullID; } +// public String getShortName() { return shortName; } +// public String getBoatName() { return boatName; } +// public String getCountry() { return country; } +// +// } } diff --git a/src/main/resources/views/MainView.fxml b/src/main/resources/views/MainView.fxml index b12a64c2..ac72bd8c 100644 --- a/src/main/resources/views/MainView.fxml +++ b/src/main/resources/views/MainView.fxml @@ -46,17 +46,17 @@