JFace Examples in Clojure

JFace supposedly is like compiled macros to help streamline SWT. But it is very Java centric, i.e. very OO or expects OO. For these examples, we have a data source, a struct of 3 people and their children. JFace then allows you to access them and "SWT" them in bulk onto certain SWT widgets that JFace wraps nicely.

I reduced, changed, and simplified the code in the examples to show how each wrapped widget works in isolation.

...

Update: I struggled with some of those. I had to strain to remember some Java conventions from college. I had to read up on some and tried things like a crazy person until I got them to work... all the while slowly realizing that JFace may be a poor man's version of Clojure's macros but for Java's OO. I really think so. Another way of seeing it is as beefed-up SWT widgets with more features especially bulk objects handling features.

Anyways, I translated all the examples as much as they made sense till the end of the chapter. That helped show that JFace could be rolled into a GUI framework, of sorts, for clojure but does not have to. In fact, I may opt for not including it at first to see if I can get away with it.

Ok, on to the next chapter. I love this book!

;; ------
;; List Viewer
(defstruct person :first :last :age)

(def example
(map #(apply (partial struct person) %)
(partition 3 ["Dan" "Rubel" 38
"Eric" "Clayberg" 39
"Mike" "Taylor" 52])))

(import '(org.eclipse.swt.widgets Display Shell))
(import '(org.eclipse.jface.viewers
ArrayContentProvider ISelectionChangedListener ListViewer
SelectionChangedEvent Viewer))
(import 'org.eclipse.jface.viewers.LabelProvider)
(import 'org.eclipse.swt.SWT)
(import 'org.eclipse.swt.layout.FillLayout)

(let [display (Display.)
shell (doto (Shell. display)
(.setText "List Viewer Example")
(.setBounds 100 100 200 100)
(.setLayout (FillLayout.)))
listViewer (doto (ListViewer. shell SWT/SINGLE)
(.setContentProvider (ArrayContentProvider.))
(.setInput (to-array example)))]

(. listViewer setLabelProvider
(proxy [LabelProvider] []
(getText [element] (str (:first element) " " (:last element)))))

(. listViewer addSelectionChangedListener
(proxy [ISelectionChangedListener] []
(selectionChanged [event]
(println "Selected: "
(let [item (.. event getSelection getFirstElement)]
(str (:first item) " " (:last item)))))))

(. shell open)
(while (not (. shell isDisposed))
(if (not (. display readAndDispatch)) (. display sleep)))
(. display dispose))



;; -----
;; Table Viewer
(defstruct person :first :last :age :child)

(def example
(map #(apply (partial struct person) %)
(partition 4 ["Dan" "Rubel" 38 [(struct person "Beth" "Rubel" 8)
(struct person "David" "Rubel" 3)]
"Eric" "Clayberg" 39 [(struct person "Lauren" "Clayberg" 6)
(struct person "Lee" "Clayberg" 4)]
"Mike" "Taylor" 52 nil])))

(import '(org.eclipse.swt.widgets
Display Shell Table TableColumn)
'org.eclipse.swt.SWT
'org.eclipse.swt.layout.FillLayout
'(org.eclipse.jface.viewers
ArrayContentProvider TableViewer LabelProvider ITableLabelProvider))

(let [display (Display.)
shell (doto (Shell. display)
(.setText "Table Viewer Example")
(.setBounds 100 100 325 200)
(.setLayout (FillLayout.)))
tableViewer (TableViewer. shell (bit-or SWT/SINGLE SWT/FULL_SELECTION))
table (. tableViewer getTable)]

(. table setHeaderVisible true)
(. table setLinesVisible true)

(doall (map #(doto (TableColumn. table %1) (.setText %2) (.setWidth %3))
[SWT/LEFT SWT/LEFT SWT/CENTER SWT/CENTER]
["First Name" "Last Name" "Age" "Num Children"]
[100 100 35 75]))

(. tableViewer setLabelProvider
(proxy [LabelProvider ITableLabelProvider] []
(getColumnImage [_1 _2] nil)
(getColumnText [element idx]
(str (cond (= idx 0) (:first element)
(= idx 1) (:last element)
(= idx 2) (:age element)
(= idx 3) (count (:child element)))))))

(. tableViewer setContentProvider (ArrayContentProvider.))
(. tableViewer setInput (to-array example))

(. shell open)
(while (not (. shell isDisposed))
(if (not (. display readAndDispatch)) (. display sleep)))
(. display dispose))



;; ---
;; Tree Viewer
(defstruct person :first :last :age :child)

(def example
(map #(apply (partial struct person) %)
(partition 4 ["Dan" "Rubel" 38 [(struct person "Beth" "Rubel" 8)
(struct person "David" "Rubel" 3)]
"Eric" "Clayberg" 39 [(struct person "Lauren" "Clayberg" 6)
(struct person "Lee" "Clayberg" 4)]
"Mike" "Taylor" 52 nil])))

(import 'org.eclipse.swt.SWT
'org.eclipse.swt.layout.FillLayout
'(org.eclipse.jface.viewers
TreeViewer LabelProvider ArrayContentProvider ITreeContentProvider)
'(org.eclipse.swt.widgets Display Shell))

(let [display (Display.)
shell (doto (Shell. display)
(.setText "Tree Viewer Example")
(.setBounds 100 100 200 200)
(.setLayout (FillLayout.)))
treeViewer (TreeViewer. shell SWT/SINGLE)]

(. treeViewer setLabelProvider
(proxy [LabelProvider] []
(getText [element] (str (:first element) " " (:last element)))))

(. treeViewer setContentProvider
(proxy [ArrayContentProvider ITreeContentProvider] []
(getChildren [parentElement] (to-array (:child parentElement)))
(hasChildren [element] (not (nil? (:child element))))))

(. treeViewer setInput (to-array example))

(. shell open)
(while (not (. shell isDisposed))
(if (not (. display readAndDispatch)) (. display sleep)))
(. display dispose))



;; ----
;; Text Viewer
(import 'org.eclipse.swt.SWT
'org.eclipse.swt.layout.FillLayout
'org.eclipse.swt.custom.StyleRange
'org.eclipse.swt.graphics.Color
'(org.eclipse.jface.text
Document TextPresentation TextViewer)
'(org.eclipse.swt.widgets Display Shell))

(let [display (Display.)
shell (doto (Shell. display)
(.setText "Text Viewer Example")
(.setBounds 100 100 300 75)
(.setLayout (FillLayout.)))
textViewer (TextViewer. shell (bit-or SWT/SINGLE SWT/V_SCROLL))]

(. textViewer setDocument
(Document. (str "This is plain text "
"This is bold text "
"This is red text")))

(. textViewer changeTextPresentation
(doto (TextPresentation.)
(.addStyleRange (StyleRange. 19 17 nil nil SWT/BOLD))
(.addStyleRange (StyleRange. 37 16 (Color. nil 255 0 0) nil)))
true)

(. shell open)
(while (not (. shell isDisposed))
(if (not (. display readAndDispatch)) (. display sleep)))
(. display dispose))