Cómo exportar un proyecto JavaFX en IntelliJ

¿No sabes cómo exportar tu proyecto JavaFX en IntelliJ, y te gustaría aprender? Yo también he tenido ese problema, y he dado bastantes vueltas para encontrar la solución, que te traigo en el artículo de hoy.

More...

He actualizado el curso de IntelliJ gratuito con la información de esta entrada, y además te explico cómo crear una interfaz sencilla con JavaFX y cómo aplicarle una hoja de estilos css. ¿Te lo vas a perder?

IntelliJ es el IDE (Integrated Development Environment, o Entorno de Desarrollo Integrado) en el que se basa Android Studio, y esa es la razón por la que yo, personalmente, le doy preferencia. Así, tanto si tengo que programar una app para Android o si quiero crear una aplicación de escritorio, me resulta mucho más fácil orientarme.

Pero no es todo tan fácil: mientras que en Android Studio es bastante fácil generar el archivo *.apk que vas a subir a Google Play Console, generar un archivo *.jar ejecutable en IntelliJ con una interfaz diseñada con JavaFX requiere varios pasos, y algunos son muy poco intuitivos.

Sea la razón que sea por la que ocurre esto, lo esencial es cómo resolverlo, así que allá vamos.

Cómo exportar un proyecto JavaFX en IntelliJ

Si has llegado hasta aquí y no sabes utilizar IntelliJ, quizá sería mejor que hicieras el curso gratuito que regalo para suscriptores. En cualquier caso, a continuación te explicaré paso a paso cómo crear un proyecto sencillo en IntelliJ.

Crea un proyecto JavaFX en IntelliJ

Haz clic en File > New > Project...

Cómo exportar un proyecto JavaFX en IntelliJ: Crear un proyecto JavaFX en IntelliJ

A continuación, solo tienes que seleccionar el tipo de proyecto ("JavaFX") y ponerle un nombre. Verás la ruta en la que se creará el proyecto.

Cómo exportar un proyecto JavaFX en IntelliJ: selecciona el tipo de proyecto
Cómo exportar un proyecto JavaFX en IntelliJ: Ponle un nombre a tu proyecto

A continuación, vamos a convertir nuestro proyecto a Maven, para instalar fácilmente las librerías que necesitamos para utilizar JavaFX, que no están incluidas en el kit de desarrollo de Java (JDK) desde su versión 11.

Para ello, haz clic con el botón derecho en la carpeta de tu proyecto en la ventana accesoria de la izquierda y selecciona Add Framework Support...

Migra tu proyecto a Maven

Selecciona Maven y pulsa Next.

Se te abrirá el archivo pom.xml, donde aparecerá seleccionado el campo groupId. Introduce ahí la ruta hasta la clase Main. En mi caso, es sample.Main.

Inserta el ID

Selecciona Enable Auto-Import en el pop-up que aparece en la esquina inferior derecha.

Enable auto import

Importa las librerías de JavaFX

Como ya te he dicho más arriba, JavaFX es un módulo aparte que tendrás que incluir en tu proyecto. Copia y pega el siguiente texto en tu archivo pom.xml, debajo de la versión y encima de la etiqueta de cierre del proyecto (</project>).

Si ejecutas ahora el proyecto, verás que aparece un nuevo problema:

Error Java 5

Por alguna razón, cada vez que modificas el archivo pom la versión del proyecto se resetea a Java 5. Tendrás que corregir este valor en dos lugares:

  • El archivo .iml (el nombre de este archivo es el nombre de tu proyecto; en mi caso, AdivinaElNumero.iml): 
Cambiar la version de Java de 5 a 8

Yo utilizo como mínimo la versión 8, así yo pondré JDK_1_8.

  • La configuración de IntelliJ. Pulsa Ctrl + Alt + S para abrir la ventana de configuración (Settings). El valor que necesitas cambiar (Target bytecode version) está en Build, Execution, Deployment > Compiler > Java Compiler.
Cambiar la configuracion de IntelliJ

Si quieres echarle un vistazo al código de todo el proyecto, puedes encontrarlo en GitHub.

Modifica la configuración de la máquina virtual en IntelliJ

Ahora tendrás que descargar el JavaFX SDK de https://gluonhq.com/products/javafx/. Es un archivo zip; cuando lo hayas descargado, extrae todos los archivos y anota la ruta hasta la carpeta lib.

A continuación, en IntelliJ haz clic en Run > Edit Configurations...

Cambiar la configuración de ejecución

Introduce la siguiente línea en VM options:

--module-path C:\<ruta completa>\javafx-sdk-<versión más reciente>\lib --add-modules=javafx.controls,javafx.fxml

Cuando yo la descargué, la última versión del JavaFX SDK era la 13.0.2; es posible que para cuando tú leas esto haya otra versión más reciente.

Configuracion de ejecución en IntelliJ

Corrige la localización del archivo .fxml

Aún queda algo más que tienes que hacer para que tu aplicación se ejecute con normalidad en IntelliJ (esta es solo la primera parte de cómo exportar un proyecto JavaFX en IntelliJ; ya ves cuánto hay que hacer solo para hacerlo funcionar).

Si ejecutas tu aplicación (Alt + Mayús + F10), aparece el siguiente error:

Dirección no especificada en Main IntelliJ

Esto significa que la ruta del archivo *.fxml, que es el que define la interfaz, es incorrecta. En lugar de encontrarse dentro de la carpeta resources, está dentro de la carpeta java/sample. Arrástralo a la posición correcta y verás un pequeño cambio en el código:

Antes de mover el archivo a resources:

Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));

Después:

Parent root = FXMLLoader.load(getClass().getResource("/sample.fxml"));

(Si no lo ves, es la barra / delante de sample.fxml). Si ejecutas ahora el código, verás que funciona.

Crea el artefacto del proyecto como JAR

Una vez que ya tenemos el proyecto creado un funcionando, lo siguiente será exportarlo como archivo ejecutable. Como ya te he dicho más arriba, tuve que darle bastantes vueltas (y buscar mucho en Google) hasta que di con la forma correcta o, por lo menos, con una de ellas.

Para crear el artefacto, pulsa Ctrl + Alt + Mayúsc + S o File > Project Structure.

Ventana de Project Structure IntelliJ

Pulsa Alt + Insertar, o haz clic en el signo + de la parte superior, y selecciona, Y ESTO ES MUY IMPORTANTE, JAR > From modules with dependencies..., y NO JavaFx Application.

Create JAR from modules

En Main Class, haz clic en el icono de la carpeta para seleccionar la clase Main, selecciona qué hacer con los archivos JAR de otras librerías (si has utilizado alguna. Yo suelo seleccionar copy to the output...)  y pulsa OK.

Te aparecerá una pantalla similar a la siguiente:

Crea la carpeta META-INF

A continuación, tienes que hacer algo que IntelliJ no hace de manera automática:

  • Selecciona la carpeta de compile output  que aparece dentro del jar en la lista.
  • Crea una carpeta y llámala META-INF.
  • Selecciona File y busca el archivo de MANIFEST:
Selecciona File
Cómo exportar un proyecto JavaFX en IntelliJ: Busca el archivo de MANIFEST

Dale OK a todo.

¡Ya casi estás! A continuación, "construye" el artefacto, haciendo clic en Build > Build Artifacts..., selecciona el artefacto que acabas de construir en el pequeño pop-up que aparece y haz clic en Build de nuevo.

Cómo exportar un proyecto JavaFX en IntelliJ: Build Artifact en IntelliJ

El archivo .jar ejecutable aparecerá en la carpeta out:

Cómo exportar un proyecto JavaFX en IntelliJ: Dónde encontrar el jar en IntelliJ

Para abrir la carpeta en la que se encuentra, haz clic con el botón derecho en el jar ahí mismo, y selecciona Show in Explorer.

Crea un script para ejecutar el jar

Pero aún no ha terminado todo. Si haces doble clic en el jar, te aparece un pop-up de aviso ERROR: invalid or corrupt jar file.

Lo siguiente que tendrás que hacer es un pequeño script que podrás ejecutar desde donde quieras, como un acceso directo. ¿Recuerdas que tuviste que descargar el SDK de JavaFX e introducir la ruta en la configuración de ejecución? Pues ahora tienes que hacer algo parecido.

Crea un archivo de texto plano con el siguiente texto:

Guárdalo con la extensión .bat y ¡ya está!

Conclusión: ¿por qué es tan complicado?

Muy buena pregunta, y me imagino que los únicos que tienen la respuesta son l@s chic@s que trabajan en IntelliJ. He tardado bastante tiempo en encontrar toda la información necesaria sobre cómo exportar un proyecto JavaFX en IntelliJ, y me sorprende que sea tan poco intuitivo.

Por ejemplo, que a la hora de crear el artefacto no se seleccione JavaFX, sino JAR, como si fuera un proyecto sin interfaz. Y todos los pasos no automáticos que hay que realizar. Es como si oficialmente se ofreciera una opción para crear interfaces, pero al mismo tiempo dificultando su uso dejándolo como un módulo independiente.

En cualquier caso, este método funciona y, si algún día resumen todo esto a un simple clic en un botón con el título "Exportar", creo que todos estaremos muy contentos.