Merge branch 'develop' into Story47CourseLimits

Conflicts:
	src/main/java/seng302/App.java
This commit is contained in:
Michael Rausch
2017-05-15 18:37:31 +12:00
8 changed files with 307 additions and 267 deletions
@@ -1,6 +1,5 @@
package seng302.controllers;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.beans.value.ChangeListener;
@@ -34,7 +33,8 @@ import java.util.*;
/**
* Created by ptg19 on 29/03/17.
*/
public class RaceViewController extends Thread implements ImportantAnnotationDelegate{
public class RaceViewController extends Thread implements ImportantAnnotationDelegate {
@FXML
private VBox positionVbox;
@FXML
@@ -55,8 +55,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
private ArrayList<Yacht> startingBoats = new ArrayList<>();
private boolean displayFps;
private Timeline timerTimeline;
private Map<Yacht, TimelineInfo> timelineInfos = new HashMap<>();
private ArrayList<Yacht> boatOrder = new ArrayList<>();
private Race race;
private Stage stage;
private ImportantAnnotationsState importantAnnotations;
@@ -79,10 +77,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
initializeSettings();
initialiseWindDirection();
initialisePositionVBox();
//set wind direction!!!!!!! can't find another place to put my code --haoming
// double windDirection = new ConfigParser("/config/config.xml").getWindDirection();
// windDirectionText.setText(String.format("%.1f°", windDirection));
// windArrowText.setRotate(windDirection);
includedCanvasController.timer.start();
selectAnnotationBtn.setOnAction(event -> {
@@ -92,11 +86,12 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
/**
* The important annotations have been changed, update this view
*
* @param importantAnnotationsState The current state of the selected annotations
*/
public void importantAnnotationsChanged(ImportantAnnotationsState importantAnnotationsState){
public void importantAnnotationsChanged(ImportantAnnotationsState importantAnnotationsState) {
this.importantAnnotations = importantAnnotationsState;
setAnnotations((int)annotationSlider.getValue()); // Refresh the displayed annotations
setAnnotations((int) annotationSlider.getValue()); // Refresh the displayed annotations
}
/**
@@ -108,12 +103,14 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
Stage stage = new Stage();
// Set controller
ImportantAnnotationController controller = new ImportantAnnotationController(this, stage);
ImportantAnnotationController controller = new ImportantAnnotationController(this,
stage);
fxmlLoader.setController(controller);
// Load FXML and set CSS
fxmlLoader.setLocation(getClass().getResource("/views/importantAnnotationSelectView.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 469, 248);
fxmlLoader
.setLocation(getClass().getResource("/views/importantAnnotationSelectView.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 469, 270);
scene.getStylesheets().add(getClass().getResource("/css/master.css").toString());
stage.initStyle(StageStyle.UNDECORATED);
@@ -132,7 +129,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
toggleFps.selectedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue,
Boolean newValue) {
displayFps = !displayFps;
}
});
@@ -141,10 +139,18 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
annotationSlider.setLabelFormatter(new StringConverter<Double>() {
@Override
public String toString(Double n) {
if (n == 0) return "None";
if (n == 1) return "Low";
if (n == 2) return "Important";
if (n == 3) return "All";
if (n == 0) {
return "None";
}
if (n == 1) {
return "Low";
}
if (n == 2) {
return "Important";
}
if (n == 3) {
return "All";
}
return "All";
}
@@ -168,25 +174,25 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
});
annotationSlider.valueProperty().addListener((obs, oldval, newVal) ->
setAnnotations((int)annotationSlider.getValue()));
setAnnotations((int) annotationSlider.getValue()));
annotationSlider.setValue(3);
}
private void initializeTimer(){
private void initializeTimer() {
timerTimeline = new Timeline();
timerTimeline.setCycleCount(Timeline.INDEFINITE);
// Run timer update every second
timerTimeline.getKeyFrames().add(
new KeyFrame(Duration.seconds(1),
event -> {
if (StreamParser.isRaceFinished()) {
timerLabel.setFill(Color.RED);
timerLabel.setText("Race Finished!");
} else {
timerLabel.setText(currentTimer());
}
})
new KeyFrame(Duration.seconds(1),
event -> {
if (StreamParser.isRaceFinished()) {
timerLabel.setFill(Color.RED);
timerLabel.setText("Race Finished!");
} else {
timerLabel.setText(currentTimer());
}
})
);
// Start the timer
@@ -197,11 +203,12 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
Timeline windDirTimeline = new Timeline();
windDirTimeline.setCycleCount(Timeline.INDEFINITE);
windDirTimeline.getKeyFrames().add(
new KeyFrame(Duration.seconds(1),
event -> {
windDirectionText.setText(String.format("%.1f°", StreamParser.getWindDirection()));
windArrowText.setRotate(StreamParser.getWindDirection());
})
new KeyFrame(Duration.seconds(1),
event -> {
windDirectionText
.setText(String.format("%.1f°", StreamParser.getWindDirection()));
windArrowText.setRotate(StreamParser.getWindDirection());
})
);
windDirTimeline.playFromStart();
}
@@ -211,106 +218,15 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
Timeline posVBoxTimeline = new Timeline();
posVBoxTimeline.setCycleCount(Timeline.INDEFINITE);
posVBoxTimeline.getKeyFrames().add(
new KeyFrame(Duration.seconds(1),
event -> {
showOrder();
})
new KeyFrame(Duration.seconds(1),
event -> {
showOrder();
})
);
posVBoxTimeline.playFromStart();
}
/**
* Generates time line for each boat, and stores time time into timelineInfos hash map
*/
private void initializeTimelines() {
HashMap<Yacht, List> boat_events = race.getEvents();
for (Yacht boat : boat_events.keySet()) {
startingBoats.add(boat);
// // x, y are the real time coordinates
// DoubleProperty x = new SimpleDoubleProperty();
// DoubleProperty y = new SimpleDoubleProperty();
//
// List<KeyFrame> keyFrames = new ArrayList<>();
// List<Event> events = boat_events.get(boat);
//
// // iterates all events and convert each event to keyFrame, then add them into a list
// for (Event event : events) {
// if (event.getIsFinishingEvent()) {
// keyFrames.add(
// new KeyFrame(Duration.seconds(event.getTime()),
// onFinished -> {race.setBoatFinished(boat); handleEvent(event);},
// new KeyValue(x, event.getThisMark().getLatitude()),
// new KeyValue(y, event.getThisMark().getLongitude())
// )
// );
// } else {
// keyFrames.add(
// new KeyFrame(Duration.seconds(event.getTime()),
// onFinished ->{
// handleEvent(event);
// boat.setHeading(event.getBoatHeading());
// },
// new KeyValue(x, event.getThisMark().getLatitude()),
// new KeyValue(y, event.getThisMark().getLongitude())
// )
// );
// }
// }
// timelineInfos.put(boat, new TimelineInfo(new Timeline(keyFrames.toArray(new KeyFrame[keyFrames.size()])), x, y));
}
setRaceDuration();
}
private void setRaceDuration(){
Double maxDuration = 0.0;
Timeline maxTimeline = null;
for (TimelineInfo timelineInfo : timelineInfos.values()) {
Timeline timeline = timelineInfo.getTimeline();
if (timeline.getTotalDuration().toMillis() >= maxDuration) {
maxDuration = timeline.getTotalDuration().toMillis();
maxTimeline = timeline;
}
// Timelines are paused by default
timeline.play();
timeline.pause();
}
maxTimeline.setOnFinished(event -> {
race.setRaceFinished();
loadRaceResultView();
});
}
/**
* Play each boats timerTimeline
*/
public void playTimelines(){
for (TimelineInfo timelineInfo : timelineInfos.values()){
Timeline timeline = timelineInfo.getTimeline();
if (timeline.getStatus() == Animation.Status.PAUSED){
timeline.play();
}
}
}
/**
* Pause each boats timerTimeline
*/
public void pauseTimelines(){
for (TimelineInfo timelineInfo : timelineInfos.values()){
Timeline timeline = timelineInfo.getTimeline();
if (timeline.getStatus() == Animation.Status.RUNNING){
timeline.pause();
}
}
}
/**
* Display the list of boats in the order they finished the race
*/
@@ -330,39 +246,21 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
}
}
public void handleEvent(Event event) {
Yacht boat = event.getBoat();
boatOrder.remove(boat);
boat.setMarkLastPast(event.getMarkPosInRace());
boatOrder.add(boat);
boatOrder.sort(new Comparator<Yacht>() {
@Override
public int compare(Yacht b1, Yacht b2) {
return b2.getMarkLastPast() - b1.getMarkLastPast();
}
});
showOrder();
}
private void showOrder() {
positionVbox.getChildren().clear();
positionVbox.getChildren().removeAll();
positionVbox.getStylesheets().add(getClass().getResource("/css/master.css").toString());
// for (Boat boat : boatOrder) {
// positionVbox.getChildren().add(new Text(boat.getShortName() + " " + boat.getSpeedInKnots() + " Knots"));
// }
for (Yacht boat : StreamParser.getBoatsPos().values()) {
if (boat.getBoatStatus() == 3) { // 3 is finish status
Text textToAdd = new Text(boat.getPosition() + ". " +
boat.getShortName() + " (Finished)");
boat.getShortName() + " (Finished)");
textToAdd.setFill(Paint.valueOf("#d3d3d3"));
positionVbox.getChildren().add(textToAdd);
} else {
Text textToAdd = new Text(boat.getPosition() + ". " +
boat.getShortName() + " ");
boat.getShortName() + " ");
textToAdd.setFill(Paint.valueOf("#d3d3d3"));
textToAdd.setStyle("");
positionVbox.getChildren().add(textToAdd);
@@ -407,6 +305,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
public void stopTimer() {
timerTimeline.stop();
}
public void startTimer() {
timerTimeline.play();
}
@@ -419,46 +318,51 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
return race;
}
public Map<Yacht, TimelineInfo> getTimelineInfos() {
return timelineInfos;
}
public ArrayList<Yacht> getStartingBoats(){
public ArrayList<Yacht> getStartingBoats() {
return startingBoats;
}
/**
* Display the important annotations for a specific BoatGroup
*
* @param bg The boat group to set the annotations for
*/
private void setBoatGroupImportantAnnotations(BoatGroup bg){
if (importantAnnotations.getAnnotationState(Annotation.NAME)){
private void setBoatGroupImportantAnnotations(BoatGroup bg) {
if (importantAnnotations.getAnnotationState(Annotation.NAME)) {
bg.setTeamNameObjectVisible(true);
}
else{
} else {
bg.setTeamNameObjectVisible(false);
}
if (importantAnnotations.getAnnotationState(Annotation.SPEED)){
if (importantAnnotations.getAnnotationState(Annotation.SPEED)) {
bg.setVelocityObjectVisible(true);
}
else{
} else {
bg.setVelocityObjectVisible(false);
}
if (importantAnnotations.getAnnotationState(Annotation.TRACK)){
if (importantAnnotations.getAnnotationState(Annotation.TRACK)) {
bg.setLineGroupVisible(true);
}
else{
} else {
bg.setLineGroupVisible(false);
}
if (importantAnnotations.getAnnotationState(Annotation.WAKE)){
if (importantAnnotations.getAnnotationState(Annotation.WAKE)) {
bg.setWakeVisible(true);
}
else{
} else {
bg.setWakeVisible(false);
}
if (importantAnnotations.getAnnotationState(Annotation.ESTTIMETONEXTMARK)) {
bg.setEstTimeToNextMarkObjectVisible(true);
} else {
bg.setEstTimeToNextMarkObjectVisible(false);
}
if (importantAnnotations.getAnnotationState(Annotation.LEGTIME)) {
bg.setLegTimeObjectVisible(true);
} else {
bg.setLegTimeObjectVisible(false);
}
}
private void setAnnotations(Integer annotationLevel) {
@@ -466,10 +370,12 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
// No Annotations
case 0:
for (RaceObject ro : includedCanvasController.getRaceObjects()) {
if(ro instanceof BoatGroup) {
if (ro instanceof BoatGroup) {
BoatGroup bg = (BoatGroup) ro;
bg.setTeamNameObjectVisible(false);
bg.setVelocityObjectVisible(false);
bg.setEstTimeToNextMarkObjectVisible(false);
bg.setLegTimeObjectVisible(false);
bg.setLineGroupVisible(false);
bg.setWakeVisible(false);
}
@@ -478,10 +384,12 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
// Low Annotations
case 1:
for (RaceObject ro : includedCanvasController.getRaceObjects()) {
if(ro instanceof BoatGroup) {
if (ro instanceof BoatGroup) {
BoatGroup bg = (BoatGroup) ro;
bg.setTeamNameObjectVisible(true);
bg.setVelocityObjectVisible(false);
bg.setEstTimeToNextMarkObjectVisible(false);
bg.setLegTimeObjectVisible(false);
bg.setLineGroupVisible(false);
bg.setWakeVisible(false);
}
@@ -490,7 +398,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
// Important Annotations
case 2:
for (RaceObject ro : includedCanvasController.getRaceObjects()) {
if(ro instanceof BoatGroup) {
if (ro instanceof BoatGroup) {
BoatGroup bg = (BoatGroup) ro;
setBoatGroupImportantAnnotations(bg);
}
@@ -499,10 +407,12 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
// All Annotations
case 3:
for (RaceObject ro : includedCanvasController.getRaceObjects()) {
if(ro instanceof BoatGroup) {
if (ro instanceof BoatGroup) {
BoatGroup bg = (BoatGroup) ro;
bg.setTeamNameObjectVisible(true);
bg.setVelocityObjectVisible(true);
bg.setEstTimeToNextMarkObjectVisible(true);
bg.setLegTimeObjectVisible(true);
bg.setLineGroupVisible(true);
bg.setWakeVisible(true);
}
@@ -511,11 +421,11 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
}
}
void setStage (Stage stage) {
void setStage(Stage stage) {
this.stage = stage;
}
Stage getStage () {
Stage getStage() {
return stage;
}
}
@@ -7,5 +7,7 @@ public enum Annotation {
SPEED,
WAKE,
TRACK,
NAME
NAME,
ESTTIMETONEXTMARK,
LEGTIME
}
@@ -15,6 +15,7 @@ import java.util.Map;
import java.util.ResourceBundle;
public class ImportantAnnotationController implements Initializable {
/*
* JavaFX Outlets
*/
@@ -30,6 +31,12 @@ public class ImportantAnnotationController implements Initializable {
@FXML
private CheckBox boatNameSelect;
@FXML
private CheckBox boatEstTimeToNextMarkSelect;
@FXML
private CheckBox boatElapsedTimeSelect;
@FXML
private AnchorPane annotationSelectWindow;
@@ -40,7 +47,7 @@ public class ImportantAnnotationController implements Initializable {
private ImportantAnnotationsState importantAnnotationsState;
private Stage stage;
public ImportantAnnotationController(ImportantAnnotationDelegate delegate, Stage stage){
public ImportantAnnotationController(ImportantAnnotationDelegate delegate, Stage stage) {
this.delegate = delegate;
importantAnnotationsState = new ImportantAnnotationsState();
this.stage = stage;
@@ -49,10 +56,11 @@ public class ImportantAnnotationController implements Initializable {
/**
* Sets whether or not an annotation is considered important, then
* sends an update to the delegate
*
* @param annotation The annotation
* @param isSet True if annotation is important
*/
private void setAnnotation(Annotation annotation, Boolean isSet){
private void setAnnotation(Annotation annotation, Boolean isSet) {
importantAnnotationsState.setAnnotationState(annotation, isSet);
sendUpdate();
}
@@ -61,36 +69,50 @@ public class ImportantAnnotationController implements Initializable {
* Sends an update to the delegate when the important
* annotations have changed
*/
private void sendUpdate(){
private void sendUpdate() {
this.delegate.importantAnnotationsChanged(importantAnnotationsState);
}
/**
* Load the current state of the 'important annotations'
*
* @param currentState hashmap containing the states of each annotation
*/
public void loadState(ImportantAnnotationsState currentState){
public void loadState(ImportantAnnotationsState currentState) {
this.importantAnnotationsState = currentState;
// Initialise checkboxes
for (Annotation annotation : importantAnnotationsState.getAnnotations()){
switch (annotation){
for (Annotation annotation : importantAnnotationsState.getAnnotations()) {
switch (annotation) {
case WAKE:
boatWakeSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation));
boatWakeSelect
.setSelected(importantAnnotationsState.getAnnotationState(annotation));
break;
case SPEED:
boatSpeedSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation));
boatSpeedSelect
.setSelected(importantAnnotationsState.getAnnotationState(annotation));
break;
case TRACK:
boatTrackSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation));
boatTrackSelect
.setSelected(importantAnnotationsState.getAnnotationState(annotation));
break;
case NAME:
boatNameSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation));
boatNameSelect
.setSelected(importantAnnotationsState.getAnnotationState(annotation));
break;
case ESTTIMETONEXTMARK:
boatEstTimeToNextMarkSelect
.setSelected(importantAnnotationsState.getAnnotationState(annotation));
break;
case LEGTIME:
boatElapsedTimeSelect
.setSelected(importantAnnotationsState.getAnnotationState(annotation));
default:
break;
}
@@ -99,15 +121,24 @@ public class ImportantAnnotationController implements Initializable {
/**
* View did load
*
* @param location .
* @param resources .
*/
@Override
public void initialize(URL location, ResourceBundle resources) {
boatWakeSelect.setOnAction(event -> setAnnotation(Annotation.WAKE, boatWakeSelect.isSelected()));
boatSpeedSelect.setOnAction(event -> setAnnotation(Annotation.SPEED, boatSpeedSelect.isSelected()));
boatTrackSelect.setOnAction(event -> setAnnotation(Annotation.TRACK, boatTrackSelect.isSelected()));
boatNameSelect.setOnAction(event -> setAnnotation(Annotation.NAME, boatNameSelect.isSelected()));
boatWakeSelect
.setOnAction(event -> setAnnotation(Annotation.WAKE, boatWakeSelect.isSelected()));
boatSpeedSelect
.setOnAction(event -> setAnnotation(Annotation.SPEED, boatSpeedSelect.isSelected()));
boatTrackSelect
.setOnAction(event -> setAnnotation(Annotation.TRACK, boatTrackSelect.isSelected()));
boatNameSelect
.setOnAction(event -> setAnnotation(Annotation.NAME, boatNameSelect.isSelected()));
boatEstTimeToNextMarkSelect.setOnAction(event -> setAnnotation(Annotation.ESTTIMETONEXTMARK,
boatEstTimeToNextMarkSelect.isSelected()));
boatElapsedTimeSelect.setOnAction(
event -> setAnnotation(Annotation.LEGTIME, boatElapsedTimeSelect.isSelected()));
closeButton.setOnAction(event -> stage.close());
}