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);
}
}