[英]Why does my JavaFX Preloader occasionally show up gray/black and other times it correctly loads?
我試圖讓我的JavaFX Preloader啟動畫面顯示在我的應用程序之前。 我使用的是Eclipse IDE,當我單擊“運行”時,啟動屏幕將正確顯示一半時間,另一半時間將顯示灰屏或黑屏,而不是圖像應顯示的位置。
我不確定是什么原因導致它有時只能正確顯示。
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();
}
}
然后在我的主要課程Demo中,我簡單地擁有:
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);
}
}
您可能正在JavaFX應用程序線程或應用程序啟動中涉及的線程上執行一些長時間運行的進程,這會阻止預加載器的順利運行。
建議您查看一個Oracle Preloader示例並將其與您的應用程序進行比較。 與鏈接的示例類似,請確保正確使用諸如Task之類的並發功能。 檢查鏈接的示例在您的環境中是否有效。
源代碼(僅從Oracle Preloader示例鏈接復制)
請注意如何在LongAppInit
主應用程序類的start方法中生成一個Task和線程,以確保JavaFX應用程序線程上不會進行長時間的應用程序初始化。 另請參閱如何在長時間的應用程序初始化期間的不同時間調用應用程序的notifyPreloader()
方法,以使預加載器了解初始化過程的當前狀態,以便它可以在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();
}
});
}
}
});;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.