Saturday 27 December 2008

Building a GUI with Clojure

Well, that's my most rubbish UI ever, but at least it gave me a chance to learn a few things. Starting from the example, I made a few very simple changes and ended up with the rubbish one above....

I'm still not fulling groking exactly how "real" applications are designed in a functional programming language. For example, in this daft app what should the separation of concerns be? Does MVC have a functional counterpart?

Next on this list is changing the code (prn alg) to actually render what's going on with quicksort and bubble sort.

(import '(javax.swing JFrame JLabel JTextField JButton JComboBox JPanel Timer)
'(java.awt.event ActionListener)
'(java.awt GridLayout))

(defn draw-sort [canvas alg]
(prn alg))

(defn sortapp []
(let [frame (JFrame. "Sort Visualizer")
canvas (JPanel. true)
algorithm-chooser (JComboBox.)
run-button (JButton. "Run Algorithm")]
(.addActionListener run-button
(proxy [ActionListener] []
(actionPerformed [evt]
(draw-sort canvas (.toString (.getSelectedItem algorithm-chooser))))))
(doto algorithm-chooser
(.addItem "Quick sort")
(.addItem "Bubble sort"))
(doto frame
(.setLayout (GridLayout. 2 2 3 3))
(.add algorithm-chooser)
(.add canvas)
(.add run-button)
(.setSize 300 300)
(.setVisible true))))

Things I have learnt:

  • doto syntax saves lots of repetition!
  • proxy is used to generate implementations of interfaces dynamically

Things I need to find out:

  • What's the idiomatic way of drawing something on the screen? Do I need to be using timers? Probably!


  1. I've noticed your blog come up a lot on my google searches... Being a java dev you've probably used this or solved this problem since but if not I've had some success with

    It's been added to clojure contribs as well.

  2. Thanks for pointing that out, I'd not heard of MigLayout. Looks interesting!

  3. By the way do you know of a good clojure group in the UK? I'm learning myself and as a student its a nice change from coding in Java I'm still unfamiliar with good practice when it comes to debugging. At the moment I'm very REPL dependent and I'm muddling around with the emacs inspector. I'm considering sitting down and writing some debug functions so I can assess objects a bit more finely.

  4. I know there's a group in Cambridge (see here). I keep meaning to go along, but work has always got in the way so far :(

    I think at some point some peeps in London have met too. Not sure of anywhere else!

  5. One crucial little detail is missing in your code. To activate the gui this line must be added at the end:


  6. Thanks Simon - good point. I was always running this in a REPL and typing (sortapp) to activate it, but I should have put it in the main code too!