¿Cómo hacer referencia a archivos javafx fxml en la carpeta de recursos?
Estoy creando una aplicación GUI javafx y mi proyecto es un proyecto configurado por Maven. Quiero poder hacer referencia a mis archivos fxml de esta manera en mis controladores:
FXMLLoader.load(getClass().getResource("main.fxml"));
Donde mi archivo main.fxml se encuentra en la carpeta src/main/resources y mi controlador está en la carpeta src/main/java. ¿Cómo voy a hacer esto? Mi carpeta src/main/resources está en la ruta de compilación y puedo llamar a un archivo .properties que está en la carpeta src/main/resources desde una clase en la carpeta src/main/java.
Editar
Intenté colocar el archivo fxml en el directorio correspondiente de la carpeta principal de recursos:
pero todavía recibo un error.
Información de búsqueda de recursos genéricos
Esta respuesta analiza la búsqueda de ubicación FXML, que en realidad es solo un subconjunto de la tarea de búsqueda de recursos genérica en Java. El programa que llama pasa la ubicación del recurso como entrada al FXMLLoader, por lo que la búsqueda de recursos en sí es parte del código de la aplicación que llama y no del FXMLLoader.
Para obtener una cobertura completa de información genérica de recursos (incluidos los pasos recomendados para la solución de problemas) para aplicaciones Java/JavaFX, consulte:
- ¿Cómo puedo determinar la ruta correcta para archivos FXML, archivos CSS, imágenes y otros recursos que necesita mi aplicación JavaFX?
También es útil la guía de recursos de codificación de Eden:
- Dónde colocar archivos de recursos en JavaFX
Uso de ejemplo
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/main.fxml"));
Parent content = loader.load();
Opciones de resolución de ubicación
Coloque todo su fxml en el directorio src/main/resources.
loader.setLocation(getClass().getResource("/main.fxml"));
Coloque todo su fxml en un directorio src/main/resources/fxml.
loader.setLocation(getClass().getResource("/fxml/main.fxml"));
Coloque fxml en el directorio de recursos correspondiente; por ejemplo, src/main/resources/com/mycompany/myapp.
loader.setLocation(getClass().getResource("main.fxml"));
La última opción supone que la clase desde la que está cargando el fxml está en la misma ubicación relativa en la jerarquía de origen Java correspondiente. Por ejemplo, puede invocar el último comando de carga desde la fuente com/mycompany/myapp/Main.java
.
Recomendaciones de uso de FXMLLoader
Cree una instancia de un FXMLLoader
new FXMLLoader()
en lugar de utilizar los métodos estáticos en el FXMLLoader .- Los métodos estáticos se vuelven confusos cuando desea obtener valores (como controladores instanciados) de un cargador.
Establezca la ubicación en el FXMLLoader instanciado y llame
load()
en lugar de cargar desde una secuencia usandoload(stream)
.- Configurar una ubicación basada en URL en el cargador permite la resolución de recursos relativos cargados en archivos fxml y css. Los recursos relativos no se resuelven para un constructor basado en secuencias.
Para derivar una ubicación basada en una clase, use
getClass().getResource()
, ya que está basado en URL, en lugar degetClass().getResourceAsStream()
que esté basado en secuencias.
IDE y configuración de compilación
Asegúrese de que su IDE o herramienta de compilación esté copiando los archivos fxml del directorio de recursos al directorio de salida de la compilación. Para comprender la configuración de Intellij para esto, consulte: Cómo convertir un proyecto java normal en intellij en un proyecto JavaFx .
Una nota sobre las aplicaciones modulares de Java Jigsaw
Ver:
- Cómo acceder a recursos usando el cargador de clases en Java 9
Específicamente, no escribas:
ComboBoxStyling.class.getClassLoader()
.getResource("/css/styleclass.css");
En su lugar escribe:
ComboBoxStyling.class
.getResource("/css/styleclass.css");
Es decir, obtenga el recurso de la clase directamente, NO del cargador de clases. Si obtiene recursos de un cargador de clases en lugar de la clase, existen restricciones adicionales en la búsqueda basadas en la configuración del módulo. Estas restricciones pueden ser difíciles de entender; consulte la documentación de los métodos Class
y para obtener información si es necesario.ClassLoader
getResource
Estás utilizando FXMLLoader fxmlLoader = new FXMLLoader( getClass().getResource("main.fxml") );
para cargar tu main.fxml. Esto requiere que main.fxml y la clase java lo carguen en el mismo directorio/ruta. Si desea cargar un archivo fxml desde una ruta/ubicación diferente de la clase Java que lo carga, debe usar una ruta relativa. Como @jewelsea mencionó anteriormente, puede usar la ruta relativa usando el carácter / antes de su main.fxml. Entonces el código que hará que funcione para usted en su caso es
FXMLLoader fxmlLoader = new FXMLLoader( getClass().getResource("/main.fxml") );