h1. Starting a Clojure Desktop Application
We’re starting up our first desktop application in Clojure. We’re a heavy vim and ruby shop. We’ve done several desktop applications in “JRuby”:https://spin.atomicobject.com/2008/07/02/rolling-a-jruby-desktop-application/. This is the first time we’ve tackled swing UIs and GUI testing in Clojure. It’s still early in the process, but here’s what we’ve found so far.
For Swing, we’re using “seesaw”:https://github.com/daveray/seesaw. It provides Clojure bindings to standard Swing widgets and MigLayout, which was all I set out looking for. What really impressed me, however, was its CSS “selector”:http://daveray.github.com/seesaw/seesaw.core-api.html#seesaw.core/select engine, allowing you to query a frame for particular widgets for event subscription or manipulation. It also offers an impressive “data binding”:http://daveray.github.com/seesaw/seesaw.bind-api.html mechanism similar to UNIX pipes, complete with transformations and @tee@.
We’re using Brian Marick’s “Midje”:https://github.com/marick/Midje for unit testing and “fest”:http://code.google.com/p/fest/ to automate system tests.
“Leiningen”:https://github.com/technomancy/leiningen manages our dependencies and packages our jars. We’ve found it helpful to “set up a local maven repository”:http://www.pgrs.net/2011/10/30/using-local-jars-with-leiningen/ in our vendor directory for a couple of cases where we needed a jar that was neither in the main maven repository nor clojars.
We’re heavy “Vim users”:https://spin.atomicobject.com/2011/08/07/atomic-vim-config/ here at AO, but as fantastic as “VimClojure”:https://bitbucket.org/kotarak/vimclojure/overview is, paredit.vim from “slimv”:http://www.vim.org/scripts/script.php?script_id=2531 just doesn’t compare to “Emacs’ glorious mode”:http://www.emacswiki.org/emacs/ParEdit. I’m pretty incompetent in Emacs, but the “Emacs starter kit”:https://github.com/technomancy/Emacs-starter-kit and a weekend of practice with Emacs and ParEdit has taken the shine off my beloved vim for lisp editing. (It’s actually been a while since I last used Emacs, so I’m sticking with vim in the short term while I ramp back up with Emacs).
h2. State mediation between model and view
So far things are going well with Clojure, but rethinking our approach to structuring GUI applications is definitely a challenge. We normally use “MVP/Presenter First”:https://atomicobject.com/resources/presenter-first when building web applications, but the pattern doesn’t map as easily to Clojure as it does to new object oriented languages. Decoupling domain model and UI with a stateless definition defining communication between the two still seems like a winning combination. We’re using Clojure reference types (refs, atoms, actors) to represent entities in our application domain and using event handlers and data binding with selector-identified Swing widgets. This seems like a workable approach but there are still questions to answer. More to come.