Tomasz Wegrzanowski
Posted on October 30, 2021
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
:
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, 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
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
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.
Posted on October 30, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.