Hello,

I've posted an example of a simple model-view-controller GUI skeleton
in Clojure here:
http://lifeofaprogrammergeek.blogspot.com/2009/05/model-view-controller-gui-in-clojure.html

The GUI has a text box and a panel which draws what you type. It's not
much, but I learned a lot doing it, and thought perhaps others could
benefit from seeing it.

The add-watch function is so cool!

There's probably lots of room for improvement, I would appreciate any
recommendations. I've started looking at neman.cells, but don't really
understand it yet. Might using cells simplify this code?

Best,
Curran

Here's the code:

;A test program exploring how to structure GUI code in Clojure
;The GUI draws whatever you type in the text field nicely in the panel
below.
;license: Public domain

(import '(javax.swing JFrame JLabel JTextField JButton JPanel)
      '(java.awt.event ActionListener)
      '(java.awt GridBagLayout GridBagConstraints Color Font
RenderingHints))

(defn make-model [] (ref "Hello MVC!"))

(defn make-graphics-panel [model]
(let [panel
  (proxy [JPanel] []
    (JPanel [] (println "in constructor"))
    (paint [g]
       (doto g
                  ;clear the background
         (.setColor (. Color black))
         (.fillRect 0 0 (.getWidth this) (.getHeight this))

                  ;draw the text
         (.setRenderingHint (. RenderingHints KEY_ANTIALIASING)
                    (. RenderingHints VALUE_ANTIALIAS_ON))
         (.setFont (Font. "Serif" (. Font PLAIN) 40))
         (.setColor (. Color white))
         (.drawString @model 20 40))))]

                  ;repaint when the model changes
  (add-watch model "repaint" (fn [k r o n] (.repaint panel)))
  panel))

(defn make-text-field [model]
(doto (JTextField.)
  (.setText @model)
  (.addActionListener
   (proxy [ActionListener] []
     (actionPerformed [e]
   (let [new-text (.getActionCommand e)]
     (dosync (ref-set model new-text))))))))

(defn make-gui-panel [model]
(defn make-text-field-constraints []
  (let [c (GridBagConstraints.)]
    (set! (.fill c) (. GridBagConstraints HORIZONTAL))
    (set! (.weightx c) 1)
    c))

(defn make-panel-constraints []
  (let [c (GridBagConstraints.)]
    (set! (.gridy c) 1)
    (set! (.weighty c) 1)
    (set! (.fill c) (. GridBagConstraints BOTH))
    c))

(let [gridbag (GridBagLayout.)
      text-field (make-text-field model)
      panel (make-graphics-panel model)]
                  ;set up the gridbag constraints
  (doto gridbag
    (.setConstraints text-field (make-text-field-constraints))
    (.setConstraints panel (make-panel-constraints)))
                  ;add the components to the panel and return it
  (doto (JPanel.)
    (.setLayout gridbag)
    (.add text-field)
    (.add panel))))

(defn show-in-frame [panel width height frame-title]
(doto (JFrame. frame-title)
  (.add panel)
  (.setSize width height)
  (.setVisible true)))

(show-in-frame (make-gui-panel (make-model)) 300 110 "GUI Test")
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to