The GoNative App is a Gluon code sample. For a full list of Gluon code samples, refer to the Gluon website.

In this tutorial, we’ll explain how to create the GoNative application that can be deployed on desktop, Android and iOS devices. Based on the Gluon Attach Extended library, we will make use of the simple log service, and its different platform implementations, to show how can we use a custom Attach service.

Before you start, make sure to check the list of prerequisites for each platform, and you have installed the Gluon plugin for your IDE.

Note: This tutorial will use the plugin for NetBeans, but it works as well on IntelliJ and Eclipse.

Code: The code for this project can be found in the samples repository at GitHub. The sample is located under the directory go-native. The reader can clone this repository or create the entire project from scratch, based on the following steps.

Native services

Gluon Attach already provides many native services for Desktop, Android and iOS. You can find them in the Gluon website.

You can also find in the Attach javadoc:

the current list of services and you can make use of any of these services when working on a Gluon project inside your IDE.

When you require a native service that is not included yet in that list, as we’ll describe in this sample, you can implement it following the LogService, build it and publish it, and then add its dependencies to the project.

Creating the Project

Let’s create a new project using the Gluon plugin. In NetBeans, click File→New Project…​ and select Gluon on the left. Select Gluon Mobile - Glisten-Afterburner Project from the list of available Projects:

Plugins Window

Add a proper name to the application (GoNative), find a proper location, add the package name and change the main class name if required.

Name and Location

Press Next and change the name of the primary view to Main.

Name of Views

Press Finish and the project will be created and opened.

Project

Modifying the Project

For this sample we don’t need the secondary view, so we can just leave it there for a possible future use, or we can get rid of the related files (SecondaryPresenter.java, secondary.css, secondary.properties and secondary.fxml), and remove the AppView instance from the AppViewManager.

LogService

We’ll make use of the LogService, that has the interface with the required method signatures:

LogService.java
package com.gluonhq.attachextended.log;

public interface LogService {

    static Optional<LogService> create() {
        return Services.get(LogService.class);
    }

    void log(String message);
}

Creating and building the log service

The service includes the Java code for the different platform implementations for desktop, Android and iOS.

The native folder contains native C code for Android and iOS, as well as the Android Java code.

The Gluon Attach Extended project describes how the libraries can be built.

For a more detailed explanation, see https://docs.gluonhq.com/#_platform_builds.

Using the LogService

The dependencies are added to the pom:

pom.xml
<properties>
    <attach.extended.version>4.0.12</attach.extended.version>
    <attach.extended.classifier>desktop</attach.extended.classifier>
</properties>

<repositories>
    <repository>
        <id>Gluon</id>
        <url>https://nexus.gluonhq.com/nexus/content/repositories/releases</url>
    </repository>
</repositories>

<!-- dependencies -->
<dependency>
    <groupId>com.gluonhq.attachextended</groupId>
    <artifactId>log</artifactId>
    <version>${attach.extended.version}</version>
</dependency>
<dependency>
    <groupId>com.gluonhq.attachextended</groupId>
    <artifactId>log</artifactId>
    <version>${attach.extended.version}</version>
    <classifier>${attach.extended.classifier}</classifier>
    <scope>runtime</scope>
</dependency>

<!-- profiles -->
<profiles>
    <profile>
        <id>ios</id>
        <properties>
            <gluonfx.target>ios</gluonfx.target>
            <attach.extended.classifier>ios</attach.extended.classifier>
        </properties>
    </profile>
    <profile>
        <id>android</id>
        <properties>
            <gluonfx.target>android</gluonfx.target>
            <attach.extended.classifier>android</attach.extended.classifier>
        </properties>
    </profile>
</profiles>

At any moment, from our main code, we’ll be able to get a service instance and log any message:

Services.get(LogService.class).ifPresent(service -> service.log(message));

Main view

We’ll now open main.fxml with Scene Builder to modify the button and add a label that will print out the message log.

Main FXML

And finally, we’ll add the service to the MainPresenter:

MainPresenter.java
public class MainPresenter {

    @FXML
    private View main;

    @FXML
    private Label messageLabel;

    @FXML
    private Button logButton;

    public void initialize() {
        main.showingProperty().addListener((obs, oldValue, newValue) -> {
            if (newValue) {
                AppBar appBar = AppManager.getInstance().getAppBar();
                appBar.setNavIcon(MaterialDesignIcon.MENU.button(e -> AppManager.getInstance().getDrawer().open()));
                appBar.setTitleText("Native Services");
            }
        });

        logButton.setOnAction(e -> {
            String message = String.format("[%s] - %s", Platform.getCurrent().name(), logButton.getText());
            messageLabel.setText(message);
            Services.get(LogService.class).ifPresent(service -> service.log(message));
        });
    }
}

We can style the view with some custom css:

main.css
#title {
    -fx-font-size: 1.6em;
    -fx-text-fill: -primary-swatch-900;
}

.button {
    -fx-font-size: 1.2em;
    -fx-alignment: CENTER;
    -fx-padding: 10 20 10 20;
}

.icon > .label {
    -fx-font-size: 2em;
}

Running the app

On Dekstop, we run mvn gluonfx:run, or from the toolbar on NetBeans we hit the button Run Project (GoNative) (F6).

Desktop app

Also notice the console when we click the button:

 --- javafx-maven-plugin:1.0.22:run (default-cli) @ gonative ---
Sep 22, 2021 9:34:49 PM com.gluonhq.attach.util.Platform <clinit>
INFO: [Gluon Attach] System Property javafx.platform is not defined. Platform will be set to Platform.DESKTOP
Sep 22, 2021 9:34:52 PM com.gluonhq.attachextended.log.impl.DesktopLogService log
INFO: [DESKTOP] - Log Service
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------

Native image

We build now the native image on desktop, running mvn gluonfx:build gluonfx:nativerun from the NetBeans terminal.

Android

From a Linux machine, plug an Android device and run:

mvn -Pandroid gluonfx:build gluonfx:package gluonfx:install gluonfx:nativerun

Android app
[Thu Sep 23 01:29:35 CEST 2021][INFO] [SUB] I/GluonAttach(14380): JNI_OnLoad_log called
[Thu Sep 23 01:29:35 CEST 2021][INFO] [SUB] D/GluonAttach(14380): [Log Service] Initializing native Log from OnLoad
[Thu Sep 23 01:29:35 CEST 2021][INFO] [SUB] D/GluonAttach(14380): Util :: Load className com/gluonhq/helloandroid/DalvikLogService
[[Thu Sep 23 01:29:35 CEST 2021][INFO] [SUB] V/GluonAttach(14380): [ANDROID] - Log Service

iOS

On MacOS, plug an iOS device and run:

mvn -Pios gluonfx:build gluonfx:nativerun

iOS app

We can check the terminal:

[Thu Sep 23 01:08:45 CEST 2021][INFO] [SUB] 2021-09-23 01:08:45.175623+0200 GoNative[45312:7626573] IOSLogService: [IOS] - Log Service

Conclusion

During this tutorial we have seen in detail how we can make use of very simple custom Attach service.

We have accomplished several tasks:

  • Starting from the default project created by the Gluon plugin, we have modified the main view to include a custom Attach service.

  • We have explored Gluon Attach for existing platform-agnostic services.

  • And we have tested the application on desktop and mobile devices, by building a native image.

If you have made it this far, congratulations, we hope this sample and the documentation was helpful to you! In case you have any questions, your first stop should be the Gluon support page, where you can access the latest documentation. Gluon also recommends the community to support each other over at the Gluon StackOverflow page. Finally, Gluon offers commercial support as well, to kick start your projects or in case you need help with a service not available yet at the Gluon Attach library.