Clojure のいいところの一つは, 組み込みの GUI ツールキットがあるところです.
その名も Swing.
JVM の上で動き, Java のクラスライブラリが使えるため, javax.swing ももちろん使える訳です.
なるほど.
まずは, 最小限コード.
ラベル一つを貼付けたウィンドウを開くだけ.
(import '(javax.swing JFrame JLabel)) (let [f (JFrame. "Swinging Clojure (1)") p (. f getContentPane)] (. p add (JLabel. "Hello Swinging Clojure!")) (. f setDefaultCloseOperation JFrame/EXIT_ON_CLOSE) (. f setLocationByPlatform true) (. f setSize 200 100) (. f setVisible true))
6 〜 8行目 はこの時点でどうしても必要というものではありませんが, ウィンドウを開く時の基本設定ですので, やっつけときます.
setDefaultCloseOperation で, ウィンドウが閉じられた時の挙動を指定します. EXIT_ON_CLOSE は, exit で, アプリケーションを終了します. REPL で実行しているならば REPL が終了します.
デフォルトは HIDE_ON_CLOSE で, リソースを解放せずに, ウィンドウを隠します. setVisible(false) 相当ですので, 後で setVisible(true) すればもう一度ウィンドウを開けます.
デフォルトでは毎回同じ位置にウィンドウが開きます. 大抵のウィンドウシステムは, ウィンドウを開くときに少しずつずれた位置に表示して, 完全に重ならないようにしてくれる機能がありますが, この機能を有効にするには, setLocationByPlatform() に true を指定します.
setSize は名前から想像できる通りです.
Swing は知っています. という方には以下の java コードとほぼ同等と思っていただければ良いかと思います.
Hello.java
import java.awt.Container; import javax.swing.JFrame; import javax.swing.JLabel; public class Hello { public static void main(String[] args) { JFrame f = new JFrame("Swinging Clojure (1)"); Container p = f.getContentPane(); p.add(new JLabel("Hello Swinging Clojure!")); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setLocationByPlatform(true); f.setSize(200, 100); f.setVisible(true); } }