What is the best way to do GUIs in Clojure?
Is there an example of some functional Swing or SWT wrapper? Or some integration with JavaFX declarative GUI description
If you want to do GUI programming I'd point to Temperature Converter or the ants colony.
Many things in Swing are done by sub-classing, particularly if you are creating custom components. For that there are two essential functions/macros: proxy and gen-class.
Now I understand where you are going with the more Lispy way. I don't think there's anything like that yet. I would strongly advise against trying to build a grandiose GUI-building framework a-la CLIM, but to do something more Lispy: start writing your Swing application and abstract out your common patterns with macros. When doing that you may end up with a language to write your kind of GUIs, or maybe some very generic stuff that can be shared and grow.
One thing you lose when writing the GUIs in Clojure is the use of tools like Matisse. That can be a strong pointing to write some parts in Java (the GUI) and some parts in Clojure (the logic). Which actually makes sense as in the logic you'll be able to build a language for your kind of logic using macros and I think there's more to gain there than with the GUI. Obviously, it depends on your application.
Nobody yet suggested it, so I will: Browser as UI platform. You could write your app in Clojure, including an HTTP server and then develop the UI using anything from HTML to hiccup, ClojureScript and any of the billions of JS libaries you need. If you wanted consistent browser behaviour and "desktop app look'n'feel" you could bundle chrome with your app.
This seems to be how Light Table is distributed.
I don't think there is an official one, but personally I would take advantage of the fact that I am using one of the most powerful language in the world and just imagine what the perfect gui code would look like:
(form {:title :on-close dispose :x-size 500 :y-size 450}
[(button {:text "Close" :id 5 :on-click #(System/exit 0) :align :bottom})
(text-field {:text "" :on-change #(.println System/out (:value %)) :align :center})
(combo-box {:text "Chose background colour" :on-change background-update-function
:items valid-colours})])
Your idea would differ but this should hopefully the above gives you some idea.
I would rather go for clojurefx, it is a bit premature, but it does work and saves you time.
I started my GUI with seesaw and then tried another component in clojurefx.
I have finished both, and I am convinced that I am going to refactor the seesaw one to clojurefx.
After all, JavaFX is the way to go forward.
It feels lighter than seesaw. Or at least, writing it..
Bindings work, listeners work, most of the component work, otherwise, just use one of the macros to create a constructor for that particular case and job done. Or, if you find it difficult, write some methods in Java and ask for help to improve clojurefx.
The guy who wrote clojurefx is busy at the moment, but you can fork the project and do some fixes.
I asked myself the same question of writing a GUI in Clojure with Swing and came up with the library signe
It lets you use represent your domain model as a single Clojure data structure wrapped inside an atom.
See the examples here.
I've been developing a Java applet in which everything is written in Clojure except the applet code, which is written in Java. The applet invokes the Clojure code's callbacks of init, paint, etc from java's hooks for those methods that are defined by the applet model. So the code ends up being 99.999 percent Clojure and you don't have to think about the tiny Java piece at all for the most part.
There are some drawbacks to this approach, which I hope to discuss in more detail on the Clojure Google Group. I think the Clojure developers should include a native way of building applications. Presently you can do whatever GUI stuff you like from the REPL, but if you want a deliverable GUI application, it is necessary to write some Java to call the Clojure code. Also, it seems like the architecture of a Java Applet kind of forces you outside of Clojure's more idiomatic best practices, requiring you to use mutable state, etc.
But also, I am not very far along with Clojure yet and it might be the case that it is possible and I just haven't discovered how to do it correctly yet.