2017-05-20 8 views
6

プリローダーで初期化するJavaアプリケーションがあります。プリローダーが非表示になると、メインアプリケーションが起動し、リソースが正常に読み込まれます。その後、アプリケーションウィンドウが一時的にロードされ、例外がスローされずに終了します。JavaFXアプリケーション(あらかじめロードされているものを使用)は早めに終了します

メインアプリケーションコード:

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package com.adrian.mobsters.gui; 

import com.adrian.mobsters.resource.Resource; 
import com.adrian.mobsters.resource.ResourceFactory; 
import java.io.IOException; 
import java.util.logging.Level; 
import javafx.application.Application; 
import static javafx.application.Application.launch; 
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.ChangeListener; 
import javafx.beans.value.ObservableValue; 
import javafx.concurrent.Task; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

/** 
* 
* @author aelder 
*/ 
public class MainGUI extends Application { 

    BooleanProperty ready = new SimpleBooleanProperty(false); 

    public void loadResources() { 
     Task task = new Task<Void>() { 

      @Override 
      protected Void call() throws Exception { 
       java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF); 
       System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog"); 

       double index = 0; 
       for (ResourceFactory factory : ResourceFactory.values()) { 
        index++; 
        Resource resource = factory.getResource(); 

        if (resource != null) { 
         resource.importResources(); 
         notifyPreloader(new ProgressNotification(((double) index)/ResourceFactory.values().length)); 
        } 
       } 

       ready.setValue(Boolean.TRUE); 
       notifyPreloader(new StateChangeNotification(
         StateChangeNotification.Type.BEFORE_START)); 
       return null; 
      } 
     }; 

     new Thread(task).start(); 
    } 

    @Override 
    public void start(Stage primaryStage) throws IOException { 
     loadResources(); 
     Parent root = FXMLLoader.load(MainGUI.class.getResource("main.fxml")); 
     Scene scene = new Scene(root); 

     primaryStage.setTitle("Mobsters Bot 2.0 - by Adrian Elder"); 
     primaryStage.setScene(scene); 

     // 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() { 
           primaryStage.show(); 
          } 
         }); 
        } 
       } 
     });; 
    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     launch(args); 
    } 
} 

プリローダーコード:

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package resourceloader; 

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

/** 
* Simple Preloader Using the ProgressBar Control 
* 
* @author aelder 
*/ 
public class ResourceLoader extends Preloader { 

    ProgressBar bar; 
    Stage stage; 

    private Scene createPreloaderScene() { 
     bar = new ProgressBar(); 
     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 handleStateChangeNotification(StateChangeNotification scn) { 
     if (scn.getType() == StateChangeNotification.Type.BEFORE_START) { 
      stage.hide(); 
     } 
    } 

    @Override 
    public void handleProgressNotification(ProgressNotification pn) { 
     bar.setProgress(pn.getProgress()); 
    } 
} 

更新: それはrunLater方法でステージショー()メソッドを実行するとは何かを持っているようです。なんらかの理由で、アプリケーションが早期に終了する原因になります。

私の現在の解決策は、リソースがロードされるまでスリープしてから、アプリケーションスレッドでshowメソッドを実行することです。

public void start(Stage primaryStage) throws IOException { 
    this.primaryStage = primaryStage; 

    primaryStage.setTitle("Mobsters Bot 2.0 - by Adrian Elder"); 
    primaryStage.getIcons().add(new Image(MainGUI.class.getResourceAsStream("/icons/sword.png"))); 

    currentThread = Thread.currentThread(); 
    primaryStage.setScene(new Scene(parent.get())); 
    primaryStage.show(); 
} 

@Override 
public void init() throws InterruptedException { 
    // After the app is ready, show the stage 
    loadResources(); 

    while(!ready.get()) { 
     Thread.sleep(100); 
    } 
} 

答えて

2

移動し、あなたのprimaryStage.show();やイベントの外には、primaryStage.setScene(scene);後にそれを置くと、アプリケーションが正常に開いている場合..私は問題はこれが私の作品

として準備ができて、それをマーキングした場合であると思い見ますロガーとリソースにコメントを付けて、部分的にコメントを外してください。デバッグに役立ちます。私はあなたの図書館を持っていないので、私はそれ以上はできません。

public class Main extends Application { 

    BooleanProperty ready = new SimpleBooleanProperty(false); 

    public void loadResources() { 
     Task task = new Task<Void>() { 

      @Override 
      protected Void call() throws Exception { 
       //java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF); 
       //System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog"); 

       /*double index = 0; 
       for (ResourceFactory factory : ResourceFactory.values()) { 
        index++; 
        Resource resource = factory.getResource(); 

        if (resource != null) { 
         resource.importResources(); 
         notifyPreloader(new ProgressNotification(((double) index)/ResourceFactory.values().length)); 
        } 
       }*/ 

       ready.setValue(Boolean.TRUE); 
       notifyPreloader(new StateChangeNotification(StateChangeNotification.Type.BEFORE_START)); 
       return null; 
      } 
     }; 

     new Thread(task).start(); 
    } 

    @Override 
    public void start(Stage primaryStage) throws IOException { 

     //Parent root = FXMLLoader.load(Main.class.getResource("main.fxml")); 
     Scene scene = new Scene(new Label("Application started"), 400, 400); 

     primaryStage.setTitle("Mobsters Bot 2.0 - by Adrian Elder"); 
     primaryStage.setScene(scene); 

     // 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() { 
          primaryStage.show(); 
         } 
        }); 
       } 
      } 
     }); 
     loadResources(); 
    } 

    /** 
    * @param args 
    *   the command line arguments 
    */ 
    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

これで問題は解決しましたが、リソースの読み込みが完了する前にアプリケーションを開始することはできませんか?私はoracle(図13-12)(http://docs.oracle.com/javase/8/docs/technotes/guides/deploy/preloaders.html#BABGGDJG)のチュートリアルに従っていましたが、このイベント・パターンが使用されていました。 –

+0

私は問題があなたの保護されたVoid呼び出しにあると思う()例外 機能をスローします。それをデバッグしましたか?私はその関数でtry catchを追加すると、エラーが発生するはずです。私はあなたのコードをデバッグすることができませんそれは私が持っていないいくつかのライブラリを参照してください –

+0

私のネイティブコードをすべて削除してもエラーが発生します。プログレスバー通知を1.0に更新する以外のすべてのコードを削除します。 –

関連する問題