clojure で SWT 使ってみた

java とかそんなに使ってないので、クラスパスとかよく分からない感じがあります。
なので、ググりまくって調べたのはいいんですが、どうすればいいのかわからなく、cat /usr/bin/clj でソースを見てやっと解決しました。

clojureSWT が使える環境を整える

clojureSWT を使う前に、CLOJURE_CLASSPATH に何が入っているのかを見てみましょう。 何も入っていない場合、SWT は使えない可能性高いので ~/.bashrc~/.zshrc にこのように書いておいたりしましょう:

export CLOJURE_CLASSPATH='/usr/share/java/*'

clojure が無事に jar ファイルを読み込むようになったかは以下のような clojure コードを実行してみてください:

(use 'clojure.pprint)
(pprint (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))

すると、読み込めそうな jar ファイルがいい感じにずらーっと出力されると思います。
その中に、swt.jar みたいなのがあれば、おkです。

Arch Linux であれば、SWT/usr/share/java/ にインストールされますが、他のプラットフォームではよく分からないので、各自脳内補完してください。

窓を表示させてみる

次は窓を表示させてみます。

(import '(org.eclipse.swt.widgets Display Shell))

(def display (new Display))
(def shell (new Shell display))

(.setText shell "Window Demo")
(.setSize shell 200 100)
(.open shell)

(while (not (.isDisposed shell))
  (do
    (if (not (.readAndDispatch display))
      (.sleep display))))
(.dispose display)

java で書かれたサンプルを clojure に書きなおすというのも勉強になりますね。
clojure いコードに java いクラスを持ってくる方法については、とりあえず import にすれば問題ないということを知りました。

あと、SWT などの定数を使う際は SWT/NULL みたいにスラッシュを使います。

フィールドは (set! (foo publicField) 42) の様に set! を使うようです。

リスナーを登録するときにリスナーなインターフェイスから匿名クラスを作るには、reify を使う感じです。

(def button (new Button shell SWT/NULL))
(.setText button "OK")
(.addSelectionListener button (reify SelectionListener
                                (widgetSelected [this e]
                                  (def message-box (new MessageBox shell))
                                  (.setMessage message-box "ボタンがクリックされました。")
                                  (.open message-box))))

参考