2017-10-12 9 views
1

アプリケーションの前にJavaFX Preloaderスプラッシュsccreenを表示しようとしています。私はEclipse IDEを使用しています。「実行」をクリックすると、スプラッシュ画面が正しく表示される時間の半分と、残りの半分が画像が表示される場所ではなく灰色または黒色の画面になります。JavaFX Preloaderが時折灰色/黒色に表示され、正しくロードされる時間があるのはなぜですか?

問題が正しく表示されない場合があります。

SplashController

public class SplashController extends Preloader { 
    private static final double WIDTH = 676; 
    private static final double HEIGHT = 227; 
    private Stage preloaderStage; 
    private Label progressText; 
    private Pane splashScreen; 

public SplashController() {}  

@Override 
    public void init() throws Exception { 
    ImageView splash = 
     new ImageView(new Image(Demo.class.getResource("pic.png").toString())); 
    progressText = 
     new Label("VERSION: " + getVersion() + " ~~~ Loading plugins, please wait..."); 
    splashScreen = new VBox(); 
    splashScreen.getChildren().addAll(splash, progressText); 
    progressText.setAlignment(Pos.CENTER); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
    this.preloaderStage = primaryStage; 
    Scene splashScene = new Scene(splashScreen); 
    this.preloaderStage.initStyle(StageStyle.UNDECORATED); 
    final Rectangle2D bounds = Screen.getPrimary().getBounds(); 
    this.preloaderStage.setScene(splashScene); 
    this.preloaderStage.setX(bounds.getMinX() + bounds.getWidth()/2 - WIDTH/2); 
    this.preloaderStage.setY(bounds.getMinY() + bounds.getHeight()/2 - HEIGHT/2); 
    this.preloaderStage.show(); 
    } 
} 

そして、私のメインクラスでデモは、私は単に持っている:

public class Demo extends Application { 
    @Override 
    public void start(Stage stage) throws Exception { 
    FXMLLoader loader = new 
    FXMLLoader(Demo.class.getResource("FXMLDocument.fxml")); 
    GridPane root = loader.load(); 

        --------other app code here--------- 
    } 

    public static void main(String[] args) { 
    LauncherImpl.launchApplication(Demo.class, SplashController.class, args); 
    } 

}

+0

ありがとうございました!はい、問題はJavaFXスレッドで長い実行プロセスがありました:) – chip

+0

幸運にも推測:-)、私はちょうど答えにコメントをしました。 – jewelsea

答えて

0

多分、あなたは上のいくつかの長い実行中のプロセスを実行していますJavaFXアプリケーションスレッドまたはアプリケーション起動に関与するスレッド。プリローダーの円滑な動作を妨げます。

あなたはOracle Preloader sampleを検討して、お使いのアプリケーションと比較することをお勧めします。リンクされた例のように、Taskのような同時機能を正しく使用していることを確認してください。ご使用の環境でリンクされているサンプルの動作を確認してください。 Taskとスレッドが長いアプリケーションの開始がないことを確認するために生み出されていることをどのようにメインLongAppInitアプリケーションクラスのstartメソッドでは、(Oracleだけプリローダーのサンプルリンクからコピー)

ソースコード

注意JavaFXアプリケーションスレッドでは発生しません。また、プリプロセッサに初期化プロセスの現在の状態を知らせるために、長いアプリケーション初期化の中でさまざまな時にアプリケーションのメソッドがどのように呼び出されるかを見て、進行状況をリアルタイムでUIに正確に反映できるようにします。

LongAppInitPreloader.java

public class LongAppInitPreloader 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); 
    } 

    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(); 
     } 
    } 
} 

LongAppInit.java

public class LongInitApp extends Application { 
    Stage stage; 
    BooleanProperty ready = new SimpleBooleanProperty(false); 

    private void longStart() { 
     //simulate long init in background 
     Task task = new Task<Void>() { 
      @Override 
      protected Void call() throws Exception { 
       int max = 10; 
       for (int i = 1; i <= max; i++) { 
        Thread.sleep(200); 
        // 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(new ChangeListener<Boolean>(){ 
      public void changed(
       ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) { 
        if (Boolean.TRUE.equals(t1)) { 
         Platform.runLater(new Runnable() { 
          public void run() { 
           stage.show(); 
          } 
         }); 
        } 
       } 
     });;     
    } 
} 
関連する問題