http://bjoernstechblog.rueffer.info/posts/lisp/java/swing/clojure/2010/12/28/A-simple-example-of-a-SWING-GUI-with-clojure./
last updated on 30 July 2015

28 December 2010

A simple example of a SWING GUI with clojure.

Writing Java code is pain if you know how simple things can be in lisp. Clojure is a lisp dialect for the Java Virtual Machine and it can be used to do everything that Java would normally be used for.

Writing platform portable user interfaces is a pain, too, and Java seems to be one of the canonical choices for this task. Of course there are other choices like QT, wxwindows, Tcl/Tk, and so forth. However, except for QT these frameworks have a strange look and feel and some require platform dependent machine code. So back to Java. What can Java do for me? The current state of the art in terms of GUI programming in the Java world seems to be to use either SWT or Swing. Swing has the advantage that most users already have it on their machines, whereas SWT might have to be bundled with your software.

Below is a small Hello-World type application that you can run from your Clojure REPL. It creates a Window with some text and a button which generates an events shown on your Java console if you press it. The notable part here is that the program is rather short and nicely structured.

Note that for Swing the GUI construction is supposed to be done from the event-dispatching thread, hence the outer wrapper.

(ns swingexample
  (:import (javax.swing SwingUtilities JFrame JPanel JLabel JButton)
  (java.awt FlowLayout) (java.awt.event ActionListener)))

;; wrap GUI construction in a call to invokeLater()
(. SwingUtilities invokeLater
	   (proxy [Runnable] []
  (run []
	   ;; set up the gui
	   (doto (JFrame.) ; generate frame (i.e. window)
		 (.setSize  640 480)
		 (.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE)
		 (.add  ; a panel to take care of
	 ; layout
   (doto (JPanel. (java.awt.FlowLayout.)) ; add label
	 (.add (JLabel. 'This GUI was constructed
	 from within the event-dispatching
	 thread.'))
	 (.add (doto (JButton. 'Press here to
	 generate events!') ; add a button
	  (.addActionListener
	   (proxy
	   [java.awt.event.ActionListener] []
		 (actionPerformed [e] (println e)))))
	)))
		 (.setVisible true))

	   ;; /end event-dispatching thread wrapper
	   )))
Björn Rüffer — Copyright © 2009–2015 — bjoern.rueffer.info