mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Important annotations are displayed correctly when updated.
- Important annotations can be selected, the live view updates in real time - Change local time text colour to white - Split the important annotations state into a separate class Tags: #story[926]
This commit is contained in:
@@ -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
|
||||||
@@ -55,23 +59,19 @@ public class RaceViewController extends Thread{
|
|||||||
private ArrayList<Yacht> boatOrder = new ArrayList<>();
|
private ArrayList<Yacht> boatOrder = new ArrayList<>();
|
||||||
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);
|
||||||
}
|
}
|
||||||
// try{
|
|
||||||
// initializeTimelines();
|
|
||||||
// }
|
|
||||||
// catch (Exception e){
|
|
||||||
// e.printStackTrace();
|
|
||||||
// }
|
|
||||||
|
|
||||||
includedCanvasController.setup(this);
|
includedCanvasController.setup(this);
|
||||||
includedCanvasController.initializeCanvas();
|
includedCanvasController.initializeCanvas();
|
||||||
@@ -91,13 +91,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
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,10 +127,6 @@ public class RaceViewController extends Thread{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Boolean> getImportantAnnotations(){
|
|
||||||
return importantAnnotations;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeSettings() {
|
private void initializeSettings() {
|
||||||
displayFps = true;
|
displayFps = true;
|
||||||
|
|
||||||
@@ -432,9 +427,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) {
|
||||||
@@ -446,6 +475,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) {
|
||||||
@@ -462,37 +492,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.setTeamNameObjectVisible(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
|
||||||
|
}
|
||||||
+32
-43
@@ -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;
|
||||||
@@ -34,57 +36,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;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -100,25 +104,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();
|
|
||||||
});
|
|
||||||
|
|
||||||
closeButton.setOnAction(event -> stage.close());
|
closeButton.setOnAction(event -> stage.close());
|
||||||
}
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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]));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user