From a23bdd0c53508c6cf1b50aa9204ec42d53475369 Mon Sep 17 00:00:00 2001 From: Michael Rausch Date: Thu, 11 May 2017 21:42:29 +1200 Subject: [PATCH 1/3] Added functionality to select important annotations and ui changes - Added CSS for the race view & welcome screen - Added view to select important annotations - Annotations are enabled/disabled when the user changes the important annotations Tags: #story[926] --- .../java/seng302/controllers/Controller.java | 9 +- .../ImportantAnnotationController.java | 125 +++++++++++++ .../controllers/RaceViewController.java | 109 ++++++++++-- src/main/resources/css/master.css | 166 ++++++++++++++++++ src/main/resources/views/MainView.fxml | 24 +-- src/main/resources/views/RaceView.fxml | 27 +-- .../views/importantAnnotationSelectView.fxml | 29 +++ 7 files changed, 446 insertions(+), 43 deletions(-) create mode 100644 src/main/java/seng302/controllers/ImportantAnnotationController.java create mode 100644 src/main/resources/css/master.css create mode 100644 src/main/resources/views/importantAnnotationSelectView.fxml diff --git a/src/main/java/seng302/controllers/Controller.java b/src/main/java/seng302/controllers/Controller.java index 9d964243..faa67cc4 100644 --- a/src/main/java/seng302/controllers/Controller.java +++ b/src/main/java/seng302/controllers/Controller.java @@ -18,12 +18,8 @@ import seng302.models.Yacht; import seng302.models.parsers.StreamParser; import seng302.models.parsers.XMLParser; - import java.io.IOException; import java.net.URL; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; import java.util.ResourceBundle; import java.util.Timer; import java.util.TimerTask; @@ -56,6 +52,7 @@ public class Controller implements Initializable { try{ contentPane.getChildren().removeAll(); contentPane.getChildren().clear(); + contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString()); contentPane.getChildren().addAll((Pane) FXMLLoader.load(getClass().getResource(jfxUrl))); } catch(javafx.fxml.LoadException e){ @@ -71,6 +68,8 @@ public class Controller implements Initializable { //DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); //format.setTimeZone(TimeZone.getTimeZone("GMT-8")); //realTime.setText(format.format(new Date())); + contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString()); + teamList.getStylesheets().add(getClass().getResource("/css/master.css").toString()); } /** @@ -138,7 +137,9 @@ public class Controller implements Initializable { private void updateTeamList() { ObservableList data = FXCollections.observableArrayList(); + teamList.setItems(data); + boatNameCol.setCellValueFactory( new PropertyValueFactory<>("boatName") ); diff --git a/src/main/java/seng302/controllers/ImportantAnnotationController.java b/src/main/java/seng302/controllers/ImportantAnnotationController.java new file mode 100644 index 00000000..e1a031cf --- /dev/null +++ b/src/main/java/seng302/controllers/ImportantAnnotationController.java @@ -0,0 +1,125 @@ +package seng302.controllers; + +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Stage; + +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.ResourceBundle; + +public class ImportantAnnotationController implements Initializable { + /* + * JavaFX Outlets + */ + @FXML + private CheckBox boatWakeSelect; + + @FXML + private CheckBox boatSpeedSelect; + + @FXML + private CheckBox boatTrackSelect; + + @FXML + private CheckBox boatNameSelect; + + @FXML + private AnchorPane annotationSelectWindow; + + @FXML + private Button closeButton; + + private RaceViewController parent; + private Map importantAnnotations; + private Stage stage; + + ImportantAnnotationController(RaceViewController parent, Stage stage){ + this.parent = parent; + importantAnnotations = new HashMap<>(); + this.stage = stage; + } + + /** + * Sets whether or not an annotation is considered important + * @param name The annotation name + * @param isSet True if annotation is important + */ + private void setAnnotation(String name, Boolean isSet){ + importantAnnotations.put(name, isSet); + } + + /** + * Sends an update to the parent controller when the important + * annotations have changed + */ + private void sendUpdate(){ + this.parent.importantAnnotationsChanged(this.importantAnnotations); + } + + /** + * Load the current state of the 'important annotations' + * @param currentState hashmap containing the states of each annotation + */ + void loadState(Map currentState){ + this.importantAnnotations = currentState; + + // Initialise checkboxes + for (String key : importantAnnotations.keySet()){ + switch (key){ + case "BoatWake": + boatWakeSelect.setSelected(importantAnnotations.get(key)); + break; + + case "BoatSpeed": + boatSpeedSelect.setSelected(importantAnnotations.get(key)); + break; + + case "BoatTrack": + boatTrackSelect.setSelected(importantAnnotations.get(key)); + break; + + case "BoatName": + boatNameSelect.setSelected(importantAnnotations.get(key)); + break; + + default: + break; + } + } + } + + /** + * View did load + * @param location . + * @param resources . + */ + @Override + public void initialize(URL location, ResourceBundle resources) { + boatWakeSelect.setOnAction(event -> { + setAnnotation("BoatWake", boatWakeSelect.isSelected()); + sendUpdate(); + }); + + 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()); + } +} diff --git a/src/main/java/seng302/controllers/RaceViewController.java b/src/main/java/seng302/controllers/RaceViewController.java index 12069084..433e47a2 100644 --- a/src/main/java/seng302/controllers/RaceViewController.java +++ b/src/main/java/seng302/controllers/RaceViewController.java @@ -1,26 +1,27 @@ package seng302.controllers; -import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer; import javafx.animation.Animation; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; -import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.Slider; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; +import javafx.scene.paint.Paint; import javafx.scene.text.Text; import javafx.stage.Stage; +import javafx.stage.StageStyle; import javafx.util.Duration; import javafx.util.StringConverter; import seng302.models.*; -import seng302.models.parsers.ConfigParser; import seng302.models.parsers.StreamParser; import java.io.IOException; @@ -43,6 +44,8 @@ public class RaceViewController extends Thread{ @FXML private Slider annotationSlider; @FXML + private Button selectAnnotationBtn; + @FXML private CanvasController includedCanvasController; private ArrayList startingBoats = new ArrayList<>(); @@ -52,6 +55,8 @@ public class RaceViewController extends Thread{ private ArrayList boatOrder = new ArrayList<>(); private Race race; private Stage stage; + private Integer annotationLevel; + private Map importantAnnotations = new HashMap<>(); public void initialize() { @@ -79,9 +84,53 @@ public class RaceViewController extends Thread{ // windDirectionText.setText(String.format("%.1f°", windDirection)); // windArrowText.setRotate(windDirection); includedCanvasController.timer.start(); + + selectAnnotationBtn.setOnAction(event -> { + loadSelectAnnotationView(); + }); } + /** + * Important annotations have been changed, update this view + * @param newImportantAnnotations HashMap containing whether or not annotations + * are important + */ + void importantAnnotationsChanged(Map newImportantAnnotations){ + this.importantAnnotations = newImportantAnnotations; + setAnnotations((int)annotationSlider.getValue()); + } + /** + * Loads the "select annotations" view in a new window + */ + private void loadSelectAnnotationView() { + try { + FXMLLoader fxmlLoader = new FXMLLoader(); + Stage stage = new Stage(); + + // Set controller + 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); + scene.getStylesheets().add(getClass().getResource("/css/master.css").toString()); + stage.initStyle(StageStyle.UNDECORATED); + + stage.setScene(scene); + stage.show(); + + controller.loadState(importantAnnotations); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + Map getImportantAnnotations(){ + return importantAnnotations; + } private void initializeSettings() { displayFps = true; @@ -93,13 +142,13 @@ public class RaceViewController extends Thread{ } }); - //SLIFER STUFF BELOW + //SLIDER STUFF BELOW annotationSlider.setLabelFormatter(new StringConverter() { @Override public String toString(Double n) { if (n == 0) return "None"; if (n == 1) return "Low"; - if (n == 2) return "Medium"; + if (n == 2) return "Important"; if (n == 3) return "All"; return "All"; @@ -112,7 +161,7 @@ public class RaceViewController extends Thread{ return 0d; case "Low": return 1d; - case "Medium": + case "Important": return 2d; case "All": return 3d; @@ -303,6 +352,7 @@ public class RaceViewController extends Thread{ 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")); @@ -310,11 +360,17 @@ public class RaceViewController extends Thread{ for (Yacht boat : StreamParser.getBoatsPos().values()) { if (boat.getBoatStatus() == 3) { // 3 is finish status - positionVbox.getChildren().add(new Text(boat.getPosition() + ". " + - boat.getShortName() + " (Finished)")); + Text textToAdd = new Text(boat.getPosition() + ". " + + boat.getShortName() + " (Finished)"); + textToAdd.setFill(Paint.valueOf("#d3d3d3")); + positionVbox.getChildren().add(textToAdd); + } else { - positionVbox.getChildren().add(new Text(boat.getPosition() + ". " + - boat.getShortName() + " ")); + Text textToAdd = new Text(boat.getPosition() + ". " + + boat.getShortName() + " "); + textToAdd.setFill(Paint.valueOf("#d3d3d3")); + textToAdd.setStyle(""); + positionVbox.getChildren().add(textToAdd); } } @@ -401,14 +457,39 @@ public class RaceViewController extends Thread{ } } break; + // Important Annotations case 2: for (RaceObject ro : includedCanvasController.getRaceObjects()) { if(ro instanceof BoatGroup) { BoatGroup bg = (BoatGroup) ro; - bg.setTeamNameObjectVisible(true); - bg.setVelocityObjectVisible(false); - bg.setLineGroupVisible(true); - bg.setWakeVisible(false); + + 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; diff --git a/src/main/resources/css/master.css b/src/main/resources/css/master.css new file mode 100644 index 00000000..81661bfe --- /dev/null +++ b/src/main/resources/css/master.css @@ -0,0 +1,166 @@ +/** +Background colours + */ +.background-blue{ + -fx-background-color: #119796; +} + +.background-dark{ + -fx-background-color: #2C2c36; +} + +/** +Exit button with no background + */ +.clear-exit-btn{ + -fx-background-insets: 0; + -fx-background-color: #119796; + -fx-border-style: none; +} + +/** +Buttons + */ +.blue-ui-btn{ + -fx-background-color: #119796; + -fx-text-fill: #fff; +} + +.text-white { + -fx-text-fill: white !important; + -fx-fill:white !important; +} + +/** +Sliders + */ +.ui-slider .thumb { + -fx-background-color: rgb(60, 60, 60); + -fx-border-radius: 10; + -fx-border-color: darkgray; +} + +.ui-slider .track{ + -fx-background-color: #119796; +} + +.ui-slider .axis{ + -fx-tick-label-fill: white; +} + +.ui-slider .axis .axis-label{ + -fx-text-fill: white; +} + +/** +Checkbox + */ +.ui-checkbox .box{ + -fx-background-color: white; + -fx-graphic:none; + -fx-shape: none; +} + +.ui-checkbox .box .mark{ + -fx-background-image: none; + -fx-image: none; + -fx-graphic: none; + -fx-shape: none; +} + +.ui-checkbox:selected .box{ + -fx-background-color: #119796; + -fx-shape: none; +} + +.ui-checkbox:selected .box .mark{ + -fx-background-color: #119796; + -fx-shape: none; + -fx-graphic: none; +} + +/** +Table + */ +.ui-table{ + -fx-background-color: transparent; +} + +.ui-table:focused{ + -fx-background-color: transparent; +} + +.ui-table .column-header-background{ + -fx-background-color: white +} + +.ui-table .column-header-background .label{ + -fx-background-color: transparent; + -fx-text-fill: black; +} + +.ui-table .column-header { + -fx-background-color: transparent; +} + +.ui-table .table-cell{ + -fx-text-fill: white; + -fx-border-style: none; +} + +.table-row-cell{ + -fx-background-color: #119796; + -fx-background-insets: 0, 0 0 1 0; + -fx-padding: 0.0em; /* 0 */ + -fx-border-style: none; +} + +.table-row-cell:odd{ + -fx-background-color: #0e6d6c; + -fx-background-insets: 0, 0 0 1 0; + -fx-padding: 0.0em; /* 0 */ + -fx-border-style: none; +} + +.table-row-cell:selected { + -fx-background-color: #005797; + -fx-background-insets: 0; + -fx-border-style: none; +} + +/** +Remove scroll bars + */ +.ui-table *.scroll-bar:horizontal *.increment-button, +.ui-table *.scroll-bar:horizontal *.decrement-button { + -fx-background-color: null; + -fx-background-radius: 0; + -fx-background-insets: 0; + -fx-padding: 0; +} + +.ui-table *.scroll-bar:horizontal *.increment-arrow, +.ui-table *.scroll-bar:horizontal *.decrement-arrow { + -fx-background-color: null; + -fx-background-radius: 0; + -fx-background-insets: 0; + -fx-padding: 0; + -fx-shape: null; +} + +.ui-table *.scroll-bar:vertical *.increment-arrow, +.ui-table *.scroll-bar:vertical *.decrement-arrow { + -fx-background-color: null; + -fx-background-radius: 0; + -fx-background-insets: 0; + -fx-padding: 0; + -fx-shape: null; +} + +.ui-table *.scroll-bar:vertical *.increment-button, +.ui-table *.scroll-bar:vertical *.decrement-button { + -fx-background-color: null; + -fx-background-radius: 0; + -fx-background-insets: 0; + -fx-padding: 0; +} \ No newline at end of file diff --git a/src/main/resources/views/MainView.fxml b/src/main/resources/views/MainView.fxml index ac72bd8c..65e7ee7b 100644 --- a/src/main/resources/views/MainView.fxml +++ b/src/main/resources/views/MainView.fxml @@ -9,7 +9,7 @@ - + @@ -18,23 +18,23 @@ - - + + - + From 14d975dce4296d3edcc16fcb53fc8796e45fc90b Mon Sep 17 00:00:00 2001 From: Zhi You Tan Date: Fri, 12 May 2017 17:41:47 +1200 Subject: [PATCH 2/3] Fixed a bug where clicking "watch race" before race starts will cause boats to travel in unexpected ways. #story[923] --- .../java/seng302/controllers/Controller.java | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/main/java/seng302/controllers/Controller.java b/src/main/java/seng302/controllers/Controller.java index faa67cc4..da85b3ae 100644 --- a/src/main/java/seng302/controllers/Controller.java +++ b/src/main/java/seng302/controllers/Controller.java @@ -46,7 +46,7 @@ public class Controller implements Initializable { @FXML private Label realTime; - private XMLParser xmlParser; + private boolean switchedToRaceView = false; private void setContentPane(String jfxUrl){ try{ @@ -65,9 +65,6 @@ public class Controller implements Initializable { @Override public void initialize(URL location, ResourceBundle resources) { - //DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); - //format.setTimeZone(TimeZone.getTimeZone("GMT-8")); - //realTime.setText(format.format(new Date())); contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString()); teamList.getStylesheets().add(getClass().getResource("/css/master.css").toString()); } @@ -77,7 +74,6 @@ public class Controller implements Initializable { */ public void startStream() { if (StreamParser.isStreamStatus()) { - xmlParser = StreamParser.getXmlObject(); streamButton.setVisible(false); realTime.setVisible(true); timeTillLive.setVisible(true); @@ -89,7 +85,9 @@ public class Controller implements Initializable { public void run() { Platform.runLater(() -> { if (StreamParser.isRaceStarted()) { - switchToRaceView(); + if (!switchedToRaceView) { + switchToRaceView(); + } timer.cancel(); } if (StreamParser.isRaceFinished()) { @@ -132,6 +130,7 @@ public class Controller implements Initializable { } public void switchToRaceView() { + switchedToRaceView = true; setContentPane("/views/RaceView.fxml"); } @@ -152,18 +151,8 @@ public class Controller implements Initializable { 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); + data.addAll(StreamParser.getBoatsPos().values()); + teamList.refresh(); } } From ff6bfc95169b5b42fa42e569c2b6a15ef3452751 Mon Sep 17 00:00:00 2001 From: Michael Rausch Date: Sun, 14 May 2017 20:27:25 +1200 Subject: [PATCH 3/3] 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] --- .../controllers/RaceViewController.java | 98 ++++++++++--------- .../controllers/annotations/Annotation.java | 11 +++ .../ImportantAnnotationController.java | 75 ++++++-------- .../ImportantAnnotationDelegate.java | 16 +++ .../ImportantAnnotationsState.java | 52 ++++++++++ src/main/resources/views/MainView.fxml | 2 +- .../TestImportantAnnotationState.java | 53 ++++++++++ 7 files changed, 216 insertions(+), 91 deletions(-) create mode 100644 src/main/java/seng302/controllers/annotations/Annotation.java rename src/main/java/seng302/controllers/{ => annotations}/ImportantAnnotationController.java (51%) create mode 100644 src/main/java/seng302/controllers/annotations/ImportantAnnotationDelegate.java create mode 100644 src/main/java/seng302/controllers/annotations/ImportantAnnotationsState.java create mode 100644 src/test/java/seng302/visualizer/annotations/TestImportantAnnotationState.java diff --git a/src/main/java/seng302/controllers/RaceViewController.java b/src/main/java/seng302/controllers/RaceViewController.java index 433e47a2..24ff0163 100644 --- a/src/main/java/seng302/controllers/RaceViewController.java +++ b/src/main/java/seng302/controllers/RaceViewController.java @@ -21,6 +21,10 @@ import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.util.Duration; 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.parsers.StreamParser; @@ -30,7 +34,7 @@ import java.util.*; /** * Created by ptg19 on 29/03/17. */ -public class RaceViewController extends Thread{ +public class RaceViewController extends Thread implements ImportantAnnotationDelegate{ @FXML private VBox positionVbox; @FXML @@ -55,23 +59,19 @@ public class RaceViewController extends Thread{ private ArrayList boatOrder = new ArrayList<>(); private Race race; private Stage stage; - private Integer annotationLevel; - private Map importantAnnotations = new HashMap<>(); + private ImportantAnnotationsState importantAnnotations; public void initialize() { + // Load a default important annotation state + importantAnnotations = new ImportantAnnotationsState(); RaceController raceController = new RaceController(); raceController.initializeRace(); race = raceController.getRace(); + for (Yacht boat : race.getBoats()) { startingBoats.add(boat); } -// try{ -// initializeTimelines(); -// } -// catch (Exception e){ -// e.printStackTrace(); -// } includedCanvasController.setup(this); includedCanvasController.initializeCanvas(); @@ -91,13 +91,12 @@ public class RaceViewController extends Thread{ } /** - * Important annotations have been changed, update this view - * @param newImportantAnnotations HashMap containing whether or not annotations - * are important + * The important annotations have been changed, update this view + * @param importantAnnotationsState The current state of the selected annotations */ - void importantAnnotationsChanged(Map newImportantAnnotations){ - this.importantAnnotations = newImportantAnnotations; - setAnnotations((int)annotationSlider.getValue()); + public void importantAnnotationsChanged(ImportantAnnotationsState importantAnnotationsState){ + this.importantAnnotations = importantAnnotationsState; + setAnnotations((int)annotationSlider.getValue()); // Refresh the displayed annotations } /** @@ -128,10 +127,6 @@ public class RaceViewController extends Thread{ } } - Map getImportantAnnotations(){ - return importantAnnotations; - } - private void initializeSettings() { displayFps = true; @@ -432,9 +427,43 @@ public class RaceViewController extends Thread{ 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) { switch (annotationLevel) { + // No Annotations case 0: for (RaceObject ro : includedCanvasController.getRaceObjects()) { if(ro instanceof BoatGroup) { @@ -446,6 +475,7 @@ public class RaceViewController extends Thread{ } } break; + // Low Annotations case 1: for (RaceObject ro : includedCanvasController.getRaceObjects()) { if(ro instanceof BoatGroup) { @@ -462,37 +492,11 @@ public class RaceViewController extends Thread{ for (RaceObject ro : includedCanvasController.getRaceObjects()) { if(ro instanceof BoatGroup) { BoatGroup bg = (BoatGroup) ro; - - 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); - } + setBoatGroupImportantAnnotations(bg); } } break; + // All Annotations case 3: for (RaceObject ro : includedCanvasController.getRaceObjects()) { if(ro instanceof BoatGroup) { diff --git a/src/main/java/seng302/controllers/annotations/Annotation.java b/src/main/java/seng302/controllers/annotations/Annotation.java new file mode 100644 index 00000000..eed70162 --- /dev/null +++ b/src/main/java/seng302/controllers/annotations/Annotation.java @@ -0,0 +1,11 @@ +package seng302.controllers.annotations; + +/** + * Annotations the user can select as important + */ +public enum Annotation { + SPEED, + WAKE, + TRACK, + NAME +} diff --git a/src/main/java/seng302/controllers/ImportantAnnotationController.java b/src/main/java/seng302/controllers/annotations/ImportantAnnotationController.java similarity index 51% rename from src/main/java/seng302/controllers/ImportantAnnotationController.java rename to src/main/java/seng302/controllers/annotations/ImportantAnnotationController.java index e1a031cf..0d1585af 100644 --- a/src/main/java/seng302/controllers/ImportantAnnotationController.java +++ b/src/main/java/seng302/controllers/annotations/ImportantAnnotationController.java @@ -1,4 +1,4 @@ -package seng302.controllers; +package seng302.controllers.annotations; import javafx.fxml.FXML; import javafx.fxml.Initializable; @@ -6,6 +6,8 @@ import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.layout.AnchorPane; import javafx.stage.Stage; +import seng302.controllers.RaceViewController; +import seng302.controllers.annotations.Annotation; import java.net.URL; import java.util.HashMap; @@ -34,57 +36,59 @@ public class ImportantAnnotationController implements Initializable { @FXML private Button closeButton; - private RaceViewController parent; - private Map importantAnnotations; + private ImportantAnnotationDelegate delegate; + private ImportantAnnotationsState importantAnnotationsState; private Stage stage; - ImportantAnnotationController(RaceViewController parent, Stage stage){ - this.parent = parent; - importantAnnotations = new HashMap<>(); + public ImportantAnnotationController(ImportantAnnotationDelegate delegate, Stage stage){ + this.delegate = delegate; + importantAnnotationsState = new ImportantAnnotationsState(); this.stage = stage; } /** - * Sets whether or not an annotation is considered important - * @param name The annotation name + * 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(String name, Boolean isSet){ - importantAnnotations.put(name, isSet); + private void setAnnotation(Annotation annotation, Boolean 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 */ private void sendUpdate(){ - this.parent.importantAnnotationsChanged(this.importantAnnotations); + this.delegate.importantAnnotationsChanged(importantAnnotationsState); } /** * Load the current state of the 'important annotations' * @param currentState hashmap containing the states of each annotation */ - void loadState(Map currentState){ - this.importantAnnotations = currentState; + public void loadState(ImportantAnnotationsState currentState){ + this.importantAnnotationsState = currentState; // Initialise checkboxes - for (String key : importantAnnotations.keySet()){ - switch (key){ - case "BoatWake": - boatWakeSelect.setSelected(importantAnnotations.get(key)); + for (Annotation annotation : importantAnnotationsState.getAnnotations()){ + switch (annotation){ + case WAKE: + boatWakeSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation)); break; - case "BoatSpeed": - boatSpeedSelect.setSelected(importantAnnotations.get(key)); + case SPEED: + boatSpeedSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation)); break; - case "BoatTrack": - boatTrackSelect.setSelected(importantAnnotations.get(key)); + case TRACK: + boatTrackSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation)); break; - case "BoatName": - boatNameSelect.setSelected(importantAnnotations.get(key)); + case NAME: + boatNameSelect.setSelected(importantAnnotationsState.getAnnotationState(annotation)); break; default: @@ -100,25 +104,10 @@ public class ImportantAnnotationController implements Initializable { */ @Override public void initialize(URL location, ResourceBundle resources) { - boatWakeSelect.setOnAction(event -> { - setAnnotation("BoatWake", boatWakeSelect.isSelected()); - sendUpdate(); - }); - - boatSpeedSelect.setOnAction(event -> { - setAnnotation("BoatSpeed", boatSpeedSelect.isSelected()); - sendUpdate(); - }); - - boatTrackSelect.setOnAction(event -> { - setAnnotation("BoatTrack", boatTrackSelect.isSelected()); - sendUpdate(); - }); - - boatNameSelect.setOnAction(event -> { - setAnnotation("BoatName", boatNameSelect.isSelected()); - sendUpdate(); - }); + 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())); closeButton.setOnAction(event -> stage.close()); } diff --git a/src/main/java/seng302/controllers/annotations/ImportantAnnotationDelegate.java b/src/main/java/seng302/controllers/annotations/ImportantAnnotationDelegate.java new file mode 100644 index 00000000..ba50726e --- /dev/null +++ b/src/main/java/seng302/controllers/annotations/ImportantAnnotationDelegate.java @@ -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); + + +} diff --git a/src/main/java/seng302/controllers/annotations/ImportantAnnotationsState.java b/src/main/java/seng302/controllers/annotations/ImportantAnnotationsState.java new file mode 100644 index 00000000..5cc97a7f --- /dev/null +++ b/src/main/java/seng302/controllers/annotations/ImportantAnnotationsState.java @@ -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 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(); + } +} diff --git a/src/main/resources/views/MainView.fxml b/src/main/resources/views/MainView.fxml index 65e7ee7b..054dd6cd 100644 --- a/src/main/resources/views/MainView.fxml +++ b/src/main/resources/views/MainView.fxml @@ -57,7 +57,7 @@ -