Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Displays a JavaFX splash page for an intensive startup task with progress monitoring
import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.collections.*;
import javafx.concurrent.*;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.*;
import javafx.util.Duration;
/**
* Example of displaying a splash page for a standalone JavaFX application
*/
public class FadeApp extends Application {
public static final String APPLICATION_ICON =
"http://cdn1.iconfinder.com/data/icons/Copenhagen/PNG/32/people.png";
public static final String SPLASH_IMAGE =
"http://fxexperience.com/wp-content/uploads/2010/06/logo.png";
private Pane splashLayout;
private ProgressBar loadProgress;
private Label progressText;
private Stage mainStage;
private static final int SPLASH_WIDTH = 676;
private static final int SPLASH_HEIGHT = 227;
public static void main(String[] args) throws Exception {
launch(args);
}
@Override
public void init() {
ImageView splash = new ImageView(new Image(
SPLASH_IMAGE
));
loadProgress = new ProgressBar();
loadProgress.setPrefWidth(SPLASH_WIDTH - 20);
progressText = new Label("Will find friends for peanuts . . .");
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());
}
@Override
public void start(final Stage initStage) throws Exception {
final Task<ObservableList<String>> friendTask = new Task<ObservableList<String>>() {
@Override
protected ObservableList<String> call() throws InterruptedException {
ObservableList<String> foundFriends =
FXCollections.<String>observableArrayList();
ObservableList<String> availableFriends =
FXCollections.observableArrayList(
"Fili", "Kili", "Oin", "Gloin", "Thorin",
"Dwalin", "Balin", "Bifur", "Bofur",
"Bombur", "Dori", "Nori", "Ori"
);
updateMessage("Finding friends . . .");
for (int i = 0; i < availableFriends.size(); i++) {
Thread.sleep(400);
updateProgress(i + 1, availableFriends.size());
String nextFriend = availableFriends.get(i);
foundFriends.add(nextFriend);
updateMessage("Finding friends . . . found " + nextFriend);
}
Thread.sleep(400);
updateMessage("All friends found.");
return foundFriends;
}
};
showSplash(
initStage,
friendTask,
() -> showMainStage(friendTask.valueProperty())
);
new Thread(friendTask).start();
}
private void showMainStage(
ReadOnlyObjectProperty<ObservableList<String>> friends
) {
mainStage = new Stage(StageStyle.DECORATED);
mainStage.setTitle("My Friends");
mainStage.getIcons().add(new Image(
APPLICATION_ICON
));
final ListView<String> peopleView = new ListView<>();
peopleView.itemsProperty().bind(friends);
mainStage.setScene(new Scene(peopleView));
mainStage.show();
}
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(1.2), splashLayout);
fadeSplash.setFromValue(1.0);
fadeSplash.setToValue(0.0);
fadeSplash.setOnFinished(actionEvent -> initStage.hide());
fadeSplash.play();
initCompletionHandler.complete();
} // todo add code to gracefully handle other task states.
});
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 interface InitCompletionHandler {
void complete();
}
}
@SyCode7
Copy link

SyCode7 commented Jan 14, 2015

Hi JewelSea,

Thanks for this great tutorial, i want to insert an image for the splashscreen from the local file system.
I have no clue on the best way to go around this, all my efforts have not yeilded my
desired result. Can you kindly give me some guidance. Thanks

SyCode7

Loading

@jewelsea
Copy link
Author

jewelsea commented Feb 4, 2015

@SyCode7 Just use an ImageView with a file: protocol to load an image from the filesystem into a node that you can display on your splash screen. Though usually, rather than hardcoding a file protocol, you want to get resources like images using getResource rather than directly from the filesystem as it makes your application more portable in that you can bundle the resources in your application jar. For example new ImageView(new Image(MyJavaFXApplication.class.getResource("application-icon.png").toExternalForm())).

Loading

@JulietteGe
Copy link

JulietteGe commented Jun 19, 2015

Thanks a lot! This is great, works well and looks awesome! :D Thank you for providing this code!

Loading

@MarceloAugusto
Copy link

MarceloAugusto commented Mar 3, 2016

Muito obrigado, foi muito util....
Grato.

Loading

@Perneel
Copy link

Perneel commented Mar 7, 2016

Very nice piece of code, I have been using this as a base to create my own preloader in a seperate jar. I tried to expand this to handle the download progress of the jars as well but failed to do so. If you have time, I made a question on SO about this: http://stackoverflow.com/questions/35849930/how-to-handle-java-web-start-downloading-application-in-a-preloader. Feel free to check it out!

Loading

@MICOFO
Copy link

MICOFO commented Apr 20, 2016

Very Good tutorial.
Thank you very much

Loading

@g9164313
Copy link

g9164313 commented Jun 22, 2016

Good tutorial. Thank you.

Loading

@OUSSAMA-EZZIOURI
Copy link

OUSSAMA-EZZIOURI commented May 29, 2017

nice one boss, I like it. Thank you soo muck :)

Loading

@tolutronics
Copy link

tolutronics commented Jul 18, 2017

i will i edit it to start another window rather than list of friends

Loading

@lvwarren
Copy link

lvwarren commented Jan 19, 2019

kudos, jewelsea, i have been following your threads for years on StackOverflow and they are always top notch!

Loading

@tango4567
Copy link

tango4567 commented Jun 25, 2020

Wonder full tutorial. Thank you soo much

Loading

@Damian-crypto
Copy link

Damian-crypto commented Aug 31, 2020

Great! Thank you!

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment