Easy UI development in Clojure with Seesaw

seesaw A4X 2DIn my learning of Clojure and figuring out some cool things to do with it, I’ve come across the issue of User Interfaces. The web side of things is pretty easily covered by Luminus (ex Noir) in Compojure which uses Ring.

How about client-side UI though?hello-some-world

As Clojure wraps Java, you have access to the Swing framework, so you can actually “code” Swing in Clojure. As an example, let’s take the most basic thing – popping up a “Hello World” window

In pure Java, you’d need to write this

import javax.swing.*;        

public class HelloSwingWorld {
    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("Hello Swing World!");
                JLabel label = new JLabel("Hi, Welcome to Swing");
                frame.pack(); frame.setVisible(true);

I’ve highlighted the two key bits of information to distinguish them from the actual code because there’s just so much crufty code! As @darevay , Dave Ray – the author of Seesaw, noted this is like shooting fish in a barrel (as you’ll see), but I’m betting that some may not realise this, so lets go the next step along and switch to Clojure

(import (javax.swing JFrame JLabel SwingUtilities))

(. SwingUtilities invokeLater
  (proxy [Runnable] [] (run []
    (JFrame/setDefaultLookAndFeelDecorated true)
    (let [frame (JFrame. "Hello Swing World!")
          label (JLabel. "Hi, Welcome to Clojure")]
      (.setDefaultCloseOperation frame JFrame/EXIT_ON_CLOSE)
      (.add (.getContentPane frame) label)
      (.pack frame) (.setVisible frame true)
) ) ) )

This is a great example of how well Clojure easily integrates with Java. The only problem is that we still have all the disadvantages of the Swing library because at the end of the day, that’s what we’re using. What we really need, is some sort of Clojure-centric and thinking wrapper for Swing (because in Java, it’s still the only way to do client-side UI’s). That’s where Seesaw comes in!

(use 'seesaw.core)

(-> (frame :title "Hello Seesaw World!"
           :content "Hi, Welcome to Seesaw") pack! show!)

Note that the last 2 lines are normally one – I’ve just split it for WordPress. What a difference! Basically everything in the Seesaw version  is critical to the interface – no extra characters, whereas the Java and pure Clojure versions have about a 90% overhead of things that we really don’t care about but have to do to set up things for that clunky old library called Swing.

“Ah”, you may say, “that’s not a real-world example my interface is much more complicated than that!”. Well, that’s where it actually gets worse as Seesaw wraps a lot more cruft, workarounds etc… and the percentage will probably go up (not that there’s that much headroom ;). Also, if you’re after a real world example of Seesaw in use then I suggest you check out the Clojure Namespace Browser (clj-ns-browser). which is also a very cool tool which takes me back to NeXTSTEP and Smalltalk


So what are the takeaways? One easy and the other hard:

  1. If you’re looking to code a client-side UI in Clojure, then you should take a serious look at Seesaw, unless you like being continually reminded of Java and it’s klunkiness
  2. If you’re coding in Java, you should seriously consider Clojure as it’s not just client-side UI’s that are easier, almost everything is!


Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s