Electron Adventures: Episode 83: JRubyFX
Tags: electron, ruby, java
Published: 2021-10-30 18:52:55

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
```

And `Gemfile` to use `jrubyfx`:

```ruby
source "https://rubygems.org"

gem "jrubyfx", "~> 1.2"
```

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)
```

Well, [judging by Github Issues](https://github.com/jruby/jrubyfx/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](https://blogs.oracle.com/java/post/the-future-of-javafx-and-other-java-client-roadmap-updates). 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:

```ruby
#!/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
```

![Episode 83 Screenshot A](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fyizlff8pg2fkemra3jt.png)

### 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.

```ruby
#!/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
```

![Episode 83 Screenshot B](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1idcqhnd6gyq3i0l63gu.png)

### 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](https://github.com/taw/electron-adventures/tree/master/episode-83-jrubyfx).