JRubyFXでは、コントローラーにてビュー(fxmlファイル)を読み込む際、fxml
メソッドを用いfxmlファイルの名前を指定しますが、ここで指定したファイル名はあらかじめfxml_root
メソッドで設定してあるディレクトリからの相対パスとして探索されます。
例えば、実行されるrubyファイルと同じディレクトリに輿水幸子.fxml
ファイルが存在する場合は、以下の様なコードとなります。
fxml_root File.dirname(__FILE__)
class KawaiiController
include JRubyFX::Controller
fxml "輿水幸子.fxml"
end
更に、このJRubyアプリケーションをjarファイルとしてパッケージングした際にも正常に動作させるためには、fxml_root
の第二引数に、実行されるjarファイルそのもののファイル名を指定する必要があります。
第二引数にnil
以外の値を指定した場合、第一引数として渡した値は使われません。ですので、jarファイルとして実行されている場合は自分自身のファイル名、そうでない場合はnil
を返すメソッドを定義し、そのメソッドを呼び出した返り値を第二引数として渡す形にしておけば、現在実行されている環境がjarファイル内なのかどうかを意識せず、動的にfxml_root
へ適切な値を設定できるようになります。
そこで、jarファイルとしてパッケージングしたJRubyアプリケーションを実行した際、$LOAD_PATH
にjarファイル自身が含まれるようになるという仕様を利用し、以下のようなjar_filename
メソッドを追加しましょう。
def jar_filename
$LOAD_PATH.map{|it|
it.split('/')
}.flatten.uniq.select{|it|
it.match /^(?!jruby-complete\.jar!)(?!jruby-stdlib-[0-9\.]+\.jar!).+\.jar!$/
}.first.tap{|it| break it.tr('!','') unless it.nil?}
end
fxml_root File.dirname(__FILE__), jar_filename
いいですね。JRubyFXにはJRubyFX::Application.in_jar?
という便利メソッドもあるので、jarファイルの名前が予めわかっている場合には、単に条件分岐でfxml_root
を呼んでしまえば良いでしょう。例えばjarファイルの名前が乙倉悠貴.jar
だとわかっている場合は以下の様なコードになります。
if JRubyFX::Application.in_jar?
fxml_root nil, '乙倉悠貴.jar'
else
fxml_root File.dirname(__FILE__)
end
ただし、jarファイルの名前はユーザーが変更してしまう事も有り得ますので、$LOAD_PATH
から動的に取得する方法の方がより安心かもしれません。
fxml_root
の仕様はドキュメント化されていませんので、より詳しく知りたい方はこの辺りのコードを読むと良いと思います。