Electron Adventures: Episode 83: JRubyFX

taw

Tomasz Wegrzanowski

Posted on October 30, 2021

Electron Adventures: Episode 83: JRubyFX

In the previous episode we tried JRuby with SWT, and it was bad. Well, the Java world knows it's bad and replaced SWT with JavaFX, so let's give it a go.

Unfortunate beginnings

First set .ruby_version to JRuby:

jruby-9.3.1.0
Enter fullscreen mode Exit fullscreen mode

And Gemfile to use jrubyfx:

source "https://rubygems.org"

gem "jrubyfx", "~> 1.2"
Enter fullscreen mode Exit fullscreen mode

Now trying Hello World from the docs, and we get:

JavaFX runtime not found.  Please install Java 7u6 or newer or set environment variable JFX_DIR to the folder that contains jfxrt.jar
If you have Java 7u6 or later, this is a bug. Please report to the issue tracker on github. Include your OS version, 32/64bit, and architecture (x86, ARM, PPC, etc)
Enter fullscreen mode Exit fullscreen mode

Well, judging by Github Issues, it's been a bug since February 2019, so it's not a very promising start.

After some investigation, JavaFX was originally included as part of Oracle JDK, but then Oracle JDK moved it out. And other Java implementations, including one used by OSX, just never included it.

So we just jpm install javafx and... just joking, Java has nothing like npm or gem.

Even worse, Java developer community is awful and instead of telling you "curl this URL and run this command" or even "click this link to download the package", they just say "install it", and expect you to figure out which one of 100 versions is supposed to work. And they treat users the same way, not just developers. Pretty much every other language's community handles this better.

Using old Java

So I checked on an old Mac, and it had old an Oracle Java instaled.

Well, export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/ and let's continue there.

Hello, World!

Here's a hello world program:

#!/usr/bin/env ruby

require "jrubyfx"

class HelloWorld < JRubyFX::Application
  def start(stage)
    with(stage, width: 300, height: 300, title: "Hello, World!") do
      layout_scene do
        label("Hello, World!")
      end
      show
    end
  end
end

HelloWorld.launch
Enter fullscreen mode Exit fullscreen mode

Episode 83 Screenshot A

Counter

And here's a counter app. There's no builtin reactivity, so we need to manually update the UI whenever we update the state.

#!/usr/bin/env ruby

require "jrubyfx"

class Counter < JRubyFX::Application
  def start(stage)
    count = 0

    with(stage, width: 300, height: 300, title: "Counter App") do
      layout_scene do
        vbox do
          count_label = label("Count: #{count}")
          hbox do
            button("+1").set_on_action {
              count += 1
              count_label.text = "Count: #{count}"
            }
            button("-1").set_on_action {
              count -= 1
              count_label.text = "Count: #{count}"
            }
          end
        end
      end
      show
    end
  end
end

Counter.launch
Enter fullscreen mode Exit fullscreen mode

Episode 83 Screenshot B

Results

In case it's not obvious yet, do not use any of this. While the UI was slightly better than SWT, and the label text resized correctly, it's really nowhere near what we expect from a modern UI framework, and the Java ecosystem you'd need to get into is a godforsaken mess.

Having tried so many Electron alternatives, I'd say NodeGui was the only one that wasn't absolute garbage, and even there you pay a big cost for abandoning the familiar world of HTML+CSS.

So in the next episode, let's just write something in Electron again!

As usual, all the code for the episode is here.

💖 💪 🙅 🚩
taw
Tomasz Wegrzanowski

Posted on October 30, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related