2017-10-12 6 views
1

내 JavaFX 프리 로더 스플래쉬 sccreen을 응용 프로그램 전에 표시하려고합니다. 이클립스 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

OK, 행운의 추측 :-), 방금 대답에 대한 설명을했습니다. – jewelsea

답변

0

가능성, 당신은 몇 가지 장기 실행 프로세스를 실행하는 JavaFX 응용 프로그램 스레드 또는 응용 프로그램 시작과 관련된 스레드 프리 로더의 원활한 작동을 방해합니다.

Oracle Preloader sample을 검토하여 신청서와 비교하는 것이 좋습니다. 연결된 예제와 비슷한 Task과 같은 동시 기능을 올바르게 사용하고 있는지 확인하십시오. 사용자 환경에서 링크 된 샘플이 작동하는지 확인하십시오. Task 및 스레드가 긴 응용 프로그램 개시가하는 것을 보장하기 위해 양산되는 방법의 주요 LongAppInit 응용 프로그램 클래스의 시작 방법에있어서, (단지 오라클 프리 로더 샘플 링크에서 복사)

소스 코드

주 JavaFX 응용 프로그램 스레드에서 발생하지 않습니다. 또한 프리 로더가 UI의 진행 상황을 실시간으로 정확하게 반영 할 수 있도록 초기화 프로세스의 현재 상태를 알 수 있도록 긴 응용 프로그램 초기화 과정에서 다양한 방법으로 응용 프로그램의 notifyPreloader() 응용 프로그램 호출 방법을 확인하십시오.

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