Arrow is now displayed on screen more vividly, the arrow can be customised to a different colour scheme if needed. #story[882]

main
Joseph Gardner 9 years ago
parent 43757b34d1
commit 3bc8ad0a07

@ -17,7 +17,7 @@ public class RaceStatus extends AC35Data {
private int windSpeed;
private int raceType;
private ArrayList<BoatStatus> boatStatuses;
private static final double windDirectionScalar = 360.0 / 32768.0; // 0x8000 / 360
private static final double windDirectionScalar = 360.0 / 49152; // 0xC000 / 360
public RaceStatus(long currentTime, int raceID, int raceStatus, long expectedStartTime, int windDirection, int windSpeed, int raceType, ArrayList<BoatStatus> boatStatuses){
super(MessageType.RACESTATUS);

@ -54,6 +54,12 @@
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>eu.hansolo</groupId>
<artifactId>Medusa</artifactId>
<version>7.9</version>
</dependency>
</dependencies>

@ -1,16 +1,27 @@
package seng302.Controllers;
import eu.hansolo.medusa.Fonts;
import eu.hansolo.medusa.Gauge;
import eu.hansolo.medusa.GaugeBuilder;
import eu.hansolo.medusa.skins.GaugeSkin;
import eu.hansolo.medusa.skins.GaugeSkinBase;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import seng302.Mock.StreamedRace;
import seng302.Model.*;
import seng302.VisualiserInput;
import java.net.URL;
import java.util.ArrayList;
import java.util.Locale;
import java.util.ResourceBundle;
/**
@ -24,7 +35,9 @@ public class RaceController extends Controller {
private ResizableRaceCanvas raceMap;
private ResizableRaceMap raceBoundaries;
private Gauge arrow;
@FXML SplitPane race;
@FXML StackPane arrowPane;
@FXML CheckBox showFPS;
@FXML CheckBox showBoatPath;
@FXML CheckBox showAnnotations;
@ -94,6 +107,8 @@ public class RaceController extends Controller {
StreamedRace newRace = new StreamedRace(visualiserInput, this);
//newRace.initialiseBoats();
makeArrow();
raceMap = new ResizableRaceCanvas(visualiserInput.getCourse());
raceMap.setMouseTransparent(true);
raceMap.widthProperty().bind(canvasBase.widthProperty());
@ -101,6 +116,7 @@ public class RaceController extends Controller {
//raceMap.setBoats(newRace.getStartingBoats());
raceMap.draw();
raceMap.setVisible(true);
raceMap.setArrow(this.arrow);
canvasBase.getChildren().add(0, raceMap);
@ -110,6 +126,7 @@ public class RaceController extends Controller {
raceBoundaries.heightProperty().bind(canvasBase.heightProperty());
raceBoundaries.draw();
raceBoundaries.setVisible(true);
canvasBase.getChildren().add(0, raceBoundaries);
race.setVisible(true);
@ -211,4 +228,44 @@ public class RaceController extends Controller {
}
});
}
private void makeArrow() {
arrow = GaugeBuilder.create()
.minValue(0)
.maxValue(359)
.startAngle(180)
.angleRange(360)
.autoScale(false)
.customTickLabelsEnabled(true)
.customTickLabels("N", "", "", "", "", "", "", "", "",
"E", "", "", "", "", "", "", "", "",
"S", "", "", "", "", "", "", "", "",
"W", "", "", "", "", "", "", "", "")
.customTickLabelFontSize(72)
.needleBehavior(Gauge.NeedleBehavior.OPTIMIZED)
.borderPaint(Color.web("#1f1e23"))
.backgroundPaint(Color.web("#1f1e23"))
.needleColor(Color.web("#dad9db"))
.tickMarkColor(Color.web("#9f9fa1"))
.tickLabelColor(Color.web("#dad9db"))
.valueColor(Color.web("#dad9db"))
.title("Wind direction")
.titleColor(Color.web("#dad9db"))
.knobType(Gauge.KnobType.FLAT)
.knobColor(Gauge.BRIGHT_COLOR)
.prefSize(125, 125)
.maxWidth(125)
.maxHeight(125)
.build();
Label value = new Label("0°");
value.setFont(Fonts.latoBold(72));
value.setAlignment(Pos.CENTER);
arrow.valueProperty().addListener(o -> {
value.setText(String.format("%f°", arrow.getValue()));
});
arrow.setValue(0);
arrowPane.getChildren().add(arrow);
}
}

@ -1,6 +1,9 @@
package seng302.Model;
import eu.hansolo.medusa.Gauge;
import eu.hansolo.medusa.GaugeBuilder;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.transform.Rotate;
@ -31,6 +34,7 @@ public class ResizableRaceCanvas extends ResizableCanvas {
private final List<Marker> markers;
double[] xpoints = {}, ypoints = {};
private final RaceDataSource raceData;
private Gauge arrow;
public ResizableRaceCanvas(RaceDataSource raceData) {
super();
@ -146,6 +150,13 @@ public class ResizableRaceCanvas extends ResizableCanvas {
gc.restore();
}
private void displayFancyArrow(GraphCoordinate coordinate, double angle) {
angle = angle % 360;
if (arrow != null && arrow.getValue() != angle) {
this.arrow.setValue(angle);
}
}
/**
* Rotates things on the canvas Note: this must be called in between gc.save() and gc.restore() else they will rotate everything
*
@ -240,9 +251,9 @@ public class ResizableRaceCanvas extends ResizableCanvas {
//display wind direction arrow - specify origin point and angle - angle now set to random angle
if (raceData instanceof StreamedCourse) {
displayArrow(new GraphCoordinate((int) getWidth() - 40, 40), ((StreamedCourse) raceData).getWindDirection());
displayFancyArrow(new GraphCoordinate((int) getWidth() - 40, 40), ((StreamedCourse) raceData).getWindDirection());
} else {
displayArrow(new GraphCoordinate((int) getWidth() - 40, 40), 150);
displayFancyArrow(new GraphCoordinate((int) getWidth() - 40, 40), 150);
}
}
@ -349,4 +360,8 @@ public class ResizableRaceCanvas extends ResizableCanvas {
));
}
public void setArrow(Gauge arrow) {
this.arrow = arrow;
}
}

@ -219,7 +219,7 @@ public class VisualiserInput implements Runnable {
//If no heartbeat has been received in more the heartbeat period
//then the connection will need to be restarted.
System.out.println("time since last heartbeat: " + timeSinceHeartbeat());//TEMP REMOVE
//System.out.println("time since last heartbeat: " + timeSinceHeartbeat());//TEMP REMOVE
long heartBeatPeriod = 10 * 1000;
if (timeSinceHeartbeat() > heartBeatPeriod) {
System.out.println("Connection has stopped, trying to reconnect.");
@ -285,7 +285,7 @@ public class VisualiserInput implements Runnable {
for (BoatStatus boatStatus: this.raceStatus.getBoatStatuses()) {
this.boatStatusMap.put(boatStatus.getSourceID(), boatStatus);
}
setCourseWindDirection(raceStatus.getScaledWindDirection() + 180);
setCourseWindDirection(raceStatus.getScaledWindDirection());
}
//DisplayTextMessage.
/*else if (message instanceof DisplayTextMessage) {

@ -1,19 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<SplitPane xmlns:fx="http://javafx.com/fxml/1" fx:id="race" dividerPositions="0.7" visible="false" AnchorPane.bottomAnchor="0.0"
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
xmlns="http://javafx.com/javafx/8" fx:controller="seng302.Controllers.RaceController">
<SplitPane fx:id="race" dividerPositions="0.7" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.Controllers.RaceController">
<items>
<GridPane fx:id="canvasBase">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Pane prefHeight="200.0" prefWidth="400.0" GridPane.halignment="LEFT" GridPane.valignment="TOP">
@ -24,28 +26,13 @@
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="240.0" prefWidth="200.0">
<children>
<CheckBox fx:id="showBoatPath" mnemonicParsing="false" selected="true"
text="Show Boat Paths" AnchorPane.leftAnchor="0.0"
AnchorPane.topAnchor="104.0"/>
<CheckBox fx:id="showAnnotations" layoutX="-2.0" layoutY="14.0"
mnemonicParsing="false" selected="true"
text="Show Annotations" AnchorPane.leftAnchor="0.0"
AnchorPane.topAnchor="0.0"/>
<CheckBox fx:id="showName" layoutY="39.0" mnemonicParsing="false"
selected="true" text="Show Boat Name"
AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="26.0"/>
<CheckBox fx:id="showAbbrev" layoutY="61.0" mnemonicParsing="false"
selected="true" text="Show Boat Abbreviation"
AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="52.0"/>
<CheckBox fx:id="showSpeed" layoutY="90.0" mnemonicParsing="false"
selected="true" text="Show Boat Speed"
AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="78.0"/>
<Button fx:id="saveAnno" layoutX="11.0" layoutY="106.0" maxWidth="154.0"
mnemonicParsing="false" prefWidth="154.0" text="Save Annotation"
AnchorPane.topAnchor="130.0"/>
<Button fx:id="showSetAnno" layoutX="11.0" layoutY="139.0"
mnemonicParsing="false" text="Show Set Annotation"
AnchorPane.topAnchor="160.0"/>
<CheckBox fx:id="showBoatPath" mnemonicParsing="false" selected="true" text="Show Boat Paths" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="104.0" />
<CheckBox fx:id="showAnnotations" layoutX="-2.0" layoutY="14.0" mnemonicParsing="false" selected="true" text="Show Annotations" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0" />
<CheckBox fx:id="showName" layoutY="39.0" mnemonicParsing="false" selected="true" text="Show Boat Name" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="26.0" />
<CheckBox fx:id="showAbbrev" layoutY="61.0" mnemonicParsing="false" selected="true" text="Show Boat Abbreviation" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="52.0" />
<CheckBox fx:id="showSpeed" layoutY="90.0" mnemonicParsing="false" selected="true" text="Show Boat Speed" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="78.0" />
<Button fx:id="saveAnno" layoutX="11.0" layoutY="106.0" maxWidth="154.0" mnemonicParsing="false" prefWidth="154.0" text="Save Annotation" AnchorPane.topAnchor="130.0" />
<Button fx:id="showSetAnno" layoutX="11.0" layoutY="139.0" mnemonicParsing="false" text="Show Set Annotation" AnchorPane.topAnchor="160.0" />
</children>
</AnchorPane>
</content>
@ -54,9 +41,7 @@
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<CheckBox fx:id="showFPS" layoutX="-14.0" layoutY="13.0"
mnemonicParsing="false" selected="true" text="Show FPS"
AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0"/>
<CheckBox fx:id="showFPS" layoutX="-14.0" layoutY="13.0" mnemonicParsing="false" selected="true" text="Show FPS" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
</content>
@ -65,40 +50,39 @@
</Accordion>
</children>
</Pane>
<Label fx:id="timer" layoutX="45.0" layoutY="146.0" maxHeight="20.0" text="0:0"
AnchorPane.bottomAnchor="0.0" AnchorPane.rightAnchor="0.0" GridPane.halignment="RIGHT"
GridPane.valignment="BOTTOM">
<Label fx:id="timer" layoutX="45.0" layoutY="146.0" maxHeight="20.0" text="0:0" AnchorPane.bottomAnchor="0.0" AnchorPane.rightAnchor="0.0" GridPane.halignment="RIGHT" GridPane.valignment="BOTTOM">
<font>
<Font name="System Bold" size="15.0"/>
<Font name="System Bold" size="15.0" />
</font>
</Label>
<Label fx:id="FPS" text="FPS: 0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
GridPane.halignment="LEFT" GridPane.valignment="BOTTOM">
<Label fx:id="FPS" text="FPS: 0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" GridPane.halignment="LEFT" GridPane.valignment="BOTTOM">
<font>
<Font name="System Bold" size="15.0"/>
<Font name="System Bold" size="15.0" />
</font>
</Label>
<Label fx:id="timeZone" text="Label" GridPane.halignment="RIGHT" GridPane.valignment="BOTTOM">
<GridPane.margin>
<Insets bottom="20.0"/>
<Insets bottom="20.0" />
</GridPane.margin>
<font>
<Font name="System Bold" size="15.0"/>
<Font name="System Bold" size="15.0" />
</font>
</Label>
<StackPane fx:id="arrowPane" alignment="TOP_RIGHT" prefHeight="150.0" prefWidth="150.0" snapToPixel="false" GridPane.halignment="RIGHT" GridPane.valignment="TOP">
<GridPane.margin>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</GridPane.margin>
</StackPane>
</children>
</GridPane>
<AnchorPane layoutX="450.0" minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="200.0"
GridPane.columnIndex="1">
<AnchorPane layoutX="450.0" minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="200.0" GridPane.columnIndex="1">
<children>
<TableView fx:id="boatInfoTable" layoutX="-2.0" prefHeight="600.0" prefWidth="264.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="-2.0" AnchorPane.rightAnchor="-62.0"
AnchorPane.topAnchor="0.0">
<TableView fx:id="boatInfoTable" layoutX="-2.0" prefHeight="600.0" prefWidth="264.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="-2.0" AnchorPane.rightAnchor="-62.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn fx:id="boatPlacingColumn" prefWidth="50.0" text="Place"/>
<TableColumn fx:id="boatTeamColumn" prefWidth="100.0" text="Team"/>
<TableColumn fx:id="boatMarkColumn" prefWidth="130.0" text="Mark"/>
<TableColumn fx:id="boatSpeedColumn" prefWidth="75.0" text="Speed"/>
<TableColumn fx:id="boatPlacingColumn" prefWidth="50.0" text="Place" />
<TableColumn fx:id="boatTeamColumn" prefWidth="100.0" text="Team" />
<TableColumn fx:id="boatMarkColumn" prefWidth="130.0" text="Mark" />
<TableColumn fx:id="boatSpeedColumn" prefWidth="75.0" text="Speed" />
</columns>
</TableView>
</children>

Loading…
Cancel
Save