日曜プログラミング

休日趣味でやってるプログラミング関連記事をダラダラと

JavaFX でちょっとばかり遊んでみた

Clojure だと GUI ライブラリは seesaw 一択な感じなんだけど
ここは敢えて JavaFXClojure から Helloworld してみた。
seesaw の作者が JavaFX に対応してくれると嬉しいんだけどねー。

お決まりの Hello world
Try! JavaFX! : JavaFX 2.0によるGUI開発入門 (第一回) - naokirin tech news
↑のサイトは Java だけど Clojure 版でほぼそのまま書き直してみた。

コード

Hello world レベルだと巷にゴロゴロ転がってるので細かい説明は無し。

; project.clj
(defproject jfx "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :resource-paths ["C:/Java/jre/lib/jfxrt.jar"] ; ハマリ->1
  :aot [jfx.core] ; ハマリ->2
  :dependencies [[org.clojure/clojure "1.5.1"]]
  :main jfx.core)
(ns jfx.core
  (:import [javafx.application Application]
           [javafx.stage Stage]
           [javafx.scene Scene layout.HBox control.Label])
  (:gen-class
   :extends javafx.application.Application))

(defn -start [this stage]
  (let [hbox (HBox.)
        scene (Scene. hbox)]
    (.add (.getChildren hbox) (Label. "ちーす"))
    (doto stage
      (.setScene scene)
      (.setTitle "Hello")
      (.show))))

(defn -main [& args]
  (javafx.application.Application/launch jfx.core args))

ハマったポイントだけ。

  1. JavaFX は 6 だか 7 だかから JDK に同梱されるようにはなってるがデフォルトでは参照しないみたいなのでこんな感じで明示的に指定してやる必要がある
  2. 上記サイト見ながら書きなおしただけなのでよく分かってないが JavaFX では javafx.application.Application を継承*1したクラスを指定して起動してやる必要があるみたい。で、多分 main から見えるようにするために AOT コンパイルが必要っぽい。

但しこれで動作確認できるのは lein run まで。lein uberjar してパッケージングされた jar ではまた JavaFX の jar を参照しなくなってるっぽい。sample.project.cljのこの辺り入れてやれば動きそうな気がするけど明日で。

けどこの方法も lein classpath コマンド見る限りじゃ単に絶対パスで展開されるだけな気がしなくもない。こういう標準であるにはあるが参照されてないライブラリってどうすりゃいいんだろうな。

*1:extend なんだから文字通り拡張でいいんじゃないのと思ったり思わなかったり。