On Thu, Oct 9, 2008 at 4:26 PM, falcon <[EMAIL PROTECTED]> wrote:

>
> I think it will be far better to model any Clojure GUI libraries on
> JavaFX rather than straight Swing.  In fact, some code samples people
> have posted here remind me of JavaFX code.
>
> Don Sym, of F# develops his programs on the command line,
> instantiating GUIs along the way to peek inside data structures or to
> keep and eye on how values of variables change.  Clojure certainly
> should be able to do that, as long as the library is designed with
> that in mind.
>
> On Oct 8, 4:07 pm, Mitch <[EMAIL PROTECTED]> wrote:
> > I'm interested in doing a GUI program in clojure, but the functional
> > style of clojure doesn't seem to blend too well with the normal Java
> > GUI libraries.  Does anybody have any advice on using clojure for GUI
> > programming?  I've seen Rich's ants demo, but that isn't really an
> > event driven GUI program (just a nice display for his simulation).
> > Has anyone tried using of the GUI building tools for Java with
> > clojure?  I feel like these could help a lot, but I'm not sure.
> >
> > Thanks,
> > Mitch
> >
>
I took a shot at Clojure GUI programming sometime back... my basic aim was
to "impedance
match" the functional style with GUI programming... I wanted to develop a
substantial Swing app then but have not been getting time to do that.
I found agents and sending messages to agents a nice fit for GUI programming
because agents like GUIs hold state and respond serially to a set of
messages (for GUIs its re-paint and user events). Swing is single threaded
and hence the "serial" parallel truly holds.

However, retrofitting Swing state in a "global-across-vm" clojure agent
seemed like too much work and overloading clojure with bloat. So I instead
tried hiding things behind syntax using the following macro:

(defmacro swing [exp]
        (list 'if '(. javax.swing.SwingUtilities (isEventDispatchThread))
                exp
                (list '. 'javax.swing.SwingUtilities (list 'invokeAndWait
                                                                (list 'proxy
'[Runnable] '[] (list 'run '[] exp))))))

The idea is that the expression
(swing <clojure expression> )
causes the <clojure expression> to be evaluated in the EventThread... kinda
like agents but this time ensuring that there is only a single thread in the
VM where this gets executed.

Next I developed simple clojure wrappers over Swing components like the
following:
(defn label [txt]
        (new javax.swing.JLabel txt))

(defn action [txt func]
        (proxy [javax.swing.AbstractAction] [txt] (actionPerformed [e] (func
(.getSource e)))))

(defn button [act]
        (new javax.swing.JButton act))

(defn comboBox [items func]
        (let [ cb (new javax.swing.JComboBox items) ]
;               (.setEditable cb false)
                (.addActionListener cb (proxy
[java.awt.event.ActionListener] []

 (actionPerformed [e]

  (func (.getSource e)))))
        cb))

... hope you get the idea. Now, these can be used as:

; Construct a dropdown menu for selecting folders
(def folders (comboBox (to-array (list "Inbox" "Sent" "Drafts" "Trash"))
                                           (fn [l] (.. System out (println
(.getSelectedItem l))))))
; .... more code here....

; Set the content pane to be a split pane with a label and the mail index
(swing (.setContentPane frame mailContent))

... and so on and so forth.

I do like the idea of using clojure syntax to layout GUIs succinctly. That
was kind of my aim when going with simple wrappers over Swing components.

For GUIs, JavaFX seems to have a killer feature that clojure doesn't have
(or maybe cannot have because of its take on data-structure mutation)...
bindings. JavaFX supports running code blocks upon changes to specific
variables/properties inside a GUI object (constructed in JavaFX using a
declarative programming style). This "reactive" programming style seems to
be a good fit for GUI programming.

It may be possible to do something similar by adding optional "hook"
functions with the swing component wrappers which trigger on
PropertyChangeEvents from swing components. I have not tried implementing
this but I think that hiding these details behind the syntax of a clojure
GUI library may be the easiest way to give the programmer an impression of
JavaFX style bindings.

-- 
Pinocchio

--~--~---------~--~----~------------~-------~--~----~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to