web-dev-qa-db-fra.com

Exception "emplacement requis" lors du chargement du fichier FXML

J'essaie de charger le fichier FXML et de l'afficher comme une fenêtre d'application, mais j'obtiens une exception. Le fichier FXML a été créé par FXML Scene Builder.

Voici les codes pour la classe 

public class Main extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setScene(FXMLLoader.load(getClass().getResource("sample.fxml")));
        primaryStage.show();
    }
}

et fichier FXML

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.AnchorPane?>
<TitledPane animated="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
            prefHeight="400.0" prefWidth="600.0" text="Pass4D" xmlns:fx="http://javafx.com/fxml/1"
            xmlns="http://javafx.com/javafx/8">
    <content>
        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
            <children>
                <Button layoutX="211.0" layoutY="134.0" mnemonicParsing="false" prefHeight="33.0" prefWidth="177.0"
                        text="Log in"/>
                <Button layoutX="212.0" layoutY="170.0" mnemonicParsing="false" prefHeight="33.0" prefWidth="175.0"
                        text="Exit"/>
            </children>
        </AnchorPane>
    </content>
</TitledPane>

Et voici l'exception que je reçois

Exception in Application start method
Exception in thread "main" 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$launchApplication$147(LauncherImpl.Java:157)
    at com.Sun.javafx.application.LauncherImpl$$Lambda$1/2074407503.run(Unknown Source)
    at Java.lang.Thread.run(Thread.Java:745)
Caused by: Java.lang.NullPointerException: Location is required.
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.Java:3201)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.Java:3169)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.Java:3142)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.Java:3118)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.Java:3098)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.Java:3091)
    at Pass4D.start(Pass4D.Java:19)
    at com.Sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.Java:821)
    at com.Sun.javafx.application.LauncherImpl$$Lambda$51/317090070.run(Unknown Source)
    at com.Sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.Java:323)
    at com.Sun.javafx.application.PlatformImpl$$Lambda$47/1833150059.run(Unknown Source)
    at com.Sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.Java:292)
    at com.Sun.javafx.application.PlatformImpl$$Lambda$49/2115863517.run(Unknown Source)
    at Java.security.AccessController.doPrivileged(Native Method)
    at com.Sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.Java:291)
    at com.Sun.javafx.application.PlatformImpl$$Lambda$48/1436737924.run(Unknown Source)
    at com.Sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.Java:95)

Qu'est-ce que je fais mal?

p.s. voici la structure du projet

enter image description here

12
Carmine

La réponse courte est getClass().getResource("sample.fxml") renvoie null de manière silencieuse si la ressource est introuvable sur le runtime classpath , pas le répertoire en cours, etc. 

Cela dépend donc de la configuration de votre projet IDE. Si vous utilisez Eclipse, essayez d’ajouter le dossier dans lequel sample.fxml réside dans la configuration d’exécution.

Quelques idées...

  • essayez getClass().getResource("/sample.fxml") à la place ...
  • essayez de déplacer sample.fxml dans le dossier des ressources. Je ne connais pas grand-chose à propos de votre IDE, mais je soupçonne que ce dossier n'est utilisé que pour les fichiers .Java ... c'est tout à fait vrai pour les projets de dégradés dans Eclipse - les ressources doivent figurer dans l'arborescence src/main/resources, car seul ce dernier est ajouté à l'exécution. classpath ...
14
Adam

J'ai déjà posté ceci aujourd'hui, alors voici encore une fois, j'espère que cela vous aide.

Voici une solution qui fonctionne dans l'environnement de développement, dans Scene Builder et dans un fichier JAR empaqueté.

La structure du dossier:

enter image description here

Main.Java:

package application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;


public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {

            FXMLLoader loader = new FXMLLoader(Main.class.getResource("view/RootLayout.fxml"));
            AnchorPane rootLayout = (AnchorPane) loader.load();

            Scene scene = new Scene(rootLayout, 400, 400);
            scene.getStylesheets().add(getClass().getResource("css/application.css").toExternalForm());

            primaryStage.setScene(scene);
            primaryStage.show();

        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

RootLayout.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import Java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.view.RootLayoutController">
   <children>
      <Pane layoutX="0.0" layoutY="0.0" prefHeight="200.0" prefWidth="200.0">
         <children>
            <Button fx:id="sunButton" layoutX="74.0" layoutY="88.0" mnemonicParsing="false" onAction="#handleSunButtonClick" styleClass="Sun-button" stylesheets="@../css/toolbar.css" text="Button" />
         </children>
      </Pane>
   </children>
</AnchorPane>

RootLayoutController.Java:

package application.view;

import javafx.fxml.FXML;
import javafx.scene.control.Button;

public class RootLayoutController {


    @FXML
    Button sunButton;

    @FXML
    public void handleSunButtonClick() {
        System.out.println( "Button clicked");
    }
}

toolbar.css:

.Sun-button {
  -fx-graphic: url('./icons/Sun.png');
}

application.css:

.root {
    -fx-background-color:lightgray;
}

Sun.png:

enter image description here

Cela fonctionne à la fois dans l'environnement de développement et dans le package du fichier JAR (choisissez "Extraire les bibliothèques requises dans le fichier JAR généré" dans Eclipse).

Capture d'écran (juste un bouton avec une icône chargée via css)

enter image description here

2
Roland

Essayez cet exemple d'Oracle:

 @Override
public void start(Stage stage) throws Exception {
   Parent root = FXMLLoader.load(getClass().getResource("fxml_example.fxml"));

    Scene scene = new Scene(root, 300, 275);

    stage.setTitle("FXML Welcome");
    stage.setScene(scene);
    stage.show();
}
1
Johan

Main.class.getResource a fonctionné pour moi. J'essayais d'obtenir des ressources de la sous-classe au lieu de la classe principale. J'y ai utilisé getClass (). GetResource () qui pointait vers la classe actuelle. Je n'avais pas mes fichiers FXML dans le répertoire des ressources.

0
kaidoj