javamavenjarsplash-screen

How to use a JAR file to display a splash screen?


package misc;

import java.awt.*;
import java.awt.event.*;

public class SplashDemo extends Frame implements ActionListener {

    static void renderSplashFrame(Graphics2D g, int frame) {
        final String[] comps = {"foo", "bar", "baz"};
        g.setComposite(AlphaComposite.Clear);
        g.fillRect(120,140,200,40);
        g.setPaintMode();
        g.setColor(Color.BLACK);
        g.drawString("Loading "+comps[(frame/5)%3]+"...", 120, 150);
    }
    public SplashDemo() {
        super("SplashScreen demo");
        setSize(300, 200);
        setLayout(new BorderLayout());
        Menu m1 = new Menu("File");
        MenuItem mi1 = new MenuItem("Exit");
        m1.add(mi1);
        mi1.addActionListener(this);
        this.addWindowListener(closeWindow);

        MenuBar mb = new MenuBar();
        setMenuBar(mb);
        mb.add(m1);
        
        //
        final SplashScreen splash = SplashScreen.getSplashScreen();
        if (splash == null) {
            System.out.println("SplashScreen.getSplashScreen() returned null");
            return;
        }
        Graphics2D g = splash.createGraphics();
        if (g == null) {
            System.out.println("g is null");
            return;
        }
        for(int i=0; i<50; i++) {
            renderSplashFrame(g, i);
            splash.update();
            try {
                Thread.sleep(90);
            }
            catch(InterruptedException e) {
            }
        }
        splash.close();
        
        // setVisible(true);
        // toFront();
    }
    public void actionPerformed(ActionEvent ae) {
        System.exit(0);
    }
    
    private static WindowListener closeWindow = new WindowAdapter(){
        public void windowClosing(WindowEvent e){
            e.getWindow().dispose();
        }
    };
}

In JAR's main class:

public static void main(String[] args) {
    new SplashDemo(); //splash with image
    ...

When I run it from the console, I get

SplashScreen.getSplashScreen() returned null

The project folders are as follows

project root > src > misc > SplashDemo.java
project root > src > main > resources > META-INF > MANIFEST.MF
// made a few locations for the picture to pick up from somewhere.
project root > src > main > resources > images > `image here`
project root > images > `image here`
project root > src > images > `image here`

and manifest file

Manifest-Version: 1.0
Main-Class: main.MainClassName
SplashScreen-Image: images/splash.gif

pom file

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://maven.apache.org/POM/4.0.0"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.creator</groupId>
    <artifactId>myapp</artifactId>
    <version>0.1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies> ... </dependencies>

    <build>
        <sourceDirectory>src</sourceDirectory>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>${project.java.version}</source>
                    <target>${project.java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>
                                ${project.build.directory}/libs
                            </outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.3.0</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>libs/</classpathPrefix>
                            <mainClass>main.MainClassName</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>

    </build>
</project>

However, the application did not create a splash screen when launched via the manifest file option, that is, the getSplashScreen method returns null. How to fix it?

The created JAR file contains an images folder with image in the root.


Solution

  • The following works for me with the SplashDemo class from the tutorial you seem to be using:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.3.0</version>
        <configuration>
            <archive>
                <manifest>
                    <addClasspath>true</addClasspath>
                    <classpathPrefix>libs/</classpathPrefix>
                    <mainClass>misc.SplashDemo</mainClass>
                </manifest>
                <manifestEntries>
                    <SplashScreen-Image>splash.gif</SplashScreen-Image>
                </manifestEntries>
            </archive>
        </configuration>
    </plugin>
    

    Demo zip is HERE (mvn package && java -jar target/misc-1.0-SNAPSHOT.jar)