Skip to content
Advertisement

How do I add a Splash screen to a main program in javafx?

I have 2 files, Splash.java and Main.java. Here are the 2 codes: Splash.java

package application;

import javafx.animation.*;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.text.Font;


/**
 * This is my own splash screen, that I made myself.
 *
 */
public class Splash{
    static Stage splash;
    static Rectangle rect = new Rectangle();
    public Splash() {
        splash = new Stage(StageStyle.UNDECORATED);
        splash.toFront();
        splash.setHeight(200);
        splash.setWidth(400);
    }
    public Splash show() {
        /*
         * Part 1:
         * This is the rolling square animation.
         * This animation looks cool for a loading screen,
         * so I made this. Only the lines of code for fading
         * from Stack Overflow.
         */
        //rectangle insertion
        int scale = 30;
        int dur = 800;
        rect = new Rectangle(100-2*scale,20,scale,scale);
        rect.setFill(Color.AQUAMARINE);

        //actual animations
        //initialising the sequentialTranslation
        SequentialTransition seqT = new SequentialTransition(rect);
        //umm, ignore this, just some configs that work magic
        int[] rotins = {scale,2*scale,3*scale,4*scale,5*scale,-6*scale,-5*scale,-4*scale,-3*scale,-2*scale};
        int x,y;
        for (int i:rotins) {
            //rotating the square
            RotateTransition rt = new RotateTransition(Duration.millis(dur),rect);
            rt.setByAngle(i/Math.abs(i)*90);
            rt.setCycleCount(1);
            //moving the square horizontally
            TranslateTransition pt = new TranslateTransition(Duration.millis(dur), rect);
            x=(int) (rect.getX()+Math.abs(i));
            y=(int) (rect.getX()+Math.abs(i)+(Math.abs(i)/i)*scale);
            pt.setFromX(x);
            pt.setToX(y);
            //parallelly execute them and you get a rolling square
            ParallelTransition pat = new ParallelTransition();
            pat.getChildren().addAll(pt,rt);
            pat.setCycleCount(1);
            seqT.getChildren().add(pat);
        }
        //playing the animation
        seqT.play();
        //lambda code sourced from StackOverflow, fades away stage
        seqT.setOnFinished(e->{
            Timeline timeline = new Timeline();
            KeyFrame key = new KeyFrame(Duration.millis(800),
                           new KeyValue (splash.getScene().getRoot().opacityProperty(), 0)); 
            timeline.getKeyFrames().add(key);   
            timeline.setOnFinished((ae) -> System.exit(1)); 
            timeline.play();
        });
        //The text part
        Label label = new Label("Flight");
        label.setFont(new Font("Verdana",40));
        label.setStyle("-fx-text-fill:white");
        label.setLayoutX(140);
        label.setLayoutY(70);
        Label lab = new Label("Launching...");
        lab.setFont(new Font("Times New Roman",10));
        lab.setStyle("-fx-text-fill:white");
        lab.setLayoutX(170);
        lab.setLayoutY(180);
        //A complimentary image
        Image image = new Image(getClass().getResourceAsStream("launchplane.png"));
        ImageView iv = new ImageView(image);
        iv.setFitWidth(32);
        iv.setFitHeight(32);
        iv.setX(174);
        iv.setY(130);
        //now adding everything to position, opening the stage, start the animation
        Pane pane = new Pane(rect,label,lab,iv);
        pane.setStyle("-fx-background-color:black");
        Scene sc = new Scene(pane);
        splash.setScene(sc);
        splash.show();
        seqT.play();
        return this;
    }
}

And Main.java

package application;    
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
            Scene scene = new Scene(root);
            scene.getStylesheets().add( getClass().getResource("application.css").toExternalForm());
            primaryStage.setTitle("Flight");
            primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("airplane.png")));
            primaryStage.setScene(scene);
            Splash splash = new Splash();
            splash.show();
            primaryStage.toBack();
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Now I want to make a Splash screen appear before the main program is launched. How do I modify Main.java so that my code can show the splash screen for its entire duration before fading away and opening the main program?

Advertisement

Answer

I made a few changes to your code. I changed the Splash variable to Scene. I then added methods to get the Scene and the SequentialTransition. I set the SequentialTransition onFinished method in the main. .

Main

import java.io.IOException;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
 *
 * @author blj0011
 */
public class JavaFXApplication266 extends Application
{

    @Override
    public void start(Stage stage) throws Exception
    {
        Splash splash = new Splash();
        splash.show();
        stage.setScene(splash.getSplashScene());
        splash.getSequentialTransition().setOnFinished(e -> {
            Timeline timeline = new Timeline();
            KeyFrame key = new KeyFrame(Duration.millis(800),
                    new KeyValue(splash.getSplashScene().getRoot().opacityProperty(), 0));
            timeline.getKeyFrames().add(key);
            timeline.setOnFinished((event) -> {
                try {
                    Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
                    //
                    Scene scene = new Scene(root);

                    stage.setScene(scene);
                }
                catch (IOException ex) {
                    ex.printStackTrace();
                }
            });
            timeline.play();
        });
//
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        launch(args);
    }

}

Splash Class

import javafx.animation.*;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.text.Font;
import javafx.util.Duration;

/**
 * This is my own splash screen, that I made myself.
 *
 */
public class Splash
{

    static Scene splash;
    static Rectangle rect = new Rectangle();
    final private Pane pane;
    final private SequentialTransition seqT;

    public Splash()
    {
        pane = new Pane();
        pane.setStyle("-fx-background-color:black");

        splash = new Scene(pane);
        seqT = new SequentialTransition();
    }

    public void show()
    {
        /*
         * Part 1:
         * This is the rolling square animation.
         * This animation looks cool for a loading screen,
         * so I made this. Only the lines of code for fading
         * from Stack Overflow.
         */
        //rectangle insertion
        int scale = 30;
        int dur = 800;
        rect = new Rectangle(100 - 2 * scale, 20, scale, scale);
        rect.setFill(Color.AQUAMARINE);

        //actual animations
        //initialising the sequentialTranslation
        //umm, ignore this, just some configs that work magic
        int[] rotins = {scale, 2 * scale, 3 * scale, 4 * scale, 5 * scale, -6 * scale, -5 * scale, -4 * scale, -3 * scale, -2 * scale};
        int x, y;
        for (int i : rotins) {
            //rotating the square
            RotateTransition rt = new RotateTransition(Duration.millis(dur), rect);
            rt.setByAngle(i / Math.abs(i) * 90);
            rt.setCycleCount(1);
            //moving the square horizontally
            TranslateTransition pt = new TranslateTransition(Duration.millis(dur), rect);
            x = (int) (rect.getX() + Math.abs(i));
            y = (int) (rect.getX() + Math.abs(i) + (Math.abs(i) / i) * scale);
            pt.setFromX(x);
            pt.setToX(y);
            //parallelly execute them and you get a rolling square
            ParallelTransition pat = new ParallelTransition();
            pat.getChildren().addAll(pt, rt);
            pat.setCycleCount(1);
            seqT.getChildren().add(pat);
        }
        //playing the animation
        seqT.play();
        //lambda code sourced from StackOverflow, fades away stage
        seqT.setNode(rect);
        //The text part
        Label label = new Label("Flight");
        label.setFont(new Font("Verdana", 40));
        label.setStyle("-fx-text-fill:white");
        label.setLayoutX(140);
        label.setLayoutY(70);
        Label lab = new Label("Launching...");
        lab.setFont(new Font("Times New Roman", 10));
        lab.setStyle("-fx-text-fill:white");
        lab.setLayoutX(170);
        lab.setLayoutY(180);
        //A complimentary image

        Image image = new Image("https://s3.amazonaws.com/media.eremedia.com/uploads/2012/08/24111405/stackoverflow-logo-700x467.png");
        ImageView iv = new ImageView(image);
        iv.setFitWidth(32);
        iv.setFitHeight(32);
        iv.setX(174);
        iv.setY(130);
        //now adding everything to position, opening the stage, start the animation
        pane.getChildren().addAll(rect, label, lab, iv);

        seqT.play();
    }

    public Scene getSplashScene()
    {
        return splash;
    }

    public SequentialTransition getSequentialTransition()
    {
        return seqT;
    }
}

After Splash Controller

import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;

/**
 *
 * @author blj0011
 */
public class FXMLDocumentController implements Initializable
{

    @FXML
    private Label label;

    @FXML
    private void handleButtonAction(ActionEvent event)
    {
        System.out.println("You clicked me!");
        label.setText("Hello World!");
    }

    @Override
    public void initialize(URL url, ResourceBundle rb)
    {
        // TODO
    }

}

After Splash FXML

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication266.FXMLDocumentController">
    <children>
        <Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
        <Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
    </children>
</AnchorPane>
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement