Controllers and Fxml nicely refactored, tests still broken #story[463]

This commit is contained in:
Peter
2017-03-29 14:59:37 +13:00
parent 4a6978ff79
commit a95d030817
21 changed files with 225 additions and 424 deletions
@@ -1,33 +1,19 @@
package seng302.controllers;
import javafx.animation.*;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.NodeOrientation;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.util.Duration;
import seng302.models.Boat;
import seng302.models.Event;
import seng302.models.Race;
import seng302.models.TimelineInfo;
import seng302.models.mark.GateMark;
import seng302.models.mark.Mark;
import seng302.models.mark.MarkType;
import seng302.models.mark.SingleMark;
import seng302.models.parsers.ConfigParser;
import java.io.IOException;
import java.util.*;
/**
@@ -39,28 +25,26 @@ public class CanvasController {
@FXML
private AnchorPane canvasPane;
private RaceViewController raceViewController;
private ResizableCanvas canvas;
private Race race;
private GraphicsContext gc;
private HashMap<Boat, TimelineInfo> timelineInfos;
private Animation.Status raceStatus = Animation.Status.PAUSED;
///test
private HashSet<Integer> headingTest = new HashSet<>();
private final double ORIGIN_LAT = 32.321504;
private final double ORIGIN_LON = -64.857063;
private final int SCALE = 16000;
public void setup(RaceViewController raceViewController){
this.raceViewController = raceViewController;
}
public void initialize() {
canvas = new ResizableCanvas();
canvasPane.getChildren().add(canvas);
// Bind canvas size to stack pane size.
canvas.widthProperty().bind(
canvasPane.widthProperty());
canvas.heightProperty().bind(
canvasPane.heightProperty());
canvas.widthProperty().bind(canvasPane.widthProperty());
canvas.heightProperty().bind(canvasPane.heightProperty());
gc = canvas.getGraphicsContext2D();
//
// timelineInfos = new HashMap<>();
// overriding the handle so that it can clean canvas and redraw boats and course marks
AnimationTimer timer = new AnimationTimer() {
@@ -80,13 +64,12 @@ public class CanvasController {
drawFps(lastFpsCount);
// If race has started, draw the boats and play the timeline
if (race.getRaceTime() > 1){
playTimelines();
if (raceViewController.getRace().getRaceTime() > 1){
raceViewController.playTimelines();
}
// Race has not started, pause the timelines
else if (race.getRaceTime() < 1 || raceStatus == Animation.Status.RUNNING){
pauseTimelines();
else {
raceViewController.pauseTimelines();
}
lastUpdate = now;
fpsCount ++;
@@ -98,44 +81,7 @@ public class CanvasController {
}
}
};
try{
generateTimelines();
}
catch (Exception e){
e.printStackTrace();
}
timer.start();
loadTimerView();
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();
raceStatus = Animation.Status.RUNNING;
}
maxTimeline.setOnFinished(event -> {
race.setRaceFinished();
loadRaceResultView();
});
//set wind direction!!!!!!! can't find another place to put my code --haoming
double windDirection = new ConfigParser("/config.xml").getWindDirection();
windDirectionText.setText(String.format("%.1f°", windDirection));
windArrowText.setRotate(windDirection);
}
class ResizableCanvas extends Canvas {
@@ -170,98 +116,8 @@ public class CanvasController {
}
}
/**
* Display the list of boats in the order they finished the race
*/
private void loadRaceResultView() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/FinishView.fxml"));
loader.setController(new RaceResultController(race));
try {
contentAnchorPane.getChildren().removeAll();
contentAnchorPane.getChildren().clear();
contentAnchorPane.getChildren().addAll((Pane) loader.load());
} catch (javafx.fxml.LoadException e) {
System.err.println(e.getCause());
} catch (IOException e) {
System.err.println(e);
}
}
/**
* Play each boats timeline
*/
private void playTimelines(){
for (TimelineInfo timelineInfo : timelineInfos.values()){
Timeline timeline = timelineInfo.getTimeline();
if (timeline.getStatus() == Animation.Status.PAUSED){
timeline.play();
}
}
raceStatus = Animation.Status.RUNNING;
}
/**
* Pause each boats timeline
*/
private void pauseTimelines(){
for (TimelineInfo timelineInfo : timelineInfos.values()){
Timeline timeline = timelineInfo.getTimeline();
if (timeline.getStatus() == Animation.Status.RUNNING){
timeline.pause();
}
}
raceStatus = Animation.Status.PAUSED;
}
/**
* Generates time line for each boat, and stores time time into timelineInfos hash map
*/
private void generateTimelines() {
HashMap<Boat, List> boat_events = race.getEvents();
for (Boat boat : boat_events.keySet()) {
// 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() / 60 / 60 / 5),
onFinished -> {race.setBoatFinished(boat); teamPositionsController.handleEvent(event);},
new KeyValue(x, event.getThisMark().getLatitude()),
new KeyValue(y, event.getThisMark().getLongitude())
)
);
} else {
keyFrames.add(
new KeyFrame(Duration.seconds(event.getTime() / 60 / 60 / 5),
onFinished ->{
teamPositionsController.handleEvent(event);
boat.setHeading(event.getBoatHeading());
},
new KeyValue(x, event.getThisMark().getLatitude()),
new KeyValue(y, event.getThisMark().getLongitude())
)
);
}
}
// uses the lists generated above to create a Timeline for the boat.
timelineInfos.put(boat, new TimelineInfo(new Timeline(keyFrames.toArray(new KeyFrame[keyFrames.size()])), x, y));
}
}
private void drawFps(int fps){
if (displayFps){
if (raceViewController.isDisplayFps()){
gc.setFill(Color.BLACK);
gc.setFont(new Font(14));
gc.setLineWidth(3);
@@ -273,6 +129,7 @@ public class CanvasController {
* Draws all the boats.
*/
private void drawBoats() {
Map<Boat, TimelineInfo> timelineInfos = raceViewController.getTimelineInfos();
for (Boat boat : timelineInfos.keySet()) {
TimelineInfo timelineInfo = timelineInfos.get(boat);
@@ -318,7 +175,7 @@ public class CanvasController {
gc.setFill(color);
if (annotationCheck) {
if (raceViewController.isDisplayAnnotations()) {
// Set boat text
gc.setFont(new Font(14));
gc.setLineWidth(3);
@@ -338,7 +195,7 @@ public class CanvasController {
double[] yy = new double[] {p1.y + y, p2.y + y, y, p3.y + y};
gc.fillPolygon(xx, yy, 4);
if (annotationCheck){
if (raceViewController.isDisplayAnnotations()){
drawWake(gc, x, y, speed, color, heading);
}
}
@@ -368,7 +225,7 @@ public class CanvasController {
* Draws the course.
*/
private void drawCourse() {
for (Mark mark : race.getCourse()) {
for (Mark mark : raceViewController.getRace().getCourse()) {
if (mark.getMarkType() == MarkType.SINGLE_MARK) {
drawSingleMark((SingleMark) mark, Color.BLACK);
} else if (mark.getMarkType() == MarkType.GATE_MARK) {
@@ -423,8 +280,4 @@ public class CanvasController {
gc.setLineWidth(1);
gc.strokeLine(x1, y1, x2, y2);
}
public Race getRace(){
return this.race;
}
}