Solución a la excepción de carga JavaFX FXML

Mehvish Ashiq 15 febrero 2024
  1. Razones que causan la excepción de carga JavaFX FXML
  2. Solución a la excepción de carga JavaFX FXML
Solución a la excepción de carga JavaFX FXML

Este tutorial educa sobre las razones que causan la excepción de carga JavaFX FXML y proporciona una solución rápida.

Razones que causan la excepción de carga JavaFX FXML

La primera razón para obtener la excepción de carga JavaFX FXML es cuando la ruta a un archivo FXML no se especifica correctamente en un cargador. La ruta /fxml/view.fxml se refiere a un archivo view.fxml en una carpeta llamada fxml que reside en la carpeta resources, es decir, en el classpath.

La llamada getClass().getResource() invoca un objeto classloader en tiempo de ejecución, que busca el classpath de un recurso que se le pasa. De esta forma, encontrará la carpeta fxml y el archivo view.fxml dentro de esa carpeta.

La segunda razón puede ser tener una ID de componente que no coincida, lo que significa que es posible que hayamos actualizado una ID de componente en nuestro archivo Controller, pero olvidamos cambiar esa ID en el archivo FXML (o viceversa). En este caso, el Controller no podría vincular ese componente en el archivo view.fxml.

Consulte el siguiente fragmento para tener una comprensión clara.

En el archivo Controller:

@FXML
Button btnName1

En el archivo FXML View:

fx:id="btnName_1"

A continuación se muestra la solución a ambas razones.

Solución a la excepción de carga JavaFX FXML

Para ejecutar esta aplicación, usamos Java 18, JavaFX 13 y NetBeans IDE versión 13. Puede usarlos todos según su elección.

Código de ejemplo (archivo view.fxml, el archivo de vista):

<!--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>

A continuación se muestra la explicación paso a paso del código anterior.

  • Escribimos una declaración XML describiendo la versión y la codificación.
  • Importe todos los tipos de Java necesarios en FXML.
  • Usamos la etiqueta AnchorPane para declarar el prefijo del espacio de nombres fx. Esta etiqueta permite anclar los bordes de los nodos secundarios al desplazamiento desde un borde del panel de anclaje.

    Si hay relleno o borde en el panel de anclaje, los desplazamientos se medirán desde los bordes interiores de esos insertos. La etiqueta AnchorPane tiene varias propiedades que se enumeran a continuación con una breve explicación.

    • Las propiedades prefHeight y prefWidth se pueden usar para anular la altura y el ancho preferidos calculados de la región.
    • En FXML, el fx:controller se usa para especificar el controlador en un elemento root. Recuerde que se nos permite tener un controlador por documento FXML y debe especificarse en el elemento root.

    ¿Cuál es el elemento root en este código? La etiqueta AchnorPane es el elemento root de este ejemplo de código, que es un objeto de nivel superior en un gráfico de objetos del documento FXML.

    Todos los elementos de la interfaz de usuario se agregarán a este elemento. Además, también necesitamos conocer las reglas que debe cumplir un controlador; estas reglas se enumeran a continuación:

    • Un controlador es instanciado por el cargador FXML.
    • Un controlador debe tener el constructor público no-args. El cargador FXML no podría crear una instancia si no está allí, lo que generaría una excepción en el momento de la carga.
    • Un controlador puede contener funciones accesibles que también se pueden especificar como controladores de eventos en FXML.
    • El controlador FXML busca automáticamente las variables de instancia accesibles de un controlador. Si el nombre de la variable de instancia accesible coincide con el atributo fx:id de un elemento, una referencia de objeto del FXML se copiará automáticamente en una variable de instancia del controlador.

    Esta función hará que las referencias de los elementos de la interfaz de usuario en el FXML sean accesibles para el controlador. Entonces, el controlador podría usarlos.

    • Un controlador también puede acceder a la función initialize(), que no debe aceptar argumentos y devolver el tipo void. Una vez que se completa el proceso de carga del documento FXML, el cargador FXML llama a la función initialize().
  • En FXML, los paneles de diseño contienen los elementos secundarios como sus elementos secundarios. Teniendo en cuenta los requisitos del proyecto, podemos agregar etiquetas, botones y otros elementos.

Código de ejemplo (clase viewController.java, la clase del controlador):

// 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

La clase viewController.java es una clase de controlador que usa la anotación @FXML en algunos miembros. Recuerde que esta anotación se puede usar en constructores y clases.

Usando esta anotación, especificamos que el cargador FXML puede acceder fácilmente a este miembro incluso si es privado. No necesitamos usar la anotación @FXML si el cargador FXML usa un miembro público.

Sin embargo, usar @FXML para un miembro público no genera ningún error. Por lo tanto, es bueno anotar cada miembro.

El siguiente FXML establece la función onBtTestAction() de una clase de controlador como controlador de eventos para el Button:

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

Código de ejemplo (clase App.java, la clase principal):

// 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

El archivo principal extiende la clase Application y anula su método abstracto start(). En el método start(), cargamos el archivo view.fxml, creamos una escena, configuramos esta escena en un escenario y mostramos ese escenario.

SALIDA (imprime la palabra CLICK en la consola del IDE cada vez que hacemos clic en el Botón):

Solución a la excepción de carga JavaFX fxml - Salida

Verifique la siguiente captura de pantalla para colocar cada archivo en la ubicación correcta:

Solución a la excepción de carga JavaFX fxml - Directorio de archivos

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

Artículo relacionado - Java JavaFX