Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAVAFX SplashScreen with an animated gif

Is it possible to have an animated gif or video in my splash screen.

Here is my code

Launcher class: ** EDITED With all needed files to run simple project.

package com.example;
import javafx.application.Application;
public class Launcher 
{    
    public static void main(String[] args) {  
        System.setProperty("javafx.preloader", "com.example.SplashScreen");      
        Application.launch(Main.class);        
    }
}

Main class

package com.example;
import javafx.application.Application;
import javafx.application.Preloader.StateChangeNotification;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class Main extends Application{

Stage stage;
Scene scene;

@Override
public void start(Stage primaryStage) throws Exception {
    
    try {
        Thread.sleep(5000);
        this.stage = primaryStage;
        AnchorPane pane;
        FXMLLoader mainLoader = new FXMLLoader(getClass().getClassLoader().getResource("layouts/main.fxml"));   
        pane = mainLoader.load();                                               
        scene = new Scene(pane, 600, 445);
        primaryStage.setScene(scene);
        
        primaryStage.show();
        notifyPreloader(new StateChangeNotification(StateChangeNotification.Type.BEFORE_START));
        
    } 
    catch (final Exception e) {
        e.printStackTrace();
    }        
}

}

SplashScreenClass

package com.example;

import javafx.application.Preloader;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class SplashScreen extends Preloader {

    Stage stage;

@Override
public void start(Stage stage) throws Exception {
    this.stage = stage;
    StackPane root = (StackPane) FXMLLoader.load(getClass().getClassLoader().getResource("layouts/splash.fxml"));        
    Scene scene = new Scene(root, 690, 380,true, SceneAntialiasing.BALANCED);
    scene.setFill(Color.TRANSPARENT);
    stage.initStyle(StageStyle.UNDECORATED);
    stage.setScene(scene);
    stage.show();
    
}

@Override
public void handleApplicationNotification(PreloaderNotification pn) {
    if (pn instanceof StateChangeNotification) {
        //hide after get any state update from application
        stage.hide();
    }
}  

}

So basically this is all the java code needed. I added a sleep for 5 seconds to simulate loading from backend. This will generate a splash screen but the gif is not animated. If I do no hide the splashscreen stage, the gif will be animated after the main stage is loaded.

splash fxml

<StackPane xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="380.0" prefWidth="690.0">
     <children>
        <ImageView fitHeight="374.0" fitWidth="686.0" pickOnBounds="true" preserveRatio="true">
           <image>
              <Image url="@../test.gif" />
           </image>
        </ImageView>
     </children>
  </StackPane>

and finally main.fxml

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" >
   <children>      
      <Label layoutX="238.0" layoutY="224.0" prefHeight="63.0" prefWidth="125.0" text="Label" />
   </children>
</AnchorPane>
like image 855
Jawad El Fou Avatar asked Nov 18 '25 05:11

Jawad El Fou


1 Answers

Thanks to the @jewelsea comment, I ended up modifying the main class to do tasks in a background thread and then, when everything is ready, I show the stage for the main application.

[...]
    
    try {
        final Task<Integer> task = new Task<Integer>() {
            @Override
            protected Integer call() throws Exception {
                Thread.sleep(5000);
                Platform.runLater(new Runnable() {
                    public void run() {
                        showStage();
                    }
                }); 
                return 0;
            }
        };
        
        Thread thread = new Thread(task);
        thread.start();
    } catch (final Exception e) {
        e.printStackTrace();
    }
}

public void showStage() {
    stage.show();
    notifyPreloader(new StateChangeNotification(StateChangeNotification.Type.BEFORE_START));
}

The GIF is animated and the splash screen will load after all background tasks are done.

like image 63
Jawad El Fou Avatar answered Nov 21 '25 08:11

Jawad El Fou



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!