torutkのブログ

ソフトウェア・エンジニアのブログ

JRubyでJavaFXプログラムを作る(Hello world編)

先月のJava読書会の折、雑談でJRubyが開発止まっているようだ、に対していやつい最近もリリースされているよ、とのことで見るとJRuby 9000(JRuby 9.x)がリリースされています。たしか、JRubyは、Ruby 1.9.3相当の1.7.xがリリースされて以降更新が停滞していたかと思っていました。が、昨年Ruby 9000という開発コードのRuby 2.2系の実装がリリースされていました。

本日時点では、JRuby 9.1.2.0が最新版です。

JRuby のインストール(Windows

JRubyのサイトから、Windows 版のJRubyをダウンロードしインストールします。
http://jruby.org/

インストーラがPATHを通してくれるので、コマンドプロンプトからjrubyコマンドなどを実行できるようになります。

さっそく簡単なプログラムを書いて、実行してみます。

  • hello.rb
puts 'hello world'

jrubyコマンドで実行します。

C:\work> jruby -v
jruby 9.1.2.0 (2.3.0) 2016-05-26 7357c8f Java HotSpot(TM) 64-Bit Server VM 25.102-b14 on 1.8.0_102-b14 +jit [mswin32-x86_64]

C:\work> jruby hello.rb
hello world

C:\work> 

JRubyJavaFXを使ってGUI表示するrubyプログラムを作る

JRubyFXというJavaFXのラッパーを使うとrubyっぽくプログラムが書けるそうです。JRubyFXは、gemで公開されているので、gemでインストールします。

C:\work> jruby -S gem install jrubyfx
Successfully installed jrubyfx-fxmlloader-0.4.1-java
Successfully installed jrubyfx-1.1.1-java
2 gems installed

jruby -S を入れることで、jrubyで実行することが確実になるそうです。gemコマンドを直接実行すると、jruby以外にruby環境がインストールされているマシンでは、どっちが実行されているか怪しくなることがあるためです。

では、実際にJRubyFXを使ったRubyプログラムを記述します。中身が空のウィンドウを表示するだけの簡単なものです。

  • hello.rb
require 'jrubyfx'

class Hello < JRubyFX::Application
  def start(stage)
    with(stage, width: 640, height: 480, title: "Hello JRubyFX") do
      show
    end
  end
end

Hello.launch

Applicationクラスを継承し、startメソッドをオーバーライドするのはJavaFXのままです。
クラスメソッドのlaunchを呼んで実行します。

startメソッドの中で登場する、JRubyFXのサンプルで頻出のwith(...)ですが、rubyの文法には見当たらず、何かなと思って調べると、JRubyFXのサイトに説明がありました。JRubyFXのDSLで、指定したインスタンスのプロパティを設定するものです。

https://github.com/jruby/jrubyfx/wiki/Getting-Started

DSL的な記述をしないときは、次のように記述します。

  def start(stage)
    stage.title = "Hello JRubyFX"
    stage.width = 640
    stage.height = 480
    stage.show
  end
end


次に、アニメーションを入れてみます。

require 'jrubyfx'

class MessageBoard < JRubyFX::Application
  def start(stage)
    with(stage) do
      layout_scene(200, 100) do
        group(layout_y: 50) do
          text('Hello world. This is JRubyFX.') do
            translate_x = translateXProperty
            timeline(cycle_count: :indefinite) do
              animate translate_x, 0.sec => 8.sec, 200 => -200
            end.play
          end
        end
      end
      show
    end
  end
end

MessageBoard.launch

layout_scene もJRubyFXのDSLです。
group() や、text() などもJRubyFXのDSLで、クラス名とコンストラクタへの引数、ハッシュ形式でプロパティの設定をまとめて記述します。

相当慣れない記述で面喰いますが、ワンライナー的に書ける点と、シーングラフ設定のように入れ子構造を記述するのが容易な点がいいのではないかと思います。