You may also consider Seesaw, which requires embedding Clojure.
You're GUI code would then look something like:
(defn -main [& args]
(invoke-later
(-> (frame :title "Hello",
:content "Hi there",
:on-close :exit)
pack!
show!)))
Where "Hi there" is automatically "converted" to a JLabel, but instead you could put any Swing component for :content
.
This more complex example from my seesaw-buttons
sample project:
(ns seesaw-buttons.core
(:use seesaw.core))
(defn -main [& args]
(invoke-later
(let [open-action (action
:handler (fn [e] (alert "I should open a new something."))
:name "Open ..."
:key "menu O"
:tip "Open a new something something.")
exit-action (action
:handler (fn [e] (.dispose (to-frame e)))
:name "Exit"
:tip "Close this window")]
(-> (frame :title "Hello",
:content (border-panel
:north (toolbar :items [open-action exit-action])
:center "More content here..."),
:on-close :exit)
pack!
show!))))
The advantage of Seesaw and Clojure is the elimination of a lot of boilerplate code and Seesaw has added some functionality and conventions that speed up development.