package seng302.Controllers; import javafx.animation.AnimationTimer; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.scene.control.Label; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import org.xml.sax.SAXException; import seng302.Model.BoatInRace; import seng302.Model.RaceClock; import seng302.RaceXMLReader; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import java.net.URL; import java.util.ResourceBundle; /** * Created by esa46 on 6/04/17. */ public class StartController extends Controller { @FXML private GridPane start; @FXML private AnchorPane startWrapper; @FXML private TableView boatNameTable; @FXML private TableColumn boatNameColumn; @FXML private TableColumn boatCodeColumn; @FXML private Label timeZoneTime; @FXML private Label timer; @FXML private int PRERACE_TIME = 15000; private RaceClock raceClock; /** * Begins the race with a scale factor of 15 */ public void startRace1Min() { startRace(15); } /** * Begins the race with a scale factor of 3 */ public void startRace5Min() { startRace(3); } /** * Begins the race with a scale factor of 1 */ public void startRaceNoScaling() { startRace(1); } private void startRace(int raceScale){ countdownTimer(raceScale); } @Override public void initialize(URL location, ResourceBundle resources){ initialiseTables(); } public AnchorPane startWrapper(){ return startWrapper; } private void initialiseTables() { RaceXMLReader raceXMLReader = null; try { raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml"); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } BoatInRace[] boats = new BoatInRace[raceXMLReader.getBoats().size()]; boats = raceXMLReader.getBoats().toArray(boats); ObservableList observableBoats = FXCollections.observableArrayList(boats); boatNameTable.setItems(observableBoats); boatNameColumn.setCellValueFactory(cellData -> cellData.getValue().getName()); boatCodeColumn.setCellValueFactory(new PropertyValueFactory<>("abbrev")); //timezone raceClock = new RaceClock(raceXMLReader.getMark()); timeZoneTime.textProperty().bind(raceClock.timeProperty()); } /** * Updates the calculated time to the timer label * * @param time The calculated time from calcTimer() method */ protected void updateTime(String time) { Platform.runLater(() -> { timer.setText(time); }); } /** * Countdown timer until race starts. Use PRERACE_TIME to set countdown duration. */ protected void countdownTimer(int scaleFactor) { new AnimationTimer() { long currentTime = System.currentTimeMillis(); long startTime = currentTime + (PRERACE_TIME/scaleFactor); long minutes; long currentTimeInSeconds; long remainingSeconds; long hours; long timeLeft; @Override public void handle(long arg0) { timeLeft = startTime - currentTime; if (timeLeft <= 0) { updateTime("Race is starting..."); stop(); parent.beginRace(scaleFactor); startWrapper.setVisible(false); } else { currentTimeInSeconds = (timeLeft*scaleFactor) / 1000; minutes = currentTimeInSeconds / 60; remainingSeconds = currentTimeInSeconds % 60; hours = minutes / 60; minutes = minutes % 60; updateTime(String.format("Race Clock: -%02d:%02d:%02d", hours, minutes, remainingSeconds)); } currentTime = System.currentTimeMillis(); } }.start(); } }