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; import java.io.IOException; 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; public static App app; /** * 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 sets up and displays the splash screen * @param initStage the inital stage * @throws Exception if something wrong with title screen. */ public void start(Stage initStage) throws Exception { final Task> boatTask = new Task>() { @Override protected ObservableList call() throws InterruptedException { ObservableList addedFilling = FXCollections.observableArrayList(); ObservableList burgerFilling = FXCollections.observableArrayList( "Buns", "Patties", "Lettuce", "Onions", "Tomato", "Sauces" ); updateMessage("Preparing ingredients . . ."); Thread.sleep(100); for (int i = 0; i < burgerFilling.size(); i++) { Thread.sleep(100); updateProgress(i + 1, burgerFilling.size()); String nextFilling = burgerFilling.get(i); addedFilling.add(nextFilling); updateMessage("Adding the " + nextFilling + " . . ."); } Thread.sleep(100); updateMessage("Burger's done!"); return addedFilling; } }; showSplash( initStage, boatTask, () -> { try { showMainStage(new Stage()); } 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 * @param stage main stage for application * @throws Exception Throws an exception on error */ public void showMainStage(Stage stage) throws Exception { App.stage = stage; App.app = this; 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); } }); } /** * Show the splash screen * @param initStage Initial stage * @param task Task for splash screen * @param initCompletionHandler initCompletionHandler interface */ 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(); } /** * InnitCompletionHandler interface */ public interface InitCompletionHandler { void complete(); } }