JavaFXPorts

Las aplicaciones Java que utilizan la librería gráfica JavaFX se pueden compilar para que puedan ejecutarse en dispositivos móviles Android y iOS, además de PCs como habitualmente ocurre con las aplicaciones Java.

Para ello, se puede utilizar la herramienta JavaFXPorts que es un proyecto open source creado por Gluon para poder hacer ese tipo de compilaciones. Gluon también ofrece una extensión (Gluon Mobile IDE plugins) para los entornos de desarrollo más conocidos, con el fin de facilitar el uso de esta herramienta, pero se trata de un producto de pago, aunque con una versión gratuita que muestra una pantalla de información al ejecutar la aplicación que se realice como se muestra en la siguiente imagen:

javafxports170208 1

Por tanto, para evitar el uso de esa extensión, se realizará siguiendo las indicaciones ofrecidas en la web de documentación de JavaFXPorts.

Gradle

La herramienta JavaFXPorts recomienda utilizar Gradle como sistema de automatización para compilar las aplicaciones, ya que se encargará de descargar automáticamente las librerías necesarias. El entorno de desarrollo NetBeans utiliza por defecto Ant para esa labor, por lo que hay que instalar la extensión de Gradle en NetBeans si no se dispone de ella: Tools > Plugins.

javafxports170208 2b

Cuando haya sido instalada la extensión aparecerá el tipo de proyecto Gradle como una nueva opción al crear un nuevo proyecto en NetBeans.

javafxports170208 3

Creación de un proyecto sencillo

Para empezar a crear un proyecto sencillo para practicar, se puede utilizar el tipo de proyecto Single Gradle Project que es el más sencillo. Deberás indicar un nombre de proyecto, la localización deseada para el proyecto y el nombre deseado para la clase principal de la aplicación (precedida de un nombre de paquete, como se recomienda).

Screen Shot 2017 02 08 at 20.15.39

Al crearse el proyecto sólo aparecerá inicialmente un carpeta en su contenido, ya que durante un momento (más largo si es el primer proyecto Gradle que se crea), se estará descargando la herramienta Gradle como se puede ver en la parte inferior de NetBeans, haciendo clic en la barra de progreso que aparece.

Screen Shot 2017 02 08 at 20.19.57

Screen Shot 2017 02 08 at 20.20.26

Pasados unos instantes aparecerá todo el contenido inicial del proyecto. En la siguiente imagen se muestra su contenido con las carpetas desplegadas.

Screen Shot 2017 02 08 at 20.23.37

Agregar la extensión de JavaFXPorts a NetBeans

Hasta este momento tan sólo se ha creado un proyecto Java simple, sin hacer realmente nada directamente relacionado con la herramienta JavaFXPorts.

Para que el proyecto de NetBeans pueda hacer uso de JavaFXPorts se debe añadir en las dependencias del proyecto la extension jfxmobile-plugin, así como otros requisitos para que se pueda hacer uso de ella. Esto se debe realizar editando el contenido del archivo build.gradle que inicialmente tendrá un contenido similar al siguiente:

apply plugin: 'java'

sourceCompatibility = '1.8'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

// NetBeans will automatically add "run" and "debug" tasks relying on the
// "mainClass" property. You may however define the property prior executing
// tasks by passing a "-PmainClass=" argument.
//
// Note however, that you may define your own "run" and "debug" task if you
// prefer. In this case NetBeans will not add these tasks but you may rely on
// your own implementation.
if (!hasProperty('mainClass')) {
    ext.mainClass = 'es.javiergarciaescobedo.Main'
}

repositories {
    mavenCentral()
    // You may define additional repositories, or even remove "mavenCentral()".
    // Read more about repositories here:
    //   http://www.gradle.org/docs/current/userguide/dependency_management.html#sec:repositories
}

dependencies {
    // TODO: Add dependencies here ...
    // You can read more about how to add dependency here:
    //   http://www.gradle.org/docs/current/userguide/dependency_management.html#sec:how_to_declare_your_dependencies
    testCompile group: 'junit', name: 'junit', version: '4.10'
}

Este archivo, que es el utilizado por Gradle para realizar las compilaciones del proyecto, debe reflejar que NetBeans utilice la extensión org.javafxports.jfxmobile para poder compilar el proyecto para Android y iOS, lo cual se indicará con la línea:

apply plugin: 'org.javafxports.jfxmobile'

Esta extensión se debe descargar desde algún repositorio de Maven como mavenCentraljcenter, indicando el nombre de la extensión junto con su número de version como una nueva dependencia del proyecto. El número de versión de la última edición de jfxmobile-plugin puedes verlo en su repositorio de Bitbucket. Estos requisitos se añadirán dentro de un bloque buildscript ya que se tratan de extensiones que usará Gradle y no son librerías que use la propia aplicación que se desarrolle.

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'org.javafxports:jfxmobile-plugin:1.3.2'
    }
}

Además se debe asignar el nombre de la clase principal del proyecto al atributo mainClassName, debiendo qeudar algo como:

mainClassName = 'es.javiergarciaescobedo.Main'

Guarda los cambios del archivo build.gradle y utiliza la opción Reload Project del menú contextual del proyecto.

Screen Shot 2017 02 13 at 22.00.14 

Si todo ha ido bien, a partir de este momento (después de unos minutos si se hace por primera, al tener que realizar algunas descargas) aparecerán nuevas opciones en la opción Tasks de ese mismo menú. Podrás ver que aparecen las opciones android o ios que podrás usar más adelante.

Screen Shot 2017 02 13 at 22.03.14

Código fuente de prueba

import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Screen;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        Label label = new Label("¡Hola Mundo!");

        StackPane root = new StackPane();
        root.getChildren().add(label);

        Rectangle2D bounds = Screen.getPrimary().getVisualBounds();
        Scene scene = new Scene(root, bounds.getWidth(), bounds.getHeight());
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

Puedes usar el botón de ejecutar (Run) de NetBeans para ver el funcionamiento de la aplicación en su versión de escritorio (PC). Observarás que se ejecuta ocupando todo el tamaño de la pantalla, ya que será como se deberá ejecutar en dispositivos móviles. El tamaño de la ventana se ha indicado en la creación del objeto Scene, donde se indica que ocupe todo el alto y ancho de la pantalla.

Screen Shot 2017 02 14 at 21.24.18

Compilación y ejecución en Android

Para poder compilar el projecto de manera que pueda ser ejecutado en un dispositivo Android se deben cumplir una serie de requisitos:

  • Kit de desarrollo de Android (Android SDK) que puede descargarse desde la web de developer.android.com dentro de la sección de Android Studio. El Android SDK viene incluido con el entorno de desarrollo de Android Studio (opción recomendada) o bien se puede descargar exclusivamente el SDK. Una vez que se tenga instalado el SDK se deben descargar desde el SDK Manager al menos los siguientes paquetes (puedes ver cómo hacerlo en Actualizar el IDE y las herramientas del SDK):
    • Al menos la versión version 23.0.1 de las Build-tools.
    • SDK Platform API 21.
    • Android Support Repository.
  • Indicar dónde se encuentra instalado el Android SDK. Este puede hacerse en el archivo .gradle/gradle.properties que se debe almacenar en la carpeta personal del usuario, con un contenido similar al siguiente (se debe indicar la ubicación exacta del SDK):
    • En Windows (hay que tener en cuenta que hay que usar la barrra / en lugar de \ para indicar la ruta):
      • ANDROID_HOME=C:/Users/USUARIO/AppData/Local/Android/Sdk
    • En Mac OS:
      • ANDROID_HOME=/Users/USUARIO/Library/Android/sdk

Puedes encontrar la ruta al abrir el SDK Manager:

Captura1702151302

Ejecución en dispositivo Android conectado

Si se desea ejecutar en un dispositivo Android una aplicación desarrollada por tí, debes habilitar la depuración USB como se indica en la web de desarrollo Android (Ejecutar apps en un dispositivo de hardware):

Para acceder a esta configuración, abre Developer options en Settings. En Android 4.2 y versiones posteriores, la pantalla Developer options está oculta de manera predeterminada. Para que se muestre, dirígete a Settings > About phone y toca Build number siete veces. Cuando regreses a la pantalla anterior, verás que Developer options aparecerá en la parte inferior.

Una vez activadas las Developer options, activa la opción de Depuración USB.

Además debes tener en cuenta que el equipo de desarrollo debe tener instalado el controladores USB de OEM correspondiente al modelo del dispositivo Android conectado.

Para ejecutar la aplicación en un dispositivo Android que se encuentre conectado por USB al equipo donde se esté desarrollando, se debe usar la opción Tasks > android > androidInstall del menú contextual del proyecto en NetBeans.

Observa en la ventana Output que finaliza correctamente la compilación, que debe mostrar el mensaje Installed on device. que indicará que la aplicación se ha instalado en el dispositivo.

Screen Shot 2017 02 14 at 21.42.15

Accede a la lista de aplicaciones de tu dispositivo donde podrás encontrar el icono correspondiente a esta aplicación, con el nombre que hayas asignado al proyecto. Al ejecutarla deberá aparecer el mensaje "¡Hola Mundo!" como se ha indicado en el código fuente de la aplicación.

Screenshot 20170214 214246

Ejecución en dispositivo Android virtual

El kit de desarrollo de Android (SDK) incorpora la herramienta AVD que permite crear dispositivos Android virtuales en los que puedes ejecutar las aplicaciones desarrolladas. Para poder ejecutar aplicaciones compiladas con JavaFXPorts, no se pueden utilizar dispositivos virtuales con CPU de tipo Intel (se obtiene el error INSTALL_FAILED_NO_MATCHING_ABIS al intentar la instalación), sino que deben ser con CPU de tipo ARM, con el inconveniente de que no se aprovecha el acelerador hardware de máquinas virtuales de Intel, por lo que la ejecución del dispositivo virtual resulta muy lenta.

Otra opción alternativa es utilizar la aplicación BlueStacks, que se trata de un emulador Android para la ejecución de aplicaciones de dicho sistema. Por las pruebas que he realizado, la ejecución es más rápida aunque no se tienen tantas opciones de configuración como en el AVD del SDK y se ejecuta en una pantalla de tamaño tablet.

Con BlueStacks no se puede utilizar la instalación directa que ofrecía la opción androidInstall, por lo que se debe generar el paquete ejecutable APK, que al abrirlo se instalará directamente en la aplicación BlueStacks. Para crear el ejecutable utiliza la opción Tasks > android > android del menú contextual del proyecto en NetBeans. El archivo ejecutable APK se generará en la carpeta build > javafxports > android > NOMBRE_PROYECTO.apk donde se encuentre almacenado el proyecto desarrollado.

Screen Shot 2017 02 14 at 22.10.05

Más información