Commits

Anonymous committed 9d7e778

New version of builder, with minor bugs, listeners using java beans api, full import of hangar project as neman.webapps and small corection to namespaces in libs.

Comments (0)

Files changed (20)

docs/index.textile

-p(pagetitle). Neman Libraries
-
-Table of Content:
-
-{toc}
-
-h1. Core functions and macros
-
-Main part of @neman.core@ library is @=>@ (builder) macro used for constructiong Java objects and there compositions. Usage of builder is similar to builtin @doto@ macro and @new@ special form with abbility to __inject__ new methods in existing Java classes, add __new constructors__, __override__ existing methods and (*TODO*).
-
-p(notice). There is no real injection of new methods and constructors, they are effective only inside builder macro.
-
-This is how you would construct a SWING menu for your app using builder macro (configured with @neman.swing@):
-
-pre.. 
- (ns user
-   (:import (javax.swing JMenuBase JMenu JMenuItem JSeparator))
-   (:require net.ksojat.neman.swing)
-   (:use net.ksojat.neman.core))
-
- (def m
-   (=> (JMenuBar.)
-     [(=> [JMenu "&File"]
-        [(=> [JMenuItem "&New [ctrl n]"])
-         (=> [JMenuItem "&Open [ctrl o]"])
-         (=> [JMenuItem "&Save [ctrl s]"]
-           :Enabled false)
-         (JSeparator.)
-         (=> [JMenuItem "&Exit [ctrl q]"])])
-       (=> [JMenu "&Edit"]
-         [(=> [JMenuItem "Cu&t [ctrl x]"])
-          (=> [JMenuItem "&Copy [ctrl c]"])
-          (=> [JMenuItem "&Paste [ctrl v]"])])]))
-p. Equivalent code using @doto@ and @new@ could be written as:
-
-pre.. 
-  (ns user
-    (:import (javax.swing JMenuBar JMenu JMenuItem JSeparator KeyStroke))
-
-  (def m
-    (doto (JMenuBar.)
-      (.add
-        (doto (JMenu. "File")
-          (.setMnemonic "f")
-          (.add
-            (doto (JMenuItem. "New")
-              (.setMnemonic "n")
-              (.setAccelerator (KeyStroke/getKeyStroke "ctrl n"))))
-          (.add
-            (doto (JMenuItem. "Open")
-              (.setMnemonic "o")
-              (.setAccelerator (KeyStroke/getKeyStroke "ctrl o"))))
-          (.add
-            (doto (JMenuItem. "Save")
-              (.setEnabled false)
-              (.setMnemonic "s")
-              (.setAccelerator (KeyStroke/getKeyStroke "ctrl s"))))))
-      (.add
-        (doto (JMenu. "Edit")
-          (.setMnemonic "e")
-          (.add
-            (doto (JMenuItem. "Cut")
-              (.setMnemonic "t")
-              (.setAccelerator (KeyStroke/getKeyStroke "ctrl x"))))
-          (.add
-            (doto (JMenuItem. "Copy")
-              (.setMnemonic "c")
-              (.setAccelerator (KeyStroke/getKeyStroke "ctrl c"))))
-          (.add
-            (doto (JMenuItem. "Paste")
-              (.setMnemonic "p")
-              (.setAccelerator (KeyStroke/getKeyStroke "ctrl v"))))))))
-h1. XML and XML templates
-
-Neman XML library is thin wrapper around "JDOM":http://www.jdom.org/ using builder macro for DOM construction. This way you don't loose any capabilities of original JDOM API.
-
-pre.. 
- (ns user
-   (:use
-     (net.ksojat.neman
-       core
-       [xml :only [xml]])))
-
- (def simple-html-page
-   (xml
-     (=> :html
-       [(=> :head [(=> :title "Hello World!")])
-        (=> :body
-          [(=> :h1 "Hello World!")
-           (=> :p  "Example paragraph.")])])))
-
-p. Default methods for JDOM classes:
-|_.Class|_.Method|_.Default|
-(odd).|org.jdom.Document|setDocType|:string|
-(even).|org.jdom.Element|addContent|:vector|
-(odd).|org.jdom.Element|addContent|:string|
-(even).|org.jdom.Element|setAttributes|:map|
-
-p. Patched methods for JDOM classes:
-|_.Class|_.Method|_.Description|
-(odd).|org.jdom.Document|setDocType|Accepts @org.jdom.DocType@ or regular @java.lang.String@|
-(even).|org.jdom.Element|setAttributes|*TODO*|
-(odd).|org.jdom.Element|addContent|Accepts @java.util.List@ of @org.jdom.Content@ objects, single @org.jdom.Content@ object or anything that can be converted to String (it will be inserted as text node).|
-
-p. TODO: Add documentation!
-
-h1. Web library
-
-TODO: Add documentation!
-
-h1. JSON
-
-TODO: Add documentation!

docs/style.css

-body {
-    margin: 10px 50px;
-    font-family: Arial;
-}
-
-h1 {
-    /*text-align: center;*/
-    font-size: 1.6em;
-}
-
-a {
-    color: #215A6D;
-}
-
-p {
-    letter-spacing: 0.2px;
-    line-height: 1.5em;
-}
-
-.notice {
-    padding: 3px;
-    background-color: #CCCCCC;
-    border-left: 4px solid black;
-    font-size: 0.8em;
-}
-
-pre {
-    padding: 5px;
-    background-color: #FFFFF5;
-    border-top: 1px solid #CDDAD9;
-    border-bottom: 1px solid #CDDAD9;
-    border-left: 4px solid orange;
-    line-height: 1.4em;
-}
-
-code {
-    background-color: #EBF7F6;
-    padding: 2px;
-}
-
-.tags {
-    clear: both;
-    display: inline;
-    margin: 0; padding: 0;
-}
-
-.tags + ol {
-    display: inline;
-    margin: 0; padding: 0;
-}
-
-.tags + ol li {
-    list-style: none;
-    display: inline;
-}
-
-.note {
-    border: 1px dashed #282828;
-    background-color: #ECF2F3;
-    padding: 10px;
-}
-
-.pagetitle {
-    font-size: 2.3em;
-    font-weight: bold;
-}
-
-table {
-    border-spacing: 0;
-    border-collapse: collapse;
-    border: 1px solid #C72545;
-}
-
-th {
-    color: white;
-    background-color: #C72545;
-    text-align: left;
-    font-family: Monospace;
-    font-weight: normal;
-    padding: 2px;
-}
-
-td {
-    padding: 4px;
-}
-
-tr.odd {
-    background-color: #f8f8f8;
-}

neman/core/src/net/ksojat/neman/core.clj

 
 (ns net.ksojat.neman.core
   (:import (clojure.lang RT Reflector)
+           (java.beans Introspector)
            (java.util UUID))
-  (:load "core/builder"))
+  (:load "core/builder"
+         "core/listeners"))
 
 (defn str-join [s & strings]
   (str (interpose s strings)))

neman/core/src/net/ksojat/neman/core/builder.clj

 ;; agreeing to be bound by the terms of this license.  You must not
 ;; remove this notice, or any other, from this software.
 
-(ns user
-  (:require [clojure.zip :as zip])
-  (:import (clojure.lang RT Reflector)))
-
 (defmulti
   #^{:doc
       "Builder macro provides alternative way of object a Java object. It's syntax is:
       ~@(loop [[m & ms :as mx] members, p []]
           (if (seq mx)
             (cond
-              (= '>> m)
-               (let [[_ expr & ms] mx]
-                 (recur ms (conj p `(~(first expr) ~gx ~@(rest expr)))))
+              ; TODO: Replace this with ~
+              ;(= '>> m)
+              ; (let [[_ expr & ms] mx]
+              ;   (recur ms (conj p `(~(first expr) ~gx ~@(rest expr)))))
+              ; TODO: Add support for ~@
               (keyword? m)
                 (let [[_ val & ms] mx]
                   (recur ms (conj p `(patch ~gx '~(symbol (str "set" (name m))) ~val))))
 (defn named? [form]
   (and (builder? form) (name? (second form))))
 
-;(defn get-name [form]
-;  (if (and (builder? form) (name? (second form)))
-;    (let [[sym [_ id] expr & members] form]
-;      [(concat (list sym id) members) [id expr]])
-;    [form nil]))
-
-;(defn walk [form]
-;  (if (coll? form)
-;    (let [res     (map walk form)
-;          newform (map first res)
-;          names   (filter (complement nil?) (mapcat second res))]
-;      (cond
-;        (seq? form)
-;          (let [[newform name] (get-name newform)]
-;            [newform (concat name names)])
-;        (vector? form)
-;          [(vec newform) names]
-;        (coll? form)
-;          [(into (empty form) newform) names]))
-;    [form nil]))
-
-(defn walk [form]
+(defn extract
+  "Exctract named builder macro calls by travesting given form
+   and spliting it in new form where (=> ~name expr & members) is transfrem
+   to (=> name & members) and list of extracted names and 'expr' expressions."
+  [form]
   (if (coll? form)
-    (let [res     (map walk form)
+    (let [res     (map extract form)
           newform (map first res)
-          names   (filter (complement nil?) (mapcat second res))]
+          names   (into [] (filter (complement nil?) (mapcat second res)))]
       (cond
         (named? form)
           (let [[sym [_ id] expr & members] newform]
           [(into (empty form) newform) names]))
     [form nil]))
 
-    
-(println "?????"
-(walk
-  '(=> ~frame (JFrame.)
-     (add (=> ~jj (J.)))
-     #{(=> ~x1 (JButton.))}
-     {:a1 (=> ~x2 (JButton.))
-      :a2 (=> ~x3 (JButton.))}
-     [(=> ~b1 (JButton.)
-        [(=> ~z (JX.))])
-      (=> ~b2 (JButton.))])))
+(defmacro build-scope
+  "TODO: Add some docs."
+  ([expr]
+    `(build-scope :toplevel ~expr))
 
-(defmacro
-  #^{:doc
-      ""}
-  build
-  ([expr]
-    `(build :toplevel expr))
   ([result expr]
-    ~expr))
+    (let [[expr names] (extract expr)]
+      `(let ~(vec names) ~expr))))
+
+(default-method javax.swing.JFrame :vector add)
+
+(def t
+  (build-scope
+    (=> (javax.swing.JFrame. "Example")
+      ;:Size [100 100]
+      
+      [(=> ~button1 (javax.swing.JButton. "Button 1"))
+       (=> ~button2 (javax.swing.JButton. "Button 2"))])))

neman/core/src/net/ksojat/neman/core/listeners.clj

+;; Copyright (c) 2009 Krešimir Šojat. All rights reserved.  The use and
+;; distribution terms for this software are covered by the Common
+;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php)
+;; which can be found in the file CPL.TXT at the root of this
+;; distribution.  By using this software in any fashion, you are
+;; agreeing to be bound by the terms of this license.  You must not
+;; remove this notice, or any other, from this software.
+
+;(import '(clojure.lang Reflector)
+;        '(java.beans Introspector))
+
+(defn create-listener [listener action f]
+  (let [names (map #(.getName %) (.getMethods listener))
+        pass  (repeat (fn [& _]))
+        methods (assoc
+                  (apply hash-map (interleave names pass))
+                  (name action) (fn [_ & args] (apply f args)))]
+    (doto (construct-proxy (get-proxy-class listener))
+      (init-proxy methods))))
+
+(defn bean-info [type]
+  (Introspector/getBeanInfo type))
+
+(defn event-descriptor [type listener-type]
+  (first
+    (filter #(isa? listener-type (.getListenerType %))
+      (.getEventSetDescriptors (bean-info type)))))
+
+(defmulti listener-add-method
+  (fn [type listener-type] [type listener-type]))
+
+(defmethod listener-add-method :default [type listener-type]
+  (let [desc   (event-descriptor type listener-type)
+        method (if desc   (.getAddListenerMethod desc))
+        name   (if method (.getName method))]
+    (.addMethod listener-add-method
+      [(.getDeclaringClass method) listener-type] (fn [& _] name))
+    name))
+
+(defmulti listener-remove-method
+  (fn [type listener-type] [type listener-type]))
+
+(defmethod listener-remove-method :default [type listener-type]
+  (let [desc   (event-descriptor type listener-type)
+        method (if desc   (.getRemoveListenerMethod desc))
+        name   (if method (.getName method))]
+    (.addMethod listener-remove-method
+      [(.getDeclaringClass method) listener-type] (fn [& _] name))
+    name))
+
+(defn add-listener [object listener]
+  (if-let [add (listener-add-method (class object) (class listener))]
+    (do
+      (Reflector/invokeInstanceMethod object add (to-array (list listener)))
+      listener)
+    (throw
+      (Exception.
+        (format
+          "Don't know how to add listener of type '%2' to object of type '%1'"
+          (class object) (class listener))))))
+
+(defn remove-listener [object listener]
+  (if-let [remove (listener-remove-method (class object) (class listener))]
+    (do
+      (Reflector/invokeInstanceMethod object remove (to-array (list listener)))
+      listener)
+    (throw
+      (Exception.
+        (format
+          "Don't know how to remove listener of type '%' from object of type '%1'"
+          (class object) (class listener))))))
+
+(defmulti event-listener (fn [type action] [type action]))
+
+(defn has-method? [type method-name]
+  (some #(= (.getName %) method-name) (.getMethods type)))
+
+(defmethod event-listener :default [type action]
+  (println "tu")
+  (let [desc (filter
+               #(let [listener-type (.getListenerType %)]
+                  (has-method? listener-type (name action)))
+               (.getEventSetDescriptors (bean-info type)))]
+    (if (= (count desc) 1)
+      (let [listener (.getListenerType (first desc))]
+        (.addMethod event-listener [type action] (fn [&_ ] [listener action]))
+        [listener action]))))
+
+;; TODO: Merge this with add-listener
+(defn add-listener2 [object action f]
+  (add-listener object
+    (let [[listener method] (event-listener (class object) action)]
+      (create-listener listener method f))))
+
+;; Integrate with builder macro.
+(defmethod patch [Object '>>] [object _ & args]
+  (apply add-listener2 object args))

neman/swing/src/net/ksojat/neman/swing.clj

 (ns net.ksojat.neman.swing
   (:import
     (clojure.lang Reflector RT))
-  (:use net.ksojat.neman.core))
+  (:use net.ksojat.neman.core)
+  (:load
+    "swing/wrapper"
+    "swing/aliases"))
 
-(defn swing-invoke [f]
+(defn invoke-later [f]
   (javax.swing.SwingUtilities/invokeLater f))
 
-(defmacro layout-data [expr]
-  ~expr)
+(defmacro doswing [& body]
+  `(javax.swing.SwingUtilities/invokeLater
+     (fn [] ~@body)))
 
 (defmacro swing [expr]
-  `(layout-data (let-builder-ids ~expr)))
-
-;;
-;; Event listeners.
-;;
-
-(defmulti on (fn [widget action callback] action))
-
-(defmethod on :action-performed [widget action callback]
-  (.addActionListener widget
-    (proxy [java.awt.event.ActionListener] []
-      (actionPerformed [#^java.awt.event.ActionEvent e]
-        (callback e)))))
+  `(layout-data (builder-scope ~expr)))
 
 ;;
 ;; Builder integration.
 ;;
 
-(defmethod default-method [javax.swing.JFrame    :vector] [& _] 'add)
-(defmethod default-method [javax.swing.JMenuBar  :vector] [& _] 'add)
-(defmethod default-method [javax.swing.JMenu     :vector] [& _] 'add)
-(defmethod default-method [javax.swing.JMenuItem :vector] [& _] 'add)
-(defmethod default-method [javax.swing.JToolBar  :vector] [& _] 'add)
-
-;(default-method
-;  [javax.swing.JFrame    :vector 'add]
-;  [javax.swing.JMenuBar  :vector 'add]
-;  [javax.swing.JMenuItem :vector 'add]
-;  [javax.swing.JToolBar  :vector 'add])
+(default-method
+  javax.swing.JFrame    :vector add
+  javax.swing.JMenuBar  :vector add
+  javax.swing.JMenuItem :vector add
+  javax.swing.JToolBar  :vector add)
 
 (defmethod patch [javax.swing.JRadioButtonMenuItem 'setGroup] [o _ g]
   (.add g o))
   (let [o (Reflector/invokeConstructor c RT/EMPTY_ARRAY)]
     (set-abutton o s)))
 
-;;
-;; Event listeners.
-;;
-
-(defmulti on (fn [object method handler-fn] [(class object) method]))
-
-;; Listeneres for java.awt.Component
-(import '(java.awt Component))
-
-(import '(java.awt.event ComponentAdapter ComponentEvent))
-
-(defmethod on [Component :resize] [object _ handler-fn]
-  (let [listener (proxy [ComponentAdapter] []
-                   (componentResized [#^ComponentEvent e] (handler-fn e)))]
-    (.addComponentListener object listener)
-    listener))
-
-(defmethod on [Component :move] [object _ handler-fn]
-  (let [listener (proxy [ComponentAdapter] []
-                   (componentMoved [#^ComponentEvent e] (handler-fn e)))]
-    (.addComponentListener object listener)
-    listener))
-
-(defmethod on [Component :show] [object _ handler-fn]
-  (let [listener (proxy [ComponentAdapter] []
-                   (componentShown [#^CompoentEvent e] (handler-fn e)))]
-    (.addComponentListener object listener)
-    (listener)))
-
-(defmethod on [Component :hide] [object _ handler-fn]
-  (let [listener (proxy [ComponentAdapter] []
-                   (componentHidden [#^ComponentEvent e] (handler-fn e)))]
-    (.addComponentListener object listener)
-    listener))
-
-(import '(java.awt.event FocusAdapter FocusEvent))
-
-(defmethod on [Component :focus-gained] [object _ handler-fn]
-  (let [listener (proxy [FocusAdapter] []
-                   (focusGained [#^FocusEvent e] (handler-fn e)))]
-    (.addFocusListener object listener)
-    listener))
-
-(defmethod on [Component :focus-lost] [object _ handler-fn]
-  (let [listener (proxy [FocusAdapter] []
-                   (focusLost [#^FocusEvent e] (handler-fn e)))]
-    (.addFocusListener object listener)
-    listener))
-
-(import '(java.awt.event HierarchyBoundsAdapter HierarchyListener HierarchyEvent))
-
-(defmethod on [Component :hierarchy-changed] [object _ handler-fn]
-  (let [listener (proxy [HierarchyListener] []
-                   (hierarchyChanged [#^HierarchyEvent e] (handler-fn e)))]
-    (.addHierarchyListener object listener)
-    listener))
-
-(defmethod on [Component :ancestor-moved] [object _ handler-fn]
-  (let [listener (proxy [HierarchyBoundsAdapter] []
-                   (ancestorMoved [#^HierarchyEvent e] (handler-fn e)))]
-    (.addHierarchyBoundsListener object listener)
-    listener))
-
-(defmethod on [Component :ancestor-resized] [object _ handler-fn]
-  (let [listener (proxy [HierarchyBoundsAdapter] []
-                   (ancestorResized [#^HierarchyEvent e] (handler-fn e)))]
-    (.addHierarchyBoundsListener object listener)
-    listener))
-
-; TODO: InputMethodListener
-
-(import '(java.awt.event KeyAdapter KeyEvent))
-
-(defmethod on [Component :key-pressed] [object _ handler-fn]
-  (let [listener (proxy [KeyAdapter] []
-                   (keyPressed [#^KeyEvent e] (handler-fn e)))]
-    (.addKeyListener object listener)
-    listener))
-
-(defmethod on [Component :key-released] [object _ handler-fn]
-  (let [listener (proxy [KeyAdapter] []
-                   (keyReleased [#^KeyEvent e] (handler-fn e)))]
-    (.addKeyListener object listener)
-    listener))
-
-(defmethod on [Component :key-typed] [object _ handler-fn]
-  (let [listener (proxy [KeyAdapter] []
-                   (keyTyped [#^KeyEvent e] (handler-fn e)))]
-    (.addKeyListener object listener)
-    listener))
-
-(import '(java.awt.event MouseAdapter MouseMotionAdapter MouseWheelListener MouseEvent))
-
-(defmethod on [Component :mouse-clicked] [object _ handler-fn]
-  (let [listener (proxy [MouseAdapter] []
-                   (mouseClicked [#^MouseEvent e] (handler-fn)))]
-    (.addMouseListener object listener)
-    listener))
-
-(defmethod on [Component :mouse-entered] [object _ handler-fn]
-  (let [listener (proxy [MouseAdapter] []
-                   (mouseEntered [#^MouseEvent e] (handler-fn e)))]
-    (.addMouseListener object listener)
-    listener))
-
-(defmethod on [Component :mouse-pressed] [object _ handler-fn]
-  (let [listener (proxy [MouseAdapter] []
-                   (mousePressed [#^MouseEvent e] (handler-fn e)))]
-    (.addMouseListener object listener)
-    listener))
-
-(defmethod on [Component :mouse-released] [object _ handler-fn]
-  (let [listener (proxy [MouseAdapter] []
-                   (mouseReleased [#^MouseEvent e] (handler-fn e)))]
-    (.addMouseListener object listener)
-    listener))
-
-(defmethod on [Component :mouse-dragged] [object _ handler-fn]
-  (let [listener (proxy [MouseMotionAdapter] []
-                   (mouseDragged [#^MouseEvent e] (handler-fn e)))]
-    (.addMouseMotionListener object listener)
-    listener))
-
-(defmethod on [Component :mouse-moved] [object _ handler-fn]
-  (let [listener (proxy [MouseMotionAdapter] []
-                   (mouseMoved [#^MouseEvent e] (handler-fn e)))]
-    (.addMouseMotionListener object listener)
-    listener))
-
-(defmethod on [Component :wheel-moved] [object _ handler-fn]
-  (let [listener (proxy [MouseWheelListener] []
-                   (mouseWheelMoved [#^MouseEvent e] (handler-fn e)))]
-    (.addMouseWheelListener object listener)
-    listener))
-
-;; Listeners for java.awt.ItemSelectable
-(import '(java.awt ItemSelectable))
-
-(import '(java.awt.event ItemListener ItemEvent))
-
-(defmethod on [ItemSelectable :item-changed] [object _ handler-fn]
-  (let [listener (proxy [ItemListener] []
-                   (itemStateChanged [#^ItemEvent e] (handler-fn e)))]
-    (.addItemListener object listener)
-    listener))
-
-
-;; Listeners for java.awt.Container
-(import '(java.awt Container))
-
-(import '(java.awt.event ContainerAdapter ContainerEvent))
-
-(defmethod on [Container :component-added] [object _ handler-fn]
-  (let [listener (proxy [ContainerAdapter] []
-                   (componentAdded [#^ComponentEvent e] (handler-fn e)))]
-    (.addComponentListener object listener)
-    listener))
-
-(defmethod on [Container :component-removed] [object _ handler-fn]
-  (let [listener (proxy [ContainerAdapter] []
-                   (componentRemoved [#^ComponentEvenet e] (handler-fn e)))]
-    (.addComponentListener object listener)
-    listener))
-
-;; Listeners for javax.swing.JComponent
-(import '(javax.swing JComponent))
-
-(import '(javax.swing.event AncestorListener AncestorEvent))
-
-(defmethod on [JComponent :ancestor-added] [object _ handler-fn]
-  (let [listener (proxy [AncestorListener] []
-                   (ancestorAdded   [#^AncestorEvent e] (handler-fn e))
-                   (ancestorMoved   [#^AncestorEvent e])
-                   (ancestorRemoved [#^AncestorEvent e]))]
-    (.addAncestorListener object listener)
-    listener))
-
-(defmethod on [JComponent :ancestor-moved] [object _ handler-fn]
-  (let [listener (proxy [AncestorListener] []
-                   (ancestorAdded   [#^AncestorEvent e])
-                   (ancestorMoved   [#^AncestorEvent e] (handler-fn e))
-                   (ancestorRemoved [#^AncestorEvent e]))]
-    (.addAncestorListener object listener)
-    listener))
-
-(defmethod on [JComponent :ancestor-removed] [object _ handler-fn]
-  (let [listener (proxy [AncestorListener] []
-                   (ancestorAdded   [#^AncestorEvent e])
-                   (ancestorMoved   [#^AncestorEvent e])
-                   (ancestorRemoved [#^AncestorEvent e] (handler-fn e)))]
-    (.addAncestorListener object listener)
-    listener))
-
-;; Listeners for javax.swing.AbstractButton
-(import '(javax.swing AbstractButton))
-
-(import '(java.awt.event ActionListener ActionEvent))
-
-(defmethod on [AbstractButton :action] [object _ handler-fn]
-  (let [listener (proxy [ActionListener] []
-                   (actionPerformed [#^ActionEvent e] (handler-fn e)))]
-    (.addActionListener object listener)
-    listener))
-
-(import '(javax.swing.event ChangeListener ChangeEvent))
-
-(defmethod on [AbstractButton :state-changed] [object _ handler-fn]
-  (let [listener (proxy [ChangeListener] []
-                   (stateChanged [#^ChangeEvent e] (handler-fn e)))]
-    (.addChangeListener object listener)
-    listener))
-
-;; Listeners for javax.swing.JMenuItem
-(import '(javax.swing JMenuItem))
-
-(import '(javax.swing.event MenuDragMouseListener MenuDragMouseEvent))
-
-(defmethod on [JMenuItem :mouse-dragged] [object _ handler-fn]
-  (let [listener (proxy [MenuDragMouseListener] []
-                   (menuDragMouseDragged  [#^MenuDragMouseEvent e] (handler-fn e))
-                   (menuDragMouseEntered  [#^MenuDragMouseEvent e])
-                   (menuDragMouseExited   [#^MenuDragMouseEvent e])
-                   (menuDragMouseReleased [#^MenuDragMouseEvent e]))]
-    (.addMenuDragMouseListener object listener)
-    listener))
-
-(defmethod on [JMenuItem :mouse-drag-entered] [object _ handler-fn]
-  (let [listener (proxy [MenuDragMouseListener] []
-                   (menuDragMouseDragged  [#^MenuDragMouseEvent e])
-                   (menuDragMouseEntered  [#^MenuDragMouseEvent e] (handler-fn e))
-                   (menuDragMouseExited   [#^MenuDragMouseEvent e])
-                   (menuDragMouseReleased [#^MenuDragMouseEvent e]))]
-    (.addMenuDragMouseListener object listener)
-    listener))
-
-(defmethod on [JMenuItem :mouse-drag-exited] [object _ handler-fn]
-  (let [listener (proxy [MenuDragMouseListener] []
-                   (menuDragMouseDragged  [#^MenuDragMouseEvent e])
-                   (menuDragMouseEntered  [#^MenuDragMouseEvent e])
-                   (menuDragMouseExited   [#^MenuDragMouseEvent e] (handler-fn e))
-                   (menuDragMouseReleased [#^MenuDragMouseEvent e]))]
-    (.addMenuDragMouseListener object listener)
-    listener))
-
-(defmethod on [JMenuItem :mouse-drag-released] [object _ handler-fn]
-  (let [listener (proxy [MenuDragMouseListener] []
-                   (menuDragMouseDragged  [#^MenuDragMouseEvent e])
-                   (menuDragMouseEntered  [#^MenuDragMouseEvent e])
-                   (menuDragMouseExited   [#^MenuDragMouseEvent e])
-                   (menuDragMouseReleased [#^MenuDragMouseEvent e] (handler-fn e)))]
-    (.addMenuDragMouseListener object listener)
-    listener))
-
-(import '(javax.swing.event MenuKeyListener MenuKeyEvent))
-
-(defmethod on [JMenuItem :menu-key-pressed] [object _ handler-fn]
-  (let [listener (proxy [MenuKeyListener] []
-                   (menuKeyPressed  [#^MenuKeyEvent e] (handler-fn e))
-                   (menuKeyReleased [#^MenuKeyEvent e])
-                   (menuKeyTyped    [#^MenuKeyEvent e]))]
-    (.addMenuKeyListener object listener)
-    listener))
-
-(defmethod on [JMenuItem :menu-key-released] [object _ handler-fn]
-  (let [listener (proxy [MenuKeyListener] []
-                   (menuKeyPressed  [#^MenuKeyEvent e])
-                   (menuKeyReleased [#^MenuKeyEvent e] (handler-fn e))
-                   (menuKeyTyped    [#^MenuKeyEvent e]))]
-    (.addMenuKeyListener object listener)
-    listener))
-
-(defmethod on [JMenuItem :menu-key-typed] [object _ handler-fn]
-  (let [listener (proxy [MenuKeyListener] []
-                   (menuKeyPressed  [#^MenuKeyEvent e])
-                   (menuKeyReleased [#^MenuKeyEvent e])
-                   (menuKeyTyped    [#^MenuKeyEvent e] (handler-fn e)))]
-    (.addMenuKeyListener object listener)
-    listener))
-
-;; Listeners for javax.swing.JMenu
-(import '(javax.swing JMenu))
-
-(import '(javax.swing.event MenuListener MenuEvent))
-
-(defmethod on [JMenu :menu-canceled] [object _ handler-fn]
-  (let [listener (proxy [MenuListener] []
-                   (menuCanceled   [#^MenuEvent e] (handler-fn e))
-                   (menuDeselected [#^MenuEvent e])
-                   (menuSelected   [#^MenuEvent e]))]
-    (.addMenuListener object listener)
-    listener))
-
-(defmethod on [JMenu :menu-deselected] [object _ handler-fn]
-  (let [listener (proxy [MenuListener] []
-                   (menuCanceled   [#^MenuEvent e])
-                   (menuDeselected [#^MenuEvent e] (handler-fn e))
-                   (menuSelected   [#^MenuEvent e]))]
-    (.addMenuListener object listener)
-    listener))
-
-(defmethod on [JMenu :menu-selected] [object _ handler-fn]
-  (let [listener (proxy [MenuListener] []
-                   (menuCanceled   [#^MenuEvent e])
-                   (menuDeselected [#^MenuEvent e])
-                   (menuSelected   [#^MenuEvent e] (handler-fn e)))]
-    (.addMenuListener object listener)
-    listener))

neman/swing/src/net/ksojat/neman/swing/aliases.clj

+;; Copyright (c) 2009 Krešimir Šojat. All rights reserved.  The use and
+;; distribution terms for this software are covered by the Common
+;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php)
+;; which can be found in the file CPL.TXT at the root of this
+;; distribution.  By using this software in any fashion, you are
+;; agreeing to be bound by the terms of this license.  You must not
+;; remove this notice, or any other, from this software.
+
+;(defmulti  alias* (fn [kw] kw))
+(defmulti class-alias* identity)
+(defmethod class-alias* :default [kw]
+  (throw (Exception. (str "Unknown alias for: " kw))))
+
+(defmacro class-alias [& pairs]
+  `(do
+      ~@(map
+          (fn [[kw klass]] `(defmethod class-alias* ~kw [_#] ~klass))
+          (partition 2 pairs))))
+
+(class-alias
+  ; Buttons
+  :button        javax.swing.JButton
+  :check-box     javax.swing.JCheckBox
+  :radio-button  javax.swing.JRadioButton
+  :toggle-button javax.swing.JToggleButton
+
+  ; Menu
+  :menu-bar               javax.swing.JMenuBar
+  :popup-menu             javax.swing.JPopupMenu
+  :menu                   javax.swing.JMenu
+  :menu-item              javax.swing.JMenuItem
+  :check-box-menu-item    javax.swing.JCheckBoxMenuItem
+  :radio-button-menu-item javax.swing.JRadioButtonMenuItem
+  :separator              javax.swing.JSeparator
+
+  ; Text
+  :text           javax.swing.JTextField
+  :password       javax.swing.JPasswordField
+  :formatted-text javax.swing.JFormattedTextField
+  :text-pane      javax.swing.JTextPane
+  :editor-pane    javax.swing.JEditorPane
+  :text-area      javax.swing.JTextArea
+
+  ; Tables and trees
+  :table javax.swing.JTable
+  :tree  javax.swing.JTree
+
+  ; Dialogs
+  :color-chooser  javax.swing.JColorChooser
+  :file-chooser   javax.swing.JFileChooser
+
+  ; Toplevels
+  :applet         javax.swing.JApplet
+  :frame          javax.swing.JFrame
+  :dialog         javax.swing.JDialog
+  :internal-frame javax.swing.JInternalFrame
+
+  ; Containers
+  :tabbed-pane  javax.swing.JTabbedPane
+  :split-pane   javax.swing.JSplitPane
+  :scroll-pane  javax.swing.JScrollPane
+  :panel        javax.swing.JPanel
+  :layered-pane javax.swing.JLayeredPane
+  :desktop-pane javax.swing.JDesktopPane
+
+  ; Misc
+  :label        javax.swing.JLabel
+  :progress-bar javax.swing.JProgressBar
+  :slider       javax.swing.JSlider
+  :spinner      javax.swing.JSpinner
+  :combo-box    javax.swing.JComboBox
+  :list         javax.swing.JList
+  :tool-tip     javax.swing.JToolTip
+
+  ; Layout managers
+  :border-layout   java.awt.BorderLayout
+  :box-layout      javax.swing.BoxLayout
+  :card-layout     java.awt.CardLayout
+  :flow-layout     java.awt.FlowLayout
+  :grid-bag-layout java.awt.GridBagLayout
+  :grid-layout     java.awt.GridLayout
+  :group-layout    javax.swing.GroupLayout
+  :overlay-layout  javax.swing.OverlayLayout
+  :spring-layout   javax.swing.SpringLayout)

neman/swing/src/net/ksojat/neman/swing/wrapper.clj

+;; Copyright (c) 2009 Krešimir Šojat. All rights reserved.  The use and
+;; distribution terms for this software are covered by the Common
+;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php)
+;; which can be found in the file CPL.TXT at the root of this
+;; distribution.  By using this software in any fashion, you are
+;; agreeing to be bound by the terms of this license.  You must not
+;; remove this notice, or any other, from this software.
+
+(gen-class
+  :name         net.ksojat.neman.swing.Wrapper
+  :init         init
+  :constructors {[Object] []}
+  :methods      [[setLayoutData [Object] Void]])
+
+(defn -Wrapper-init [object]
+  [[] (ref {:object object, :layout-data nil})])
+
+(defn -setLayoutData [this data]
+  (dosync
+    (alter (.state this) assoc :layout-data data)))
+
+; TODO: Make private
+(defn get-layout-data [wrapper]
+  (@(.state wrapper) :layout-data))
+
+; TODO: Make private
+(defn get-wrapped-object [wrapper]
+  (@(.state wrapper) :object))
+
+(defmethod patch [net.ksojat.neman.swing.Wrapper 'setLayoutData] [object _ data]
+  (.setLayoutData object data))
+
+(defmethod patch [net.ksojat.neman.swing.Wrapper Object] [object method & args]
+  (apply patch (get-wrapped-object object) method args))
+
+(defmethod default-method* [net.ksojat.neman.swing.Wrapper Object] [wrapper type]
+  (default-method* (@(.state wrapper) :object) type))
+

neman/utils/src/net/ksojat/neman/cli.clj

   (:import (org.apache.commons.cli Options GnuParser HelpFormatter)))
 
 ; Default method in builder macro.
-(defmethod default-method [Options :vector] [& _] 'addOption)
+(default-method Options :vector addOption)
 
 (defn parse-gnu [options args]
   (.parse (GnuParser.) options (into-array args)))

neman/web/src/net/ksojat/neman/jetty.clj

 ;; Builder integration.
 ;;
 
-(defmethod default-method [MimeTypes :vector] [& _] 'addMimeMappings)
-(defmethod default-method [RewriteHandler :vector] [& _] 'addRewriteRule)
+(default-method
+  MimeTypes      :vector addMimeMappings
+  RewriteHandler :vector addRewriteRule)
 
 (defmethod patch [Handler 'addHandlerList] [o _ v]
   (.addHandler o

neman/webapps/_ivy.xml

-<ivy-module version='2.0'>
-    <info
-        organisation='net.ksojat'
-        module='neman'/>
-    <publications>
-        <artifact name='webapps' type='jar' ext='jar'/>
-    </publications>
-    <dependencies>
-        <dependency org='clojure' name='clojure' rev='svn1205'>
-            <artifact name='clojure' type='jar'/>
-        </dependency>
-        <!-- TODO: Add web, xml and core to list -->
-    </dependencies>
-</ivy-module>

neman/webapps/ivy.xml

 <ivy-module version='2.0'>
     <info
-        organisation='net.ksojat'
-        module='neman'/>
+        organisation='net.ksojat.neman'
+        module='webapps'/>
     <publications>
         <artifact name='webapps' type='jar' ext='jar'/>
     </publications>
         <dependency org='clojure' name='clojure' rev='svn1205'>
             <artifact name='clojure' type='jar'/>
         </dependency>
-        <!-- TODO: Add web, xml and core to list -->
+	<dependency name='core' rev='0.0.2'/>
+	<dependency name='xml' rev='0.0.2'/>
+	<dependency name='web' rev='0.0.2'/>
+	<dependency name='utils' rev='0.0.2'/>
     </dependencies>
 </ivy-module>

neman/webapps/src/net/ksojat/neman/webapps/admin.clj

 ;; agreeing to be bound by the terms of this license.  You must not
 ;; remove this notice, or any other, from this software.
 
-(ns net.ksojat.hangar.admin
+(ns net.ksojat.neman.webapps.admin
   (:require
-    [net.ksojat.hangar.html :as html]
+    [net.ksojat.neman.webapps.html :as html]
     [net.ksojat.neman.web   :as web]
     [net.ksojat.neman.css   :as css])
   (:use
-    [net.ksojat.hangar.html :only [a-for shortcut-icon css-link]]
-    [net.ksojat.hangar.admin.style :only [style]]
+    [net.ksojat.neman.webapps.html :only [a-for shortcut-icon css-link]]
+    [net.ksojat.neman.webapps.admin.style :only [style]]
     (net.ksojat.neman
       core
       [css :only [to-css]]

neman/webapps/src/net/ksojat/neman/webapps/admin/dashboard.clj

 ;; agreeing to be bound by the terms of this license.  You must not
 ;; remove this notice, or any other, from this software.
 
-(ns net.ksojat.hangar.admin.dashboard
+(ns net.ksojat.neman.webapps.admin.dashboard
   (:require
-    [net.ksojat.hangar.admin :as admin])
+    [net.ksojat.neman.webapps.admin :as admin])
   (:use
     (net.ksojat.neman
       core

neman/webapps/src/net/ksojat/neman/webapps/admin/help.clj

 ;; agreeing to be bound by the terms of this license.  You must not
 ;; remove this notice, or any other, from this software.
 
-(ns net.ksojat.hangar.admin.help
+(ns net.ksojat.neman.webapps.admin.help
   (:refer-clojure :exclude [partial])
   (:import (java.io File))
   (:require
     [net.ksojat.neman.textile :as textile]
-    (net.ksojat.hangar
+    (net.ksojat.neman.webapps
       [admin    :as admin]
       [flatpage :as flatpage]))
   (:use
-    (net.ksojat.hangar
+    (net.ksojat.neman.webapps
       [html     :only [a-for]]
       [flatpage :only [textile-page]])
     (net.ksojat.neman

neman/webapps/src/net/ksojat/neman/webapps/admin/overview.clj

 ;; agreeing to be bound by the terms of this license.  You must not
 ;; remove this notice, or any other, from this software.
 
-(ns net.ksojat.hangar.admin.overview
+(ns net.ksojat.neman.webapps.admin.overview
   (:require
-    [net.ksojat.hangar.admin :as admin])
+    [net.ksojat.neman.webapps.admin :as admin])
   (:use
     (net.ksojat.neman
       [xml :only [render-str template-from]]

neman/webapps/src/net/ksojat/neman/webapps/admin/style.clj

 ;; agreeing to be bound by the terms of this license.  You must not
 ;; remove this notice, or any other, from this software.
 
-(ns net.ksojat.hangar.admin.style)
+(ns net.ksojat.neman.webapps.admin.style)
 
 (def color1 "#1A1916")
 (def color2 "#C63D63")

neman/webapps/src/net/ksojat/neman/webapps/flatpage.clj

 ;; agreeing to be bound by the terms of this license.  You must not
 ;; remove this notice, or any other, from this software.
 
-(ns net.ksojat.hangar.flatpage
+(ns net.ksojat.neman.webapps.flatpage
   (:use
     (net.ksojat.neman
       core

neman/webapps/src/net/ksojat/neman/webapps/html.clj

 ;; agreeing to be bound by the terms of this license.  You must not
 ;; remove this notice, or any other, from this software.
 
-(ns net.ksojat.hangar.html
+(ns net.ksojat.neman.webapps.html
   (:import (org.jdom Namespace))
   (:use
     (net.ksojat.neman

neman/xml/src/net/ksojat/neman/xml.clj

     (org.jdom.xpath XPath)
     (org.jdom.output XMLOutputter)))
 
-(defmethod default-method [Document :string] [& _] 'setDocType)
-(defmethod default-method [Element :vector] [& _] 'addContent)
-(defmethod default-method [Element :string] [& _] 'addContent)
-(defmethod default-method [Element :map] [& _] 'setAttributes)
+(default-method
+  Document :string setDocType
+  (Element :vector addContent
+           :string addContent
+           :map    setAttributes))
 
 (defmethod patch [Document 'setDocType] [o _ a]
   (.setDocType a (if (string? a) (DocType. a) a)))