joelbecker.net
tech, music, life and meaning

Running Scala + JavaFX on Android, iOS, Windows, and Mac OS X

Mar 12, 2016

Since I wasn't able to find anything on the Internet for how to make a Windows/OS X/Android/iOS app using Scala and JavaFX, I'm sharing what I figured out for how to do it, along with an example/template project for your own use.

Why Scala and JavaFX?

Well that's another article. For those wanting to get started right away, here we go!

Algorithm Block Diagram

"What happened on the iPad?" you ask? Appears to be a JavaFXPorts charts rendering issue on my old iPad 2. I'll keep you posted. But I believe the normal UI controls all work fine.

Just give me the code

Fine! Sheesh. Here's an example gradle project that will build Scala and JavaFX code for all four platforms. You can use it as a template project for your own app. But you'll still need the other prerequisites like Android SDK and RoboVM as described below.

So how do you do it?

You have things to do and so do I, so in quick, straightforward bullet points, here's how you do it:

  • The jfxmobile gradle plugin makes it easy to build a Java+JavaFX project for all four platforms.
    • When it builds for desktop, it simply utilizes the JavaFX framework included in JavaSE. Use the run gradle task for that.
    • For mobile, it employs the JavaFXPorts project, which ports JavaFX to Android and iOS.
    • The Android build requires the Android SDK, as any means of building for Android does.
      • You'll either need and ANDROID_HOME environment variable pointing to the SDK's directory on your machine (that's what I do), or use the androidSdk property in your gradle.build file as described in the JavaFXPorts documentation (also linked later).
    • The iOS build requires you to have:
      • OS X installed on a Mac or on a PC, though the latter is legally questionable if you're producing commercial software. Then within your OS X installation you need:
      • XCode installed. You don't need to use XCode as your IDE; it's just there for stuff required for gradle or anything else to be able to build for iOS.
      • RoboVM installed
        • RoboVM has a free 30-day trial, and is free for people making games with libgdx. After that it is rather expensive. Nevertheless it is worth the price compared to porting and maintaining a parallel Swift or Objective-C code base. (And a better investment than using Xamarine / .NET from my experience.)
  • The scala gradle plugin compiles Scala source code into Java byte code.
    • After that happpens in the build, it can treat the byte code as if it was originally plain old icky Java code.
    • You'll notice the build.gradle file of the "modules" module in the example project has apply plugin: 'scala'
  • Likely the most valuable point here -- that hours of struggle and digital black eyes taught me -- is that you must (at the time of this writing anyway) put your Scala code in a separate gradle module from the module using the jfxmobile plug-in.
    • The jfxmobile plugin does not play nice with the scala plugin. No matter how hard you try, you'll get all kinds of weird stuff. Believe me. A lot of it has to do with the retrolambda plugin that the jfxmobile plugin uses, and trying to disable a transitive plugin use is a mess, if you can even make it work.
    • But this requirement of separation isn't bad. In a sense it creates a good separation: the jfxmobile project serves to glue everything together for each platform, but it won't house the bulk of the code. The other projects where the Scala code resides are basically just plain old library projects.
  • You can add more Scala projects to the "modules" project if you would like to separate more of your application's code into modules. modules's build.gradle file has the build settings common for all Scala projects, such as applying the scala plugin and depending on the scala library.

Beside the above particulars for using Scala with JavaFXPorts, you can follow the regular JavaFXPorts instructions here to get you up and running.

Now go make some multi-platform Scala apps!