Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

FX Preloader in stand alone app

OlekJun 30 2014 — edited Jul 8 2014

Hi there,

I am a little bit frustrated with the Preloader API...

After reading the tutorial here I still don't get it...

At the end I just copy and paste the code from section 9.3.4 (the long startup task example) and it still won't work.

After starting the application I only see some black screen flickering at the upper left

screen and then the main app shows up.

What I have done:

Using Netbeans 8.0 under Linux(Fedora20 64bit), JDK 1.8u5 ...

Here are the two classes - the main app :

import javafx.application.Application;
import javafx.application.Platform;
import javafx.application.Preloader.ProgressNotification;
import javafx.application.Preloader.StateChangeNotification;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;

public class PreloaderDemo extends Application {

Stage stage;
BooleanProperty ready = new SimpleBooleanProperty( false );

private void longStart() {
//simulate long init in background
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
int max = 10;
for ( int i = 1; i <= max; i++ ) {
Thread.sleep( 1000 );
// Send progress to preloader
notifyPreloader( new ProgressNotification( ( ( double ) i ) / max ) );
}
// After init is ready, the app is ready to be shown
// Do this before hiding the preloader stage to prevent the
// app from exiting prematurely
ready.setValue( Boolean.TRUE );

notifyPreloader( new StateChangeNotification(
StateChangeNotification.Type.BEFORE_START ) );

return null;
}
};
new Thread( task ).start();
}

@Override
public void start( final Stage stage ) throws Exception {
// Initiate simulated long startup sequence
longStart();

stage.setScene( new Scene( new Label( "Application started" ),
400, 400 ) );

// After the app is ready, show the stage
ready.addListener( (ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) -> {
if ( Boolean.TRUE.equals( t1 ) ) {
Platform.runLater( stage::show );
}
} );;
}
}

Here is the preloader :

import javafx.application.Preloader;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class DemoPreloader extends Preloader {

ProgressBar bar;
Stage stage;
boolean noLoadingProgress = true;

private Scene createPreloaderScene() {
bar = new ProgressBar( 0 );
BorderPane p = new BorderPane();
p.setCenter( bar );
return new Scene( p, 300, 150 );
}

@Override
public void start( Stage stage ) throws Exception {
this.stage = stage;
stage.setScene( createPreloaderScene() );
stage.show();
}

@Override
public void handleProgressNotification( ProgressNotification pn ) {
//application loading progress is rescaled to be first 50%
//Even if there is nothing to load 0% and 100% events can be
// delivered
if ( pn.getProgress() != 1.0 || !noLoadingProgress ) {
bar.setProgress( pn.getProgress() / 2 );
if ( pn.getProgress() > 0 ) {
noLoadingProgress = false;
}
}
}

@Override
public void handleStateChangeNotification( StateChangeNotification evt ) {
//ignore, hide after application signals it is ready
}

@Override
public void handleApplicationNotification( PreloaderNotification pn ) {
if ( pn instanceof ProgressNotification ) {
//expect application to send us progress notifications
//with progress ranging from 0 to 1.0
double v = ( ( ProgressNotification ) pn ).getProgress();
if ( !noLoadingProgress ) {
//if we were receiving loading progress notifications
//then progress is already at 50%.
//Rescale application progress to start from 50%
v = 0.5 + v / 2;
}
bar.setProgress( v );
}
else if ( pn instanceof StateChangeNotification ) {
//hide after get any state update from application
stage.hide();
}
}
}

Can anyone re-run this?

On my machine I see only a little black flickering on the left upper screen and

then immediately the app is shown...

The only way I can get this to run is to set the custom preloader property in the Netbeans-project properties...

Is this the only way I can achieve this?

If you use a maven based project in Netbeans you did not got this option ...

Regards,

Olek

Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Aug 5 2014
Added on Jun 30 2014
9 comments
4,861 views