Function 在Clojure中,创建一个函数来创建';n';b每个按钮具有不同的';执行的行动';方法在其他命名空间中
我将此方法改编自《Clojure的欢乐》第216页Function 在Clojure中,创建一个函数来创建';n';b每个按钮具有不同的';执行的行动';方法在其他命名空间中,function,clojure,namespaces,parameter-passing,Function,Clojure,Namespaces,Parameter Passing,我将此方法改编自《Clojure的欢乐》第216页 (defn makeButton [txt func panel] (let [btn (JButton. txt) ] ;bfun (symbol func) ] (doto btn (.addActionListener (proxy [ActionListener] [] (actionPerformed [_] (func))) ;(bfun
(defn makeButton [txt func panel]
(let [btn (JButton. txt) ] ;bfun (symbol func) ]
(doto btn
(.addActionListener
(proxy [ActionListener] [] (actionPerformed [_]
(func))) ;(bfun)))
))
(.add panel btn)
))
加上此测试代码:
(defn fba [] (prn "fba"))
(defn fbb [] (prn "fbb"))
(def funs [fba fbb])
(def btnames ["B1" "B2"])
执行的按钮和操作在gui设置功能中创建:
(doseq [i (range (count btnames)) ]
(makeButton (get btnames i) (nth funs i) aJpanel))
这是我想要的;单击“B1”打印字符串“fba”等。当我想附加到“actionPerformed”时,我的困难就出现了,例如:ns1.ns2/myFunction
,而不是这些简单的情况(即使用多个命名空间限定函数的列表/向量)。报告的例外情况是
传递给符号的参数数(0)错误
从上面的“makeButton”函数中,我试图解决的问题被注释掉了。这个问题的惯用clojure解决方案是什么?这段代码在REPL中适用于我。我使用
clojure.pprint/pprint
作为位于不同命名空间中的函数的示例:
(import '[javax.swing JFrame JPanel JButton]
'[java.awt.event ActionListener])
(def panel (JPanel.))
(def frame (doto (JFrame. "Hello Frame")
(.setContentPane panel)
(.setSize 200 200)
(.setVisible true)))
(defn make-button [label f panel]
(let [button (JButton. label)]
(doto button
(.addActionListener
(proxy [ActionListener] []
(actionPerformed [evt]
(f evt)))))
(.add panel button)))
(make-button "One" clojure.pprint/pprint panel)
(.revalidate frame)
您只需将
funs
中的一个函数替换为ns1.ns2/myFunction
。如果您尝试这样做(不修改工作版本中的makeButton
),会发生什么?顺便说一句,我建议为您的标签/功能使用贴图:(def foo{“B1”fba,“B2”fbb})
,然后将您的按钮设置为(doseq[[label f]foo](make button label f panel))
感谢您提供了关于使用贴图的有用建议。有时人们会回到旧的Java循环习惯。不用担心,我自己还在学习Clojure,所以我会尝试找到看起来不像“Clojure”的代码很奇怪,但你是对的,你的版本是有效的。谢谢你的帮助。现在我要确定我把事情搞砸了。