启动画面未加载 mainFxml 文件

splash Screen not load the mainFxml file

我正在尝试制作像这样的启动画面 SplashScreen ,但是我的代码不会加载 mainFxml.fxml ...每件事情都很好 我认为启动画面加载得很好但是加载后我收到此错误:

`Exception in Application start method
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at istehkakat.Istehkakat.changed(Istehkakat.java:163)
    at istehkakat.Istehkakat.changed(Istehkakat.java:157)
    at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
    at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:105)
    at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
    at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:145)
    at javafx.concurrent.Task.setState(Task.java:693)
    at javafx.concurrent.Task$TaskCallable.lambda$call3(Task.java:1420)
    at javafx.concurrent.Task$TaskCallable$$Lambda7/1990300023.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null4(PlatformImpl.java:292)
    at com.sun.javafx.application.PlatformImpl$$Lambda/1527683020.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater5(PlatformImpl.java:291)
    at com.sun.javafx.application.PlatformImpl$$Lambda/1174361318.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication.lambda$null(GtkApplication.java:126)
    at com.sun.glass.ui.gtk.GtkApplication$$Lambda/1768305536.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:363)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:303)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:875)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication7(LauncherImpl.java:157)
    at com.sun.javafx.application.LauncherImpl$$Lambda/1972439101.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
    at istehkakat.Istehkakat.showMainStage(Istehkakat.java:130)
    at istehkakat.Istehkakat.start(Istehkakat.java:103)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication13(LauncherImpl.java:821)
    at com.sun.javafx.application.LauncherImpl$$Lambda4/86108265.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait6(PlatformImpl.java:323)
    at com.sun.javafx.application.PlatformImpl$$Lambda/1717159510.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null4(PlatformImpl.java:292)
    at com.sun.javafx.application.PlatformImpl$$Lambda/1527683020.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater5(PlatformImpl.java:291)
    at com.sun.javafx.application.PlatformImpl$$Lambda/1174361318.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication.lambda$null(GtkApplication.java:126)
    at com.sun.glass.ui.gtk.GtkApplication$$Lambda/1768305536.run(Unknown Source)
    ... 1 more
Exception running application istehkakat.Istehkakat
Java Result: 1`

我的主要 java class 是:

/*
 * 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 istehkakat;

import controller.MainFxmlController;
import java.io.IOException;
import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.application.Preloader;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.concurrent.Worker;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.WindowEvent;
import javafx.util.Duration;

/**
 *
 * @author combozo
 */
public class Istehkakat extends Application {

    private Pane splashLayout;
    private ProgressBar loadProgress;
    private Label progressText;
    private Stage mainStage;
    private static final int SPLASH_WIDTH = 676;
    private static final int SPLASH_HEIGHT = 227;

    @Override
    public void init() {
        ImageView splash = new ImageView(new Image(getClass().getResourceAsStream("/imgs/SplashScreenIll.png")));
        loadProgress = new ProgressBar();
        loadProgress.setPrefWidth(SPLASH_WIDTH - 20);
        progressText = new Label("تحميل بيانات البرنامج ...");
        splashLayout = new VBox();
        splashLayout.getChildren().addAll(splash, loadProgress, progressText);
        progressText.setAlignment(Pos.CENTER);
        splashLayout.setStyle("-fx-padding: 5; -fx-background-color: cornsilk; -fx-border-width:5; -fx-border-color: linear-gradient(to bottom, chocolate, derive(chocolate, 50%));");
        splashLayout.setEffect(new DropShadow());
    }

    @Override
    public void start(Stage initStage) throws Exception {
        notifyPreloader(new Preloader.StateChangeNotification(Preloader.StateChangeNotification.Type.BEFORE_START));
        final Task preloaderTask = new Task() {
            @Override
            protected Object call() throws InterruptedException {
                updateMessage("Loading Chancecoin");
                /*  FXMLLoader fxmloader = new FXMLLoader();
                 Parent root = fxmloader.load(getClass().getResource("/views/mainFxml.fxml"));
                 MainFxmlController c = (MainFxmlController) fxmloader.getController();
                 Scene scene = new Scene(root);
                 //////////////////////


                 Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();


                 stage.getIcons().add(new Image(getClass().getResourceAsStream("/imgs/favIco.png")));

                 stage.setX(primaryScreenBounds.getMinX());
                 stage.setY(primaryScreenBounds.getMinY());
                 stage.setWidth(primaryScreenBounds.getWidth());
                 stage.setHeight(primaryScreenBounds.getHeight());
                 stage.setTitle("أستحــقاقــات");
                 /////////////////////////////////



                 stage.setScene(scene);
                 stage.show();

                 */
                return null;
            }
        };

        showSplash(initStage, preloaderTask);
        new Thread(preloaderTask).start();
        showMainStage();

    }

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





    private void showMainStage() throws IOException {
        // create the scene
        FXMLLoader fxmloader = new FXMLLoader();
                 Parent root = fxmloader.load(getClass().getResource("/views/mainFxml.fxml"));
                 Scene scene = new Scene(root);
                 //////////////////////


                 Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();


                 mainStage.getIcons().add(new Image(getClass().getResourceAsStream("/imgs/favIco.png")));

                 mainStage.setX(primaryScreenBounds.getMinX());
                 mainStage.setY(primaryScreenBounds.getMinY());
                 mainStage.setWidth(primaryScreenBounds.getWidth());
                 mainStage.setHeight(primaryScreenBounds.getHeight());
                 mainStage.setTitle("أستحــقاقــات");
                 /////////////////////////////////



                 mainStage.setScene(scene);
                 mainStage.show();

        mainStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent event) {
                System.exit(0);
            }
        });
    }



    private void showSplash(final Stage initStage, Task task) {
        progressText.textProperty().bind(task.messageProperty());
        loadProgress.progressProperty().bind(task.progressProperty());
        task.stateProperty().addListener(new ChangeListener<Worker.State>() {
            @Override
            public void changed(ObservableValue<? extends Worker.State> observableValue, Worker.State oldState, Worker.State newState) {
                if (newState == Worker.State.SUCCEEDED) {
                    loadProgress.progressProperty().unbind();
                    loadProgress.setProgress(1);
                    mainStage.setIconified(false);
                    initStage.toFront();
                    FadeTransition fadeSplash = new FadeTransition(Duration.seconds(1.2), splashLayout);
                    fadeSplash.setFromValue(1.0);
                    fadeSplash.setToValue(0.0);
                    fadeSplash.setOnFinished(new EventHandler<ActionEvent>() {
                        @Override
                        public void handle(ActionEvent actionEvent) {
                            initStage.hide();
                        }
                    });
                    fadeSplash.play();
                }
            }
        });

        Scene splashScene = new Scene(splashLayout);
        initStage.initStyle(StageStyle.UNDECORATED);
        final Rectangle2D bounds = Screen.getPrimary().getBounds();
        initStage.setScene(splashScene);
        initStage.setX(bounds.getMinX() + bounds.getWidth() / 2 - SPLASH_WIDTH / 2);
        initStage.setY(bounds.getMinY() + bounds.getHeight() / 2 - SPLASH_HEIGHT / 2);
        initStage.show();
    }
}

问题

您已经声明了一个 MainStage,但从未对其进行初始化。因此,在下一行中使用它会在 :

处抛出 NPE
mainStage.setIconified(false);

解决方案

您可以通过在声明时初始化 mainStage 来解决它:

private Stage mainStage = new Stage();

或者您可以在 showSplash() 中第一次使用它之前对其进行初始化:

private void showSplash(final Stage initStage, Task task) {
    ...
    mainStage = new Stage();
    mainStage.setIconified(false);
    ...
}

showMainStage() 方法中包含这一行:

Scene scene = new Scene(root);
mainStage = new Stage();   // include this

这将解决您的问题。

我环绕启动画面,我制作了一个预加载器,它对我来说很完美这是代码:

/*
 * 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 istehkakat.preloader;

import javafx.animation.FadeTransition;
import javafx.application.Preloader;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.BorderPaneBuilder;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;

/**
 * Simple Preloader Using the ProgressBar Control
 *
 * @author TattoApps
 */
public class Istehkakat_Preloader extends Preloader {

    private ProgressBar bar;
    private Stage stage;
    private boolean isEmbedded = false;

    public void start(Stage stage) throws Exception {
        isEmbedded = (stage.getWidth() > 0);
        this.stage = stage;
        stage.initStyle(StageStyle.UNDECORATED);
        stage.initStyle(StageStyle.TRANSPARENT);
        stage.setScene(createPreloaderScene());

        stage.show();
    }

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

    @Override
    public void handleStateChangeNotification(StateChangeNotification evt) {
        if (evt.getType() == StateChangeNotification.Type.BEFORE_START) {
            if (isEmbedded && stage.isShowing()) {
                // fade out, hide stage at the end of animation
                final FadeTransition ft = new FadeTransition(Duration.seconds(5.2), stage.getScene().getRoot());
                ft.setFromValue(1.0);
                ft.setToValue(0.0);
                final Stage s = stage;
                final EventHandler<ActionEvent> eh = new EventHandler<ActionEvent>() {
                    public void handle(ActionEvent t) {
                        s.hide();
                    }
                };
                ft.setOnFinished(eh);
                ft.play();
            } else {
                stage.hide();
            }
        }
    }

    private Scene createPreloaderScene() {
        bar = new ProgressBar();
        final BorderPane p = BorderPaneBuilder
                .create()
                .center(new ImageView(new Image(this.getClass()
                                        .getResourceAsStream("/imgs/SplashScreenIll.png"))))
                .bottom(bar).build();
        return new Scene(p, 676, 207, Color.TRANSPARENT);
    }
}

谢谢大家