mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Implemented observer and strategy pattern in BoatAnnotations, now renamed AnnotationsBox.
Also implemented various other small fixes and further refactored code. #refactor
This commit is contained in:
@@ -1,16 +1,21 @@
|
||||
package seng302.visualiser.controllers;
|
||||
|
||||
import com.sun.javafx.collections.SortableList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.Scene;
|
||||
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import javafx.scene.chart.XYChart;
|
||||
import javafx.scene.chart.XYChart.Data;
|
||||
import javafx.scene.chart.XYChart.Series;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.CheckBox;
|
||||
@@ -35,8 +40,8 @@ import seng302.visualiser.controllers.annotations.Annotation;
|
||||
import seng302.visualiser.controllers.annotations.ImportantAnnotationController;
|
||||
import seng302.visualiser.controllers.annotations.ImportantAnnotationDelegate;
|
||||
import seng302.visualiser.controllers.annotations.ImportantAnnotationsState;
|
||||
import seng302.visualiser.fxObjects.BoatGroup;
|
||||
import seng302.visualiser.fxObjects.MarkGroup;
|
||||
import seng302.visualiser.fxObjects.BoatObject;
|
||||
import seng302.visualiser.fxObjects.MarkObject;
|
||||
import seng302.model.*;
|
||||
import seng302.model.mark.GateMark;
|
||||
import seng302.model.mark.Mark;
|
||||
@@ -45,15 +50,14 @@ import seng302.model.stream.parsers.StreamParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import seng302.model.stream.parsers.xml.XMLParser.RaceXMLObject.Participant;
|
||||
|
||||
/**
|
||||
* Created by ptg19 on 29/03/17.
|
||||
* Controller class that manages the display of a race
|
||||
*/
|
||||
public class RaceViewController extends Thread implements ImportantAnnotationDelegate {
|
||||
|
||||
@FXML
|
||||
private LineChart raceSparkLine;
|
||||
private LineChart<String, Double> raceSparkLine;
|
||||
@FXML
|
||||
private NumberAxis sparklineYAxis;
|
||||
@FXML
|
||||
@@ -75,15 +79,14 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
|
||||
//Race Data
|
||||
private Map<Integer, Boat> participants;
|
||||
private Map<Integer, Mark> course;
|
||||
private RaceXMLData raceData;
|
||||
private Map<Integer, Mark> markers;
|
||||
private RaceXMLData courseData;
|
||||
private GameView gameView;
|
||||
private RaceState raceState;
|
||||
|
||||
private Timeline timerTimeline;
|
||||
private Stage stage;
|
||||
private HashMap<Integer, Series<String, Double>> sparkLineData = new HashMap<>();
|
||||
private ImportantAnnotationsState importantAnnotations;
|
||||
private Boat selectedBoat;
|
||||
|
||||
public void initialize() {
|
||||
// Load a default important annotation state
|
||||
@@ -96,20 +99,26 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
raceSparkLine.getYAxis().setAutoRanging(false);
|
||||
sparklineYAxis.setTickMarkVisible(false);
|
||||
|
||||
selectAnnotationBtn.setOnAction(event -> loadSelectAnnotationView());
|
||||
}
|
||||
|
||||
public void loadRace (Map<Integer, Boat> participants, RaceXMLData raceData, RaceState raceState) {
|
||||
this.participants = participants;
|
||||
this.courseData = raceData;
|
||||
this.markers = raceData.getCompoundMarks();
|
||||
this.raceState = raceState;
|
||||
|
||||
initializeUpdateTimer();
|
||||
initialiseFPSCheckBox();
|
||||
initialiseAnnotationSlider();
|
||||
initialiseBoatSelectionComboBox();
|
||||
|
||||
selectAnnotationBtn.setOnAction(event -> loadSelectAnnotationView());
|
||||
}
|
||||
|
||||
public void loadRace (Map<Integer, Boat> participants, RaceXMLData raceData) {
|
||||
this.participants = participants;
|
||||
this.raceData = raceData;
|
||||
this.course = raceData.getCompoundMarks();
|
||||
gameView = new GameView();
|
||||
gameView.setBoats(new ArrayList<>(participants.values()));
|
||||
gameView.updateBorder(raceData.getCourseLimit());
|
||||
gameView.updateCourse(new ArrayList<>(raceData.getCompoundMarks().values()));
|
||||
gameView.startRace();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,7 +178,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
if (n == 2) {
|
||||
return "All";
|
||||
}
|
||||
|
||||
return "All";
|
||||
}
|
||||
|
||||
@@ -189,7 +197,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
}
|
||||
});
|
||||
|
||||
annotationSlider.valueProperty().addListener((obs, oldval, newVal) ->
|
||||
annotationSlider.valueProperty().addListener((obs, oldVal, newVal) ->
|
||||
setAnnotations((int) annotationSlider.getValue())
|
||||
);
|
||||
annotationSlider.setValue(2);
|
||||
@@ -202,10 +210,11 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
private void updateSparkLine(){
|
||||
// Collect the racing boats that aren't already in the chart
|
||||
List<Boat> sparkLineCandidates = new ArrayList<>();
|
||||
participants.forEach((id, boat) ->{
|
||||
if (!sparkLineData.containsKey(id) && boat.getPosition() != null && !boat.getPosition().equals("-"))
|
||||
sparkLineCandidates.add(boat);
|
||||
});
|
||||
// participants.forEach((id, boat) ->{
|
||||
// if (!sparkLineData.containsKey(id) && boat.getPosition() != null && !boat.getPosition().equals("-"))
|
||||
// sparkLineCandidates.add(boat);
|
||||
// });
|
||||
participants.forEach((id, boat) -> sparkLineCandidates.add(boat));
|
||||
|
||||
sparklineYAxis.setUpperBound(participants.size() + 1);
|
||||
|
||||
@@ -213,13 +222,18 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
sparkLineCandidates.stream().filter(yacht -> yacht.getPosition() != null).forEach(yacht -> {
|
||||
Series<String, Double> yachtData = new Series<>();
|
||||
yachtData.setName(yacht.getSourceID().toString());
|
||||
yachtData.getData().add(new XYChart.Data<>(Integer.toString(yacht.getLegNumber()), 1 + participants.size() - Double.parseDouble(yacht.getPosition())));
|
||||
yachtData.getData().add(
|
||||
new XYChart.Data<>(
|
||||
Integer.toString(yacht.getLegNumber()),
|
||||
1.0 + participants.size() - yacht.getPosition()
|
||||
)
|
||||
);
|
||||
sparkLineData.put(yacht.getSourceID(), yachtData);
|
||||
});
|
||||
|
||||
// Lambda function to sort the series in order of leg (later legs shown more to the right)
|
||||
List<XYChart.Series<String, Double>> positions = new ArrayList<>(sparkLineData.values());
|
||||
Collections.sort(positions, (o1, o2) -> {
|
||||
positions.sort((o1, o2) -> {
|
||||
Integer leg1 = Integer.parseInt(o1.getData().get(o1.getData().size()-1).getXValue());
|
||||
Integer leg2 = Integer.parseInt(o2.getData().get(o2.getData().size()-1).getXValue());
|
||||
if (leg2 < leg1){
|
||||
@@ -247,13 +261,21 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
* @param legNumber the leg number that the position will be assigned to
|
||||
*/
|
||||
public void updateYachtPositionSparkline(Boat boat, Integer legNumber){
|
||||
XYChart.Series<String, Double> positionData = sparkLineData.get(boat.getSourceID());
|
||||
positionData.getData().add(
|
||||
new XYChart.Data<>(
|
||||
Integer.toString(legNumber),
|
||||
1 + participants.size() - Double.parseDouble(boat.getPosition())
|
||||
)
|
||||
);
|
||||
for (XYChart.Series<String, Double> positionData : sparkLineData.values()) {
|
||||
positionData.getData().add(
|
||||
new Data<>(
|
||||
Integer.toString(legNumber),
|
||||
1.0 + participants.size() - boat.getPosition()
|
||||
)
|
||||
);
|
||||
}
|
||||
// XYChart.Series<String, Double> positionData = sparkLineData.get(boat.getSourceID());
|
||||
// positionData.getData().add(
|
||||
// new XYChart.Data<>(
|
||||
// Integer.toString(legNumber),
|
||||
// 1.0 + participants.size() - boat.getPosition()
|
||||
// )
|
||||
// );
|
||||
}
|
||||
|
||||
|
||||
@@ -306,10 +328,10 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
* @param bg The BoatGroup to find the next mark of
|
||||
* @return The next Mark or null if none found
|
||||
*/
|
||||
private Mark getNextMark(BoatGroup bg) {
|
||||
private Mark getNextMark(BoatObject bg) {
|
||||
|
||||
Integer legNumber = bg.getBoat().getLegNumber();
|
||||
List<Corner> markSequence = raceData.getMarkSequence();
|
||||
List<Corner> markSequence = courseData.getMarkSequence();
|
||||
|
||||
if (legNumber == 0) {
|
||||
return null;
|
||||
@@ -319,7 +341,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
|
||||
for (Corner corner : markSequence) {
|
||||
if (legNumber + 2 == corner.getSeqID()) {
|
||||
return raceData.getCompoundMarks().get(corner.getCompoundMarkID());
|
||||
return courseData.getCompoundMarks().get(corner.getCompoundMarkID());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -330,8 +352,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
* Updates the wind direction arrow and text as from info from the StreamParser
|
||||
*/
|
||||
private void updateWindDirection() {
|
||||
windDirectionText.setText(String.format("%.1f°", StreamParser.getWindDirection()));
|
||||
windArrowText.setRotate(StreamParser.getWindDirection());
|
||||
windDirectionText.setText(String.format("%.1f°", raceState.getWindDirection()));
|
||||
windArrowText.setRotate(raceState.getWindDirection());
|
||||
}
|
||||
|
||||
|
||||
@@ -339,26 +361,14 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
* Updates the clock for the race
|
||||
*/
|
||||
private void updateRaceTime() {
|
||||
if (StreamParser.isRaceFinished()) {
|
||||
if (!raceState.isRaceStarted()) {
|
||||
timerLabel.setFill(Color.RED);
|
||||
timerLabel.setText("Race Finished!");
|
||||
} else {
|
||||
timerLabel.setText(getTimeSinceStartOfRace());
|
||||
timerLabel.setText(raceState.getRaceTimeStr());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Grabs the boats currently in the race as from the StreamParser and sets them to be selectable
|
||||
* in the boat selection combo box
|
||||
*/
|
||||
private void updateBoatSelectionComboBox() {
|
||||
ObservableList<Boat> observableBoats = FXCollections.observableArrayList();
|
||||
observableBoats.addAll(participants.values());
|
||||
boatSelectionComboBox.setItems(observableBoats);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the order of the boats as from the StreamParser and sets them in the boat order
|
||||
* section
|
||||
@@ -369,101 +379,98 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
positionVbox.getStylesheets().add(getClass().getResource("/css/master.css").toString());
|
||||
|
||||
// list of racing boat id
|
||||
List<Boat> sorted = new ArrayList<>(participants.values());
|
||||
sorted.sort(Comparator.comparingInt(Boat::getPosition));
|
||||
|
||||
if (StreamParser.isRaceStarted()) {
|
||||
for (Boat boat : StreamParser.getBoatsPos().values()) {
|
||||
if (participantIDs.contains(boat.getSourceID())) { // check if the boat is racing
|
||||
if (boat.getBoatStatus() == 3) { // 3 is finish status
|
||||
Text textToAdd = new Text(boat.getPosition() + ". " +
|
||||
boat.getShortName() + " (Finished)");
|
||||
textToAdd.setFill(Paint.valueOf("#d3d3d3"));
|
||||
positionVbox.getChildren().add(textToAdd);
|
||||
for (Boat boat : sorted) {
|
||||
if (boat.getBoatStatus() == 3) { // 3 is finish status
|
||||
Text textToAdd = new Text(boat.getPosition() + ". " +
|
||||
boat.getShortName() + " (Finished)");
|
||||
textToAdd.setFill(Paint.valueOf("#d3d3d3"));
|
||||
positionVbox.getChildren().add(textToAdd);
|
||||
|
||||
} else {
|
||||
Text textToAdd = new Text(boat.getPosition() + ". " +
|
||||
boat.getShortName() + " ");
|
||||
textToAdd.setFill(Paint.valueOf("#d3d3d3"));
|
||||
textToAdd.setStyle("");
|
||||
positionVbox.getChildren().add(textToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
participants.forEach((id, boat) ->{
|
||||
} else {
|
||||
Text textToAdd = new Text(boat.getPosition() + ". " +
|
||||
boat.getShortName() + " ");
|
||||
textToAdd.setFill(Paint.valueOf("#d3d3d3"));
|
||||
textToAdd.setStyle("");
|
||||
positionVbox.getChildren().add(textToAdd);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void updateLaylines(BoatGroup bg) {
|
||||
|
||||
Mark nextMark = getNextMark(bg);
|
||||
Boolean isUpwind = null;
|
||||
// Can only calc leg direction if there is a next mark and it is a gate mark
|
||||
if (nextMark != null) {
|
||||
if (nextMark instanceof GateMark) {
|
||||
if (bg.isUpwindLeg(gameViewController, nextMark)) {
|
||||
isUpwind = true;
|
||||
} else {
|
||||
isUpwind = false;
|
||||
}
|
||||
|
||||
for(MarkGroup mg : gameViewController.getMarkGroups()) {
|
||||
|
||||
mg.removeLaylines();
|
||||
|
||||
if (mg.getMainMark().getId() == nextMark.getId()) {
|
||||
|
||||
SingleMark singleMark1 = ((GateMark) nextMark).getSingleMark1();
|
||||
SingleMark singleMark2 = ((GateMark) nextMark).getSingleMark2();
|
||||
Point2D markPoint1 = gameViewController
|
||||
.findScaledXY(singleMark1.getLatitude(), singleMark1.getLongitude());
|
||||
Point2D markPoint2 = gameViewController
|
||||
.findScaledXY(singleMark2.getLatitude(), singleMark2.getLongitude());
|
||||
HashMap<Double, Double> angleAndSpeed;
|
||||
if (isUpwind) {
|
||||
angleAndSpeed = PolarTable.getOptimalUpwindVMG(StreamParser.getWindSpeed());
|
||||
} else {
|
||||
angleAndSpeed = PolarTable.getOptimalDownwindVMG(StreamParser.getWindSpeed());
|
||||
}
|
||||
|
||||
Double resultingAngle = angleAndSpeed.keySet().iterator().next();
|
||||
|
||||
|
||||
Point2D boatCurrentPos = new Point2D(bg.getBoatLayoutX(), bg.getBoatLayoutY());
|
||||
Point2D gateMidPoint = markPoint1.midpoint(markPoint2);
|
||||
Integer lineFuncResult = GeoUtility.lineFunction(boatCurrentPos, gateMidPoint, markPoint2);
|
||||
Line rightLayline = new Line();
|
||||
Line leftLayline = new Line();
|
||||
if (lineFuncResult == 1) {
|
||||
rightLayline = makeRightLayline(markPoint2, 180 - resultingAngle, StreamParser.getWindDirection());
|
||||
leftLayline = makeLeftLayline(markPoint1, 180 - resultingAngle, StreamParser.getWindDirection());
|
||||
} else if (lineFuncResult == -1) {
|
||||
rightLayline = makeRightLayline(markPoint1, 180 - resultingAngle, StreamParser.getWindDirection());
|
||||
leftLayline = makeLeftLayline(markPoint2, 180 - resultingAngle, StreamParser.getWindDirection());
|
||||
}
|
||||
|
||||
leftLayline.setStrokeWidth(0.5);
|
||||
leftLayline.setStroke(bg.getBoat().getColour());
|
||||
|
||||
rightLayline.setStrokeWidth(0.5);
|
||||
rightLayline.setStroke(bg.getBoat().getColour());
|
||||
|
||||
bg.setLaylines(leftLayline, rightLayline);
|
||||
mg.addLaylines(leftLayline, rightLayline);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// participants.forEach((id, boat) ->{
|
||||
// Text textToAdd = new Text(boat.getPosition() + ". " +
|
||||
// boat.getShortName() + " ");
|
||||
// textToAdd.setFill(Paint.valueOf("#d3d3d3"));
|
||||
// textToAdd.setStyle("");
|
||||
// positionVbox.getChildren().add(textToAdd);
|
||||
// });
|
||||
}
|
||||
|
||||
|
||||
// private void updateLaylines(BoatObject bg) {
|
||||
//
|
||||
// Mark nextMark = getNextMark(bg);
|
||||
// Boolean isUpwind = null;
|
||||
// // Can only calc leg direction if there is a next mark and it is a gate mark
|
||||
// if (nextMark != null) {
|
||||
// if (nextMark instanceof GateMark) {
|
||||
// if (bg.isUpwindLeg(gameViewController, nextMark)) {
|
||||
// isUpwind = true;
|
||||
// } else {
|
||||
// isUpwind = false;
|
||||
// }
|
||||
//
|
||||
// for(MarkObject mg : gameViewController.getMarkGroups()) {
|
||||
//
|
||||
// mg.removeLaylines();
|
||||
//
|
||||
// if (mg.getMainMark().getId() == nextMark.getId()) {
|
||||
//
|
||||
// SingleMark singleMark1 = ((GateMark) nextMark).getSingleMark1();
|
||||
// SingleMark singleMark2 = ((GateMark) nextMark).getSingleMark2();
|
||||
// Point2D markPoint1 = gameViewController
|
||||
// .findScaledXY(singleMark1.getLatitude(), singleMark1.getLongitude());
|
||||
// Point2D markPoint2 = gameViewController
|
||||
// .findScaledXY(singleMark2.getLatitude(), singleMark2.getLongitude());
|
||||
// HashMap<Double, Double> angleAndSpeed;
|
||||
// if (isUpwind) {
|
||||
// angleAndSpeed = PolarTable.getOptimalUpwindVMG(StreamParser.getWindSpeed());
|
||||
// } else {
|
||||
// angleAndSpeed = PolarTable.getOptimalDownwindVMG(StreamParser.getWindSpeed());
|
||||
// }
|
||||
//
|
||||
// Double resultingAngle = angleAndSpeed.keySet().iterator().next();
|
||||
//
|
||||
//
|
||||
// Point2D boatCurrentPos = new Point2D(bg.getBoatLayoutX(), bg.getBoatLayoutY());
|
||||
// Point2D gateMidPoint = markPoint1.midpoint(markPoint2);
|
||||
// Integer lineFuncResult = GeoUtility.lineFunction(boatCurrentPos, gateMidPoint, markPoint2);
|
||||
// Line rightLayline = new Line();
|
||||
// Line leftLayline = new Line();
|
||||
// if (lineFuncResult == 1) {
|
||||
// rightLayline = makeRightLayline(markPoint2, 180 - resultingAngle, StreamParser.getWindDirection());
|
||||
// leftLayline = makeLeftLayline(markPoint1, 180 - resultingAngle, StreamParser.getWindDirection());
|
||||
// } else if (lineFuncResult == -1) {
|
||||
// rightLayline = makeRightLayline(markPoint1, 180 - resultingAngle, StreamParser.getWindDirection());
|
||||
// leftLayline = makeLeftLayline(markPoint2, 180 - resultingAngle, StreamParser.getWindDirection());
|
||||
// }
|
||||
//
|
||||
// leftLayline.setStrokeWidth(0.5);
|
||||
// leftLayline.setStroke(bg.getBoat().getColour());
|
||||
//
|
||||
// rightLayline.setStrokeWidth(0.5);
|
||||
// rightLayline.setStroke(bg.getBoat().getColour());
|
||||
//
|
||||
// bg.setLaylines(leftLayline, rightLayline);
|
||||
// mg.addLaylines(leftLayline, rightLayline);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
private Point2D getPointRotation(Point2D ref, Double distance, Double angle){
|
||||
Double newX = ref.getX() + (ref.getX() + distance -ref.getX())*Math.cos(angle) - (ref.getY() + distance -ref.getY())*Math.sin(angle);
|
||||
Double newY = ref.getY() + (ref.getX() + distance -ref.getX())*Math.sin(angle) + (ref.getY() + distance -ref.getY())*Math.cos(angle);
|
||||
@@ -495,17 +502,27 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
* for the combobox to take action upon selection
|
||||
*/
|
||||
private void initialiseBoatSelectionComboBox() {
|
||||
updateBoatSelectionComboBox();
|
||||
boatSelectionComboBox.valueProperty().addListener((observable, oldValue, newValue) -> {
|
||||
//This listener is fired whenever the combo box changes. This means when the values are updated
|
||||
//We dont want to set the selected value if the values are updated but nothing clicked (null)
|
||||
if (newValue != null && newValue != selectedBoat) {
|
||||
Boat thisBoat = (Boat) newValue;
|
||||
setSelectedBoat(thisBoat);
|
||||
boatSelectionComboBox.setItems(
|
||||
FXCollections.observableArrayList(participants.values())
|
||||
);
|
||||
//Null check is if the listener is fired but nothing selected
|
||||
boatSelectionComboBox.valueProperty().addListener((obs, lastSelection, selectedBoat) -> {
|
||||
if (selectedBoat != null) {
|
||||
gameView.selectBoat(selectedBoat);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the boats currently in the race as from the StreamParser and sets them to be selectable
|
||||
* in the boat selection combo box
|
||||
*/
|
||||
private void updateBoatSelectionComboBox() {
|
||||
ObservableList<Boat> observableBoats = FXCollections.observableArrayList();
|
||||
observableBoats.addAll(participants.values());
|
||||
boatSelectionComboBox.setItems(observableBoats);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display the list of boats in the order they finished the race
|
||||
@@ -525,38 +542,12 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
private String getTimeSinceStartOfRace() {
|
||||
String timerString = "0:00";
|
||||
if (StreamParser.getTimeSinceStart() > 0) {
|
||||
String timerMinute = Long.toString(StreamParser.getTimeSinceStart() / 60);
|
||||
String timerSecond = Long.toString(StreamParser.getTimeSinceStart() % 60);
|
||||
if (timerSecond.length() == 1) {
|
||||
timerSecond = "0" + timerSecond;
|
||||
}
|
||||
timerString = "-" + timerMinute + ":" + timerSecond;
|
||||
} else {
|
||||
String timerMinute = Long.toString(-1 * StreamParser.getTimeSinceStart() / 60);
|
||||
String timerSecond = Long.toString(-1 * StreamParser.getTimeSinceStart() % 60);
|
||||
if (timerSecond.length() == 1) {
|
||||
timerSecond = "0" + timerSecond;
|
||||
}
|
||||
timerString = timerMinute + ":" + timerSecond;
|
||||
}
|
||||
return timerString;
|
||||
private String getMillisToFormattedTime(long milliseconds) {
|
||||
return String.format("%02d:%02d:%02d",
|
||||
TimeUnit.MILLISECONDS.toHours(milliseconds),
|
||||
TimeUnit.MILLISECONDS.toMinutes(milliseconds) % 60, //Modulus 60 minutes per hour
|
||||
TimeUnit.MILLISECONDS.toSeconds(milliseconds) % 60 //Modulus 60 seconds per minute
|
||||
);
|
||||
}
|
||||
|
||||
private void setAnnotations(Integer annotationLevel) {
|
||||
@@ -594,38 +585,21 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
* @param boat The yacht for which we want to view all annotations
|
||||
*/
|
||||
private void setSelectedBoat(Boat boat) {
|
||||
for (BoatGroup bg : gameViewController.getBoatGroups()) {
|
||||
//We need to iterate over all race groups to get the matching boat group belonging to this boat if we
|
||||
//are to toggle its annotations, there is no other backwards knowledge of a yacht to its boatgroup.
|
||||
if (bg.getBoat().getHullID().equals(boat.getHullID())) {
|
||||
updateLaylines(bg);
|
||||
bg.setIsSelected(true);
|
||||
selectedBoat = boat;
|
||||
} else {
|
||||
bg.setIsSelected(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setStage(Stage stage) {
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
Stage getStage() {
|
||||
return stage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for when the boat attempts to add data to the sparkline (first checks if the sparkline contains info on it)
|
||||
* @param yachtId
|
||||
* @return
|
||||
*/
|
||||
public static boolean sparkLineStatus(Integer yachtId) {
|
||||
return sparkLineData.containsKey(yachtId);
|
||||
// for (BoatObject bg : gameViewController.getBoatGroups()) {
|
||||
// //We need to iterate over all race groups to get the matching boat group belonging to this boat if we
|
||||
// //are to toggle its annotations, there is no other backwards knowledge of a yacht to its boatgroup.
|
||||
// if (bg.getBoat().getHullID().equals(boat.getHullID())) {
|
||||
//// updateLaylines(bg);
|
||||
// bg.setIsSelected(true);
|
||||
//// selectedBoat = boat;
|
||||
// } else {
|
||||
// bg.setIsSelected(false);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public void updateRaceData (RaceXMLData raceData) {
|
||||
this.raceData = raceData;
|
||||
this.courseData = raceData;
|
||||
gameView.updateBorder(raceData.getCourseLimit());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user