diff --git a/racevisionGame/src/main/java/visualiser/app/App.java b/racevisionGame/src/main/java/visualiser/app/App.java index 8c75ee97..48db2bcb 100644 --- a/racevisionGame/src/main/java/visualiser/app/App.java +++ b/racevisionGame/src/main/java/visualiser/app/App.java @@ -1,61 +1,209 @@ package visualiser.app; +import javafx.animation.FadeTransition; import javafx.application.Application; import javafx.application.Platform; +import javafx.beans.property.ReadOnlyObjectProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.concurrent.Task; +import javafx.concurrent.Worker; import javafx.event.EventHandler; import javafx.fxml.FXMLLoader; +import javafx.geometry.Pos; +import javafx.geometry.Rectangle2D; import javafx.scene.Parent; import javafx.scene.Scene; +import javafx.scene.control.Label; +import javafx.scene.control.ListView; +import javafx.scene.control.ProgressBar; +import javafx.scene.effect.DropShadow; import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.Pane; +import javafx.scene.layout.VBox; +import javafx.scene.paint.Color; +import javafx.stage.Screen; import javafx.stage.Stage; +import javafx.stage.StageStyle; import javafx.stage.WindowEvent; +import javafx.util.Duration; import visualiser.Controllers.MainController; public class App extends Application { + + private static Stage stage; + private Pane splashLayout; + private ProgressBar loadProgress; + private Label progressText; + private static final int SPLASH_WIDTH = 676; + private static final int SPLASH_HEIGHT = 227; + /** * Entry point for running the programme - * * @param args for starting the programme */ public static void main(String[] args) { launch(args); } + @Override + public void init() { + ImageView splash = new ImageView(new Image( + getClass().getClassLoader().getResourceAsStream("images/splashScreen.png") + )); + loadProgress = new ProgressBar(); + loadProgress.setPrefWidth(SPLASH_WIDTH - 20); + progressText = new Label("Preparing application . . ."); + splashLayout = new VBox(); + splashLayout.getChildren().addAll(splash, loadProgress, progressText); + progressText.setAlignment(Pos.CENTER); + splashLayout.setStyle( + "-fx-padding: 5; " + + "-fx-background-color: cornsilk; " + + "-fx-border-width:5; " + + "-fx-border-color: " + + "linear-gradient(" + + "to bottom, " + + "chocolate, " + + "derive(chocolate, 50%)" + + ");" + ); + splashLayout.setEffect(new DropShadow()); + } + /** - * Method that displays the visualiser, starting with the title screen. - * @param stage the stage to be displayed. + * Method that sets up and displays the splash screen + * @param initStage the inital stage * @throws Exception if something wrong with title screen. */ - public void start(Stage stage) throws Exception { - stage.setOnCloseRequest(new EventHandler() { + public void start(Stage initStage) throws Exception { + final Task> boatTask = new Task>() { @Override - public void handle(WindowEvent event) { - Platform.exit(); - System.exit(0); + protected ObservableList call() throws InterruptedException { + ObservableList addedFilling = + FXCollections.observableArrayList(); + ObservableList burgerFilling = + FXCollections.observableArrayList( + "Buns", "Patties", "Lettuce", "Onions", "Tomato", + "Sauces" + ); + + updateMessage("Preparing ingredients . . ."); + Thread.sleep(1000); + for (int i = 0; i < burgerFilling.size(); i++) { + Thread.sleep(800); + updateProgress(i + 1, burgerFilling.size()); + String nextFilling = burgerFilling.get(i); + addedFilling.add(nextFilling); + updateMessage("Adding the " + nextFilling + " . . ."); + } + Thread.sleep(400); + updateMessage("Burger's done!"); + + return addedFilling; } - }); + }; + + showSplash( + initStage, + boatTask, + () -> { + try { + showMainStage(); + } catch (Exception e) { + e.printStackTrace(); + } + } + ); + new Thread(boatTask).start(); + + } + + /** + * Get main stage + * @return main stage + */ + public static Stage getStage() { + return App.stage; + } + + /** + * Set main stage + * @param stage stage to set main stage + */ + public static void setStage(Stage stage) { + App.stage = stage; + } + + /** + * Show the main stage after the splash screen + * @throws Exception + */ + private void showMainStage() throws Exception { + stage = new Stage(StageStyle.DECORATED); FXMLLoader loader = new FXMLLoader(getClass().getResource("/visualiser/scenes/main.fxml")); Parent root = loader.load(); stage.setResizable(false); MainController mc = (MainController) loader.getController(); mc.enterTitle(); Scene scene = new Scene(root); - stage.setScene(scene); stage.setTitle("RaceVision - Team 7"); stage.getIcons().add(new Image(getClass().getClassLoader().getResourceAsStream("images/SailIcon.png"))); mc.startCss(); setStage(stage); stage.show(); + stage.setOnCloseRequest(new EventHandler() { + @Override + public void handle(WindowEvent event) { + Platform.exit(); + System.exit(0); + } + }); } - public static Stage getStage() { - return App.stage; + /** + * Show the splash screen + * @param initStage Initial stage + * @param task + * @param initCompletionHandler + */ + private void showSplash( + final Stage initStage, + Task task, + InitCompletionHandler initCompletionHandler + ) { + progressText.textProperty().bind(task.messageProperty()); + loadProgress.progressProperty().bind(task.progressProperty()); + task.stateProperty().addListener((observableValue, oldState, newState) -> { + if (newState == Worker.State.SUCCEEDED) { + loadProgress.progressProperty().unbind(); + loadProgress.setProgress(1); + initStage.toFront(); + FadeTransition fadeSplash = new FadeTransition(Duration.seconds(2), splashLayout); + fadeSplash.setFromValue(1.0); + fadeSplash.setToValue(0.0); + fadeSplash.setOnFinished(actionEvent -> initStage.hide()); + fadeSplash.play(); + + initCompletionHandler.complete(); + } + }); + + Scene splashScene = new Scene(splashLayout, Color.TRANSPARENT); + final Rectangle2D bounds = Screen.getPrimary().getBounds(); + initStage.setScene(splashScene); + initStage.setX(bounds.getMinX() + bounds.getWidth() / 2 - SPLASH_WIDTH / 2); + initStage.setY(bounds.getMinY() + bounds.getHeight() / 2 - SPLASH_HEIGHT / 2); + initStage.initStyle(StageStyle.TRANSPARENT); + initStage.setAlwaysOnTop(true); + initStage.show(); } - public static void setStage(Stage stage) { - App.stage = stage; + public interface InitCompletionHandler { + void complete(); } } diff --git a/racevisionGame/src/main/resources/images/splashScreen.png b/racevisionGame/src/main/resources/images/splashScreen.png new file mode 100644 index 00000000..1d60605e Binary files /dev/null and b/racevisionGame/src/main/resources/images/splashScreen.png differ