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
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...
getClass().getResource("/sample.fxml")
à la place ...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 ...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:
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:
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)
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();
}
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.