Forcing an argument in a Clojure macro to get namespace-captured -
i working on clojure macro build gridbaglayout-based jpanels. can java classes in defaults map inside macro namespace-qualify, not passed in arguments. magic combination of backquotes, quotes, tildas, or else need?
(import [java.awt gridbagconstraints gridbaglayout insets] [javax.swing jbutton jpanel]) (defmacro make-constraints [gridx gridy & constraints] (let [defaults {:gridwidth 1 :gridheight 1 :weightx 0 :weighty 0 :anchor 'gridbagconstraints/west :fill 'gridbagconstraints/none :insets `(insets. 5 5 5 5) :ipadx 0 :ipady 0} values (assoc (merge defaults (apply hash-map constraints)) :gridx gridx :gridy gridy)] `(gridbagconstraints. ~@(map (fn [value] (if (or (number? value) (string? value) (char? value) (true? value) (false? value) (nil? value)) value `~value)) (map values [:gridx :gridy :gridwidth :gridheight :weightx :weighty :anchor :fill :insets :ipadx :ipady])))))
when use insets
defined in defaults map, gets qualified (not "symbol-captured") (java.awt.insets ...)
:
user=> (macroexpand-1 '(make-constraints 0 0 :weightx 1)) (java.awt.gridbagconstraints. 0 0 1 1 1 0 gridbagconstraints/west gridbagconstraints/none (java.awt.insets. 5 5 5 5) 0 0)
but when pass argument, not:
user=> (macroexpand-1 '(make-constraints 1 1 :insets (insets. 2 2 2 2))) (java.awt.gridbagconstraints. 1 1 1 1 0 0 gridbagconstraints/west gridbagconstraints/none (insets. 2 2 2 2) 0 0)
i'm not trying stickler. getting compiler errors cannot find proper gridbagconstraints
constructor.
i don't know gridbaglayout
, following should work similar macro. if have component :height
bigger 1, have add nil
in column(s) below keep column counter in sync. say, arrive-text-field
have height of 2, you'd have add row of nil
before depart-label
row in order keep counters correct. it's quick hack.
(def default-opts {:insets (insets. 0 0 0 0) :width 1 :height 1 :weight-x 0.0 :weight-y 0.0 :fill gridbagconstraints/none :anchor gridbagconstraints/west :ipadx 0 :ipady 0}) (defn grid-bag-constraints [x y global-opts opts] (let [{:keys [insets width height weight-x weight-h fill anchor ipadx ipady]} (merge default-opts global-opts opts)] (gridbagconstraints. x y width height weight-x weight-h anchor fill insets ipadx ipady))) (defn grid-bag-container [panel global-opts & rows] (doseq [[row-idx row] (map-indexed identity rows) [col-idx [target & {:as opts}]] (map-indexed identity row) :when target] (let [constraints (grid-bag-constraints col-idx row-idx global-opts opts)] (.add panel target constraints))))
usage before.
Comments
Post a Comment