Merge branch 'develop' into story33_add_estimated_time_annotation

# Conflicts:
#	src/main/java/seng302/controllers/RaceViewController.java
This commit is contained in:
Zhi You Tan
2017-05-15 10:19:58 +12:00
7 changed files with 217 additions and 92 deletions
@@ -21,6 +21,10 @@ import javafx.stage.Stage;
import javafx.stage.StageStyle; import javafx.stage.StageStyle;
import javafx.util.Duration; import javafx.util.Duration;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import seng302.controllers.annotations.Annotation;
import seng302.controllers.annotations.ImportantAnnotationController;
import seng302.controllers.annotations.ImportantAnnotationDelegate;
import seng302.controllers.annotations.ImportantAnnotationsState;
import seng302.models.*; import seng302.models.*;
import seng302.models.parsers.StreamParser; import seng302.models.parsers.StreamParser;
@@ -30,7 +34,7 @@ import java.util.*;
/** /**
* Created by ptg19 on 29/03/17. * Created by ptg19 on 29/03/17.
*/ */
public class RaceViewController extends Thread{ public class RaceViewController extends Thread implements ImportantAnnotationDelegate{
@FXML @FXML
private VBox positionVbox; private VBox positionVbox;
@FXML @FXML
@@ -53,14 +57,16 @@ public class RaceViewController extends Thread{
private Timeline timerTimeline; private Timeline timerTimeline;
private Race race; private Race race;
private Stage stage; private Stage stage;
private Integer annotationLevel; private ImportantAnnotationsState importantAnnotations;
private Map<String, Boolean> importantAnnotations = new HashMap<>();
public void initialize() { public void initialize() {
// Load a default important annotation state
importantAnnotations = new ImportantAnnotationsState();
RaceController raceController = new RaceController(); RaceController raceController = new RaceController();
raceController.initializeRace(); raceController.initializeRace();
race = raceController.getRace(); race = raceController.getRace();
for (Yacht boat : race.getBoats()) { for (Yacht boat : race.getBoats()) {
startingBoats.add(boat); startingBoats.add(boat);
} }
@@ -79,13 +85,12 @@ public class RaceViewController extends Thread{
} }
/** /**
* Important annotations have been changed, update this view * The important annotations have been changed, update this view
* @param newImportantAnnotations HashMap containing whether or not annotations * @param importantAnnotationsState The current state of the selected annotations
* are important
*/ */
void importantAnnotationsChanged(Map<String, Boolean> newImportantAnnotations){ public void importantAnnotationsChanged(ImportantAnnotationsState importantAnnotationsState){
this.importantAnnotations = newImportantAnnotations; this.importantAnnotations = importantAnnotationsState;
setAnnotations((int)annotationSlider.getValue()); setAnnotations((int)annotationSlider.getValue()); // Refresh the displayed annotations
} }
/** /**
@@ -116,10 +121,6 @@ public class RaceViewController extends Thread{
} }
} }
Map<String, Boolean> getImportantAnnotations(){
return importantAnnotations;
}
private void initializeSettings() { private void initializeSettings() {
displayFps = true; displayFps = true;
@@ -307,8 +308,43 @@ public class RaceViewController extends Thread{
return startingBoats; 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)){
bg.setTeamNameObjectVisible(true);
}
else{
bg.setTeamNameObjectVisible(false);
}
if (importantAnnotations.getAnnotationState(Annotation.SPEED)){
bg.setVelocityObjectVisible(true);
}
else{
bg.setVelocityObjectVisible(false);
}
if (importantAnnotations.getAnnotationState(Annotation.TRACK)){
bg.setLineGroupVisible(true);
}
else{
bg.setLineGroupVisible(false);
}
if (importantAnnotations.getAnnotationState(Annotation.WAKE)){
bg.setWakeVisible(true);
}
else{
bg.setWakeVisible(false);
}
}
private void setAnnotations(Integer annotationLevel) { private void setAnnotations(Integer annotationLevel) {
switch (annotationLevel) { switch (annotationLevel) {
// No Annotations
case 0: case 0:
for (RaceObject ro : includedCanvasController.getRaceObjects()) { for (RaceObject ro : includedCanvasController.getRaceObjects()) {
if(ro instanceof BoatGroup) { if(ro instanceof BoatGroup) {
@@ -321,6 +357,7 @@ public class RaceViewController extends Thread{
} }
} }
break; break;
// Low Annotations
case 1: case 1:
for (RaceObject ro : includedCanvasController.getRaceObjects()) { for (RaceObject ro : includedCanvasController.getRaceObjects()) {
if(ro instanceof BoatGroup) { if(ro instanceof BoatGroup) {
@@ -338,44 +375,11 @@ public class RaceViewController extends Thread{
for (RaceObject ro : includedCanvasController.getRaceObjects()) { for (RaceObject ro : includedCanvasController.getRaceObjects()) {
if(ro instanceof BoatGroup) { if(ro instanceof BoatGroup) {
BoatGroup bg = (BoatGroup) ro; BoatGroup bg = (BoatGroup) ro;
setBoatGroupImportantAnnotations(bg);
if (importantAnnotations.containsKey("BoatName") && importantAnnotations.get("BoatName")){
bg.setTeamNameObjectVisible(true);
}
else{
bg.setTeamNameObjectVisible(false);
}
if (importantAnnotations.containsKey("BoatSpeed") && importantAnnotations.get("BoatSpeed")){
bg.setVelocityObjectVisible(true);
}
else{
bg.setVelocityObjectVisible(false);
}
if (importantAnnotations.containsKey("BoatEstTimeToNextMark") && importantAnnotations.get("BoatEstTimeToNextMark")) {
bg.setEstTimeToNextMarkVisible(true);
}
else{
bg.setEstTimeToNextMarkVisible(false);
}
if (importantAnnotations.containsKey("BoatTrack") && importantAnnotations.get("BoatTrack")){
bg.setLineGroupVisible(true);
}
else{
bg.setLineGroupVisible(false);
}
if (importantAnnotations.containsKey("BoatWake") && importantAnnotations.get("BoatWake")){
bg.setWakeVisible(true);
}
else{
bg.setWakeVisible(false);
}
} }
} }
break; break;
// All Annotations
case 3: case 3:
for (RaceObject ro : includedCanvasController.getRaceObjects()) { for (RaceObject ro : includedCanvasController.getRaceObjects()) {
if(ro instanceof BoatGroup) { if(ro instanceof BoatGroup) {
@@ -0,0 +1,11 @@
package seng302.controllers.annotations;
/**
* Annotations the user can select as important
*/
public enum Annotation {
SPEED,
WAKE,
TRACK,
NAME
}
@@ -1,4 +1,4 @@
package seng302.controllers; package seng302.controllers.annotations;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
@@ -6,6 +6,8 @@ import javafx.scene.control.Button;
import javafx.scene.control.CheckBox; import javafx.scene.control.CheckBox;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage; import javafx.stage.Stage;
import seng302.controllers.RaceViewController;
import seng302.controllers.annotations.Annotation;
import java.net.URL; import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
@@ -37,57 +39,59 @@ public class ImportantAnnotationController implements Initializable {
@FXML @FXML
private Button closeButton; private Button closeButton;
private RaceViewController parent; private ImportantAnnotationDelegate delegate;
private Map<String, Boolean> importantAnnotations; private ImportantAnnotationsState importantAnnotationsState;
private Stage stage; private Stage stage;
ImportantAnnotationController(RaceViewController parent, Stage stage){ public ImportantAnnotationController(ImportantAnnotationDelegate delegate, Stage stage){
this.parent = parent; this.delegate = delegate;
importantAnnotations = new HashMap<>(); importantAnnotationsState = new ImportantAnnotationsState();
this.stage = stage; this.stage = stage;
} }
/** /**
* Sets whether or not an annotation is considered important * Sets whether or not an annotation is considered important, then
* @param name The annotation name * sends an update to the delegate
* @param annotation The annotation
* @param isSet True if annotation is important * @param isSet True if annotation is important
*/ */
private void setAnnotation(String name, Boolean isSet){ private void setAnnotation(Annotation annotation, Boolean isSet){
importantAnnotations.put(name, isSet); importantAnnotationsState.setAnnotationState(annotation, isSet);
sendUpdate();
} }
/** /**
* Sends an update to the parent controller when the important * Sends an update to the delegate when the important
* annotations have changed * annotations have changed
*/ */
private void sendUpdate(){ private void sendUpdate(){
this.parent.importantAnnotationsChanged(this.importantAnnotations); this.delegate.importantAnnotationsChanged(importantAnnotationsState);
} }
/** /**
* Load the current state of the 'important annotations' * Load the current state of the 'important annotations'
* @param currentState hashmap containing the states of each annotation * @param currentState hashmap containing the states of each annotation
*/ */
void loadState(Map<String, Boolean> currentState){ public void loadState(ImportantAnnotationsState currentState){
this.importantAnnotations = currentState; this.importantAnnotationsState = currentState;
// Initialise checkboxes // Initialise checkboxes
for (String key : importantAnnotations.keySet()){ for (Annotation annotation : importantAnnotationsState.getAnnotations()){
switch (key){ switch (annotation){
case "BoatWake": case WAKE:
boatWakeSelect.setSelected(importantAnnotations.get(key)); boatWakeSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation));
break; break;
case "BoatSpeed": case SPEED:
boatSpeedSelect.setSelected(importantAnnotations.get(key)); boatSpeedSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation));
break; break;
case "BoatTrack": case TRACK:
boatTrackSelect.setSelected(importantAnnotations.get(key)); boatTrackSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation));
break; break;
case "BoatName": case NAME:
boatNameSelect.setSelected(importantAnnotations.get(key)); boatNameSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation));
break; break;
case "BoatEstTimeToNextMark": case "BoatEstTimeToNextMark":
@@ -107,25 +111,10 @@ public class ImportantAnnotationController implements Initializable {
*/ */
@Override @Override
public void initialize(URL location, ResourceBundle resources) { public void initialize(URL location, ResourceBundle resources) {
boatWakeSelect.setOnAction(event -> { boatWakeSelect.setOnAction(event -> setAnnotation(Annotation.WAKE, boatWakeSelect.isSelected()));
setAnnotation("BoatWake", boatWakeSelect.isSelected()); boatSpeedSelect.setOnAction(event -> setAnnotation(Annotation.SPEED, boatSpeedSelect.isSelected()));
sendUpdate(); boatTrackSelect.setOnAction(event -> setAnnotation(Annotation.TRACK, boatTrackSelect.isSelected()));
}); boatNameSelect.setOnAction(event -> setAnnotation(Annotation.NAME, boatNameSelect.isSelected()));
boatSpeedSelect.setOnAction(event -> {
setAnnotation("BoatSpeed", boatSpeedSelect.isSelected());
sendUpdate();
});
boatTrackSelect.setOnAction(event -> {
setAnnotation("BoatTrack", boatTrackSelect.isSelected());
sendUpdate();
});
boatNameSelect.setOnAction(event -> {
setAnnotation("BoatName", boatNameSelect.isSelected());
sendUpdate();
});
boatEstTimeToNextMarkSelect.setOnAction(event -> { boatEstTimeToNextMarkSelect.setOnAction(event -> {
setAnnotation("BoatEstTimeToNextMark", boatEstTimeToNextMarkSelect.isSelected()); setAnnotation("BoatEstTimeToNextMark", boatEstTimeToNextMarkSelect.isSelected());
@@ -0,0 +1,16 @@
package seng302.controllers.annotations;
/**
* An ImportantAnnotationDelegate handles updating the important annotations
* displayed to the user on behalf of the ImportantAnnotationController
*/
public interface ImportantAnnotationDelegate {
/**
* The important annotations have been changed, update the
* annotations displayed to the user
* @param importantAnnotationsState The current state of the selected annotations
*/
void importantAnnotationsChanged(ImportantAnnotationsState importantAnnotationsState);
}
@@ -0,0 +1,52 @@
package seng302.controllers.annotations;
import java.util.HashMap;
import java.util.Map;
public class ImportantAnnotationsState {
public static final Boolean DEFAULT_ANNOTATION_STATE = true;
private Map<Annotation, Boolean> currentState;
/**
* Stores the users preference for the annotations
* they consider to be important
*/
public ImportantAnnotationsState(){
this.currentState = new HashMap<>();
initialiseState();
}
/**
* Set each annotation to the default annotation state
*/
private void initialiseState(){
for (Annotation annotation : getAnnotations()){
currentState.put(annotation, DEFAULT_ANNOTATION_STATE);
}
}
/**
* Sets the state (visibility) of an annotation
* @param annotation The annotation to set
* @param visible Whether or not the annotation should be visible
*/
public void setAnnotationState(Annotation annotation, Boolean visible){
this.currentState.put(annotation, visible);
}
/**
* Returns the state (visibility) of a specific annotation
* @param annotation The annotation to check
* @return True if visible, else false
*/
public Boolean getAnnotationState(Annotation annotation){
return this.currentState.containsKey(annotation) && this.currentState.get(annotation);
}
/**
* @return Return an array containing all defined annotations
*/
public Annotation[] getAnnotations(){
return Annotation.class.getEnumConstants();
}
}
+1 -1
View File
@@ -57,7 +57,7 @@
<Insets top="10.0" /> <Insets top="10.0" />
</GridPane.margin> </GridPane.margin>
</TableView> </TableView>
<Label fx:id="realTime" text="Local time" visible="false" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="BOTTOM" /> <Label fx:id="realTime" text="Local time" textFill="WHITE" visible="false" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="BOTTOM" />
</children> </children>
</GridPane> </GridPane>
</children> </children>
@@ -0,0 +1,53 @@
package seng302.visualizer.annotations;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import seng302.controllers.annotations.Annotation;
import seng302.controllers.annotations.ImportantAnnotationsState;
import static org.junit.Assert.assertEquals;
public class TestImportantAnnotationState {
private ImportantAnnotationsState importantAnnotationsState;
@Before
public void setUpForTest(){
importantAnnotationsState = new ImportantAnnotationsState();
}
@After
public void tearDownAfterTest(){
importantAnnotationsState = null;
}
/**
* Check whether each annotation has its default value set to the default value when
* the class is initialized
*/
@Test
public void testDefaultValueSet(){
for (Annotation annotation : importantAnnotationsState.getAnnotations()){
assertEquals(ImportantAnnotationsState.DEFAULT_ANNOTATION_STATE,
importantAnnotationsState.getAnnotationState(annotation));
}
}
/**
* Check whether an annotations state can be changed
*/
@Test
public void testAnnotationStateChange(){
Annotation[] annotations = importantAnnotationsState.getAnnotations();
// do not run test if there are no annotations
if (annotations.length <= 0){
return;
}
Boolean currentAnnotationState = importantAnnotationsState.getAnnotationState(annotations[0]);
importantAnnotationsState.setAnnotationState(annotations[0], !currentAnnotationState);
assertEquals(!currentAnnotationState, importantAnnotationsState.getAnnotationState(annotations[0]));
}
}