Lösung für die JavaFX FXML Load Exception

Mehvish Ashiq 15 Februar 2024
  1. Ursachen für die Ausnahme beim Laden von JavaFX FXML
  2. Lösung für die JavaFX FXML-Ladeausnahme
Lösung für die JavaFX FXML Load Exception

Dieses Tutorial informiert über die Gründe, die die JavaFX FXML-Ladeausnahme verursachen, und bietet eine schnelle Lösung.

Ursachen für die Ausnahme beim Laden von JavaFX FXML

Der erste Grund für das Erhalten der JavaFX FXML-Ladeausnahme ist, wenn der Pfad zu einer FXML-Datei für einen Loader nicht korrekt angegeben ist. Der Pfad /fxml/view.fxml verweist auf eine Datei view.fxml in einem Ordner namens fxml, der sich im Ordner resources befindet, d. h. auf dem classpath.

Der Aufruf getClass().getResource() ruft zur Laufzeit ein Objekt classloader auf, das nach dem classpath einer ihm übergebenen Ressource sucht. Auf diese Weise findet es den Ordner fxml und die Datei view.fxml in diesem Ordner.

Der zweite Grund kann eine nicht übereinstimmende Komponenten-ID sein, was bedeutet, dass wir möglicherweise eine Komponenten-ID in unserer Controller-Datei aktualisiert, aber vergessen haben, diese ID in der FXML-Datei zu ändern (oder umgekehrt). In diesem Fall wäre der Controller nicht in der Lage, diese Komponente in der view.fxml-Datei zu verlinken.

Sehen Sie sich den folgenden Abschnitt an, um ein klares Verständnis zu haben.

Auf der Datei Controller:

@FXML
Button btnName1

Auf der FXML View-Datei:

fx:id="btnName_1"

Im Folgenden finden Sie die Lösung für diese beiden Gründe.

Lösung für die JavaFX FXML-Ladeausnahme

Um diese Anwendung auszuführen, verwenden wir Java 18, JavaFX 13 und NetBeans IDE Version 13. Sie können alle nach Ihrer Wahl verwenden.

Beispielcode (Datei view.fxml, die Ansichtsdatei):

<!--Step1: XML declaration-->
<?xml version="1.0" encoding="UTF-8"?>

<!--Step 2: import necessary java types in FXML-->

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>

<!--Step 3: specify the FXML namespace-->

<AnchorPane prefHeight="300.0" prefWidth="400.0"
xmlns="http://javafx.com/javafx/11.0.1"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.mycompany.javafx_fxml_loadexception.viewController">

    <!--Step 4: layout pane have children-->
    <children>
        <Button fx:id="btTest" layoutX="170.0"
        layoutY="208.0" mnemonicParsing="false"
        onAction="#onBtTestAction" text="Button" />

        <Label layoutX="167.0" layoutY="126.0" text="Cick here!" />
   </children>

</AnchorPane>

Es folgt die Schritt-für-Schritt-Erklärung des obigen Codes.

  • Wir schreiben eine XML-Deklaration, indem wir die Version und Kodierung beschreiben.
  • Importieren Sie alle erforderlichen Java-Typen in FXML.
  • Wir verwenden das Tag AnchorPane, um das Namespace-Präfix fx zu deklarieren. Dieses Tag ermöglicht es, die Kanten der untergeordneten Knoten mit dem Versatz von einer Kante des Ankerbereichs zu verankern.

    Wenn im Ankerbereich eine Polsterung oder ein Rand vorhanden ist, werden die Versätze von den Innenkanten dieser Einfügungen aus gemessen. Das AnchorPane-Tag hat verschiedene Eigenschaften, die unten mit einer kurzen Erklärung aufgeführt sind.

    • Die Eigenschaften prefHeight und prefWidth können verwendet werden, um die berechnete bevorzugte Höhe und Breite der Region zu überschreiben.
    • In FXML wird der fx:controller verwendet, um den Controller auf einem root-Element anzugeben. Denken Sie daran, dass wir einen Controller pro FXML-Dokument haben dürfen und dieser im root-Element angegeben werden muss.

    Was ist das root-Element in diesem Code? Das AchnorPane-Tag ist das root-Element für dieses Codebeispiel, das ein Objekt der obersten Ebene in einem Objektdiagramm des FXML-Dokuments ist.

    Alle UI-Elemente werden diesem Element hinzugefügt. Darüber hinaus müssen wir auch die Regeln kennen, die ein Verantwortlicher erfüllen muss; Diese Regeln sind unten aufgeführt:

    • Ein Controller wird durch den FXML-Loader instanziiert.
    • Ein Controller muss den öffentlichen Konstruktor no-args haben. Der FXML-Loader könnte es nicht instanziieren, wenn es nicht vorhanden ist, was zu einer Ausnahme beim Laden führen würde.
    • Ein Controller kann zugängliche Funktionen enthalten, die auch als Ereignishandler in FXML angegeben werden können.
    • Der FXML-Controller sucht automatisch nach zugänglichen Instanzvariablen eines Controllers. Wenn der Name der zugänglichen Instanzvariablen mit dem Attribut fx:id eines Elements übereinstimmt, wird automatisch eine Objektreferenz aus dem FXML in eine Controller-Instanzvariable kopiert.

    Diese Funktion macht die Referenzen der UI-Elemente in FXML für den Controller zugänglich. Dann wäre der Controller in der Lage, sie zu verwenden.

    • Ein Controller kann auch auf die Funktion initialize() zugreifen, die keine Argumente akzeptieren darf und den Typ void zurückgibt. Sobald der Ladevorgang des FXML-Dokuments abgeschlossen ist, ruft der FXML-Loader die initialize()-Funktion auf.
  • In FXML enthalten die Layoutfenster die untergeordneten Elemente als untergeordnete Elemente. Unter Berücksichtigung der Projektanforderungen können wir Beschriftungen, Schaltflächen und andere Elemente hinzufügen.

Beispielcode (Klasse viewController.java, die Controller-Klasse):

// Step 1: replace this package name with your package name
package com.mycompany.javafx_fxml_loadexception;

// Step 2: import necessary libraries
import javafx.fxml.FXML;
import javafx.scene.control.Button;

// Step 3: viewController class
public class viewController {
  // define button
  @FXML private Button btTest;

  // define the action when the button is clicked
  @FXML
  public void onBtTestAction() {
    System.out.println("CLICK");
  } // end onBtTestAction method

} // end viewController class

Die Klasse viewController.java ist eine Controller-Klasse, die bei einigen Mitgliedern die Annotation @FXML verwendet. Denken Sie daran, dass diese Anmerkung für Konstruktoren und Klassen verwendet werden kann.

Mit dieser Anmerkung geben wir an, dass der FXML-Loader problemlos auf dieses Mitglied zugreifen kann, auch wenn es privat ist. Wir müssen die Annotation @FXML nicht verwenden, wenn der FXML-Loader ein öffentliches Mitglied verwendet.

Die Verwendung von @FXML für ein öffentliches Mitglied löst jedoch keinen Fehler aus. Es ist also gut, jedes Mitglied zu kommentieren.

Das folgende FXML setzt die Funktion onBtTestAction() einer Controller-Klasse als Eventhandler für den Button:

<Button fx:id="btTest" layoutX="170.0" layoutY="208.0" mnemonicParsing="false"         onAction="#onBtTestAction" text="Button" />

Beispielcode (Klasse App.java, die Hauptklasse):

// Step 1: replace the package name with your package name
package com.mycompany.javafx_fxml_loadexception;

// Step 2: import necessary libraries
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

// Step 3: primary launch class extending the Application class
public class App extends Application {
  /**
   *
   * @param stage
   */
  @Override
  public void start(Stage stage) {
    // load the view.fxml file, add it to the scene and show it
    try {
      Parent parent = FXMLLoader.load(getClass().getResource("/fxml/view.fxml"));
      // create a scene
      Scene scene = new Scene(parent);
      // set scene to a stage
      stage.setScene(scene);
      // show the stage
      stage.show();
    } // end try
    catch (IOException e) {
      e.printStackTrace();
    } // end catch
  } // end start method

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

} // end App class

Die Hauptdatei erweitert die Klasse Application und überschreibt ihre abstrakte Methode start(). In der Methode start() laden wir die Datei view.fxml, erstellen eine Szene, setzen diese Szene auf eine Bühne und zeigen diese Bühne an.

OUTPUT (druckt das Wort CLICK auf der IDE-Konsole, wenn wir auf den Button klicken):

Lösung für die Ausnahme beim Laden von JavaFX fxml - Ausgabe

Überprüfen Sie den folgenden Screenshot, um jede Datei an der richtigen Stelle zu platzieren:

Lösung für JavaFX fxml Load Exception - Dateiverzeichnis

Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook

Verwandter Artikel - Java JavaFX